import {
  Component,
  EventTouch,
  Node,
  NodePool,
  Prefab,
  UITransform,
  Vec2,
  Vec3,
  _decorator,
  instantiate,
  sys,
} from 'cc'

import FishBulletBase from '../../../fish/script/FishBulletBase'
import FishUI from '../../../fish/script/FishUI'
import CommonTips from '../../engine/uicomponent/CommonTips'
import MathUtils from '../../engine/utils/MathUtils'

import { MoveHelper } from '../../engine/utils/MoveHelper'

import GameMusicHelper from '../utils/GameMusicHelper'

import CannonManager from './CannonManager'
import FishNetManager from './FishNetManager'
import WsManager from './WsManager'

const { ccclass, property } = _decorator

// 子弹管理类
@ccclass('BulletManager')
export default class BulletManager extends Component {
  public static instance: BulletManager = null
  @property({ type: [Prefab] })
  private bulletPrefabList: Prefab[] | [] = []

  private bulletPool: Array<NodePool> = []
  private bulletList: Array<FishBulletBase> = []
  private bulletMoveSpeed: number = 30
  private _vec3Cache: Vec3
  private _vec2Cache: Vec2
  private _fireTime: number = 0
  private _fireTimeNew: number

  onLoad() {
    this._vec3Cache = new Vec3()
    this._vec2Cache = new Vec2()
    BulletManager.instance = this
    this.node.on(Node.EventType.TOUCH_START, this.onShootBullet, this)
  }

  start() {}

  update() {
    this.checkMoveBullet()
  }

  // 检测子弹是否移动完成
  private checkMoveBullet() {
    for (let i = this.bulletList.length - 1; i >= 0; i--) {
      const bullet: FishBulletBase = this.bulletList[i]
      const isMoving: boolean = MoveHelper.moveNode(
        bullet.node,
        this.bulletMoveSpeed,
        bullet.targetP.x,
        bullet.targetP.y,
      )
      if (!isMoving) {
        bullet.node.getPosition(this._vec3Cache)
        this._vec2Cache.x = this._vec3Cache.x
        this._vec2Cache.y = this._vec3Cache.y
        FishNetManager.instance.addFishNet(bullet.bulletType, this._vec2Cache)
        this.bulletList.splice(i, 1)
        this.destroyBullet(bullet)
      }
    }
  }

  // 发射炮弹
  private onShootBullet(event: EventTouch) {
    // TOUCH_START 在Editor上，连续触发2次，导致发2次炮弹bug
    if (sys.platform === 'EDITOR_PAGE') {
      this._fireTimeNew = new Date().getTime()
      if (this._fireTimeNew - this._fireTime < 15000) return
      this._fireTime = this._fireTimeNew
    }

    const tran = this.node.getComponent(UITransform)
    const location = event.getUILocation()
    this._vec3Cache.x = location.x
    this._vec3Cache.y = location.y
    this._vec3Cache.z = 0
    tran.convertToNodeSpaceAR(this._vec3Cache, this._vec3Cache)
    const localP: Vec2 = new Vec2(this._vec3Cache.x, this._vec3Cache.y)
    FishUI.instance.playClickEffect(localP)
    // 子弹发射
    if (FishUI.instance.dz_score >= CannonManager.instance.cannonType) {
      FishUI.instance.dz_score -= CannonManager.instance.cannonType
      // FishUI.instance.refreshScore()
      this._vec3Cache = CannonManager.instance.getCannonPosition()
      const rad: number = MathUtils.p2pRad(new Vec2(this._vec3Cache.x, this._vec3Cache.y), localP)
      const rot: number = MathUtils.radiansToDegrees(rad)
      const bullet: FishBulletBase = this.createBullet(CannonManager.instance.cannonType - 1)
      bullet.targetP = localP
      this.node.addChild(bullet.node)
      bullet.node.setPosition(CannonManager.instance.getCannonPosition())
      this._vec3Cache.x = 1
      this._vec3Cache.y = 1
      this._vec3Cache.y = 1
      Vec3.multiplyScalar(this._vec3Cache, this._vec3Cache, 2)
      bullet.node.setScale(this._vec3Cache)
      bullet.node.angle = rot
      this.bulletList.push(bullet)
      GameMusicHelper.playFire()
      // 旋转炮台
      CannonManager.instance.rotateCannon(location)
    } else {
      CommonTips.showMsg('豆子不足!')
    }
  }

  // 创建子弹
  private createBullet(bulletType: number) {
    let bulletNode: Node
    if (this.bulletPool[bulletType] && this.bulletPool[bulletType].size() > 0) {
      bulletNode = this.bulletPool[bulletType].get()
    } else {
      bulletNode = instantiate(this.bulletPrefabList[bulletType])
    }
    bulletNode.getComponent(FishBulletBase).bulletType = bulletType
    return bulletNode.getComponent(FishBulletBase)
  }

  public killBullet(bullet: FishBulletBase) {
    const index: number = this.bulletList.indexOf(bullet)
    if (index >= 0) {
      this.bulletList.splice(index, 1)
      this.destroyBullet(bullet)
    }
  }

  // 销毁子弹
  private destroyBullet(bullet: FishBulletBase) {
    // 临时代码，因为回收在内存卡顿。后面在优化 2023-2-10
    if (sys.platform === 'EDITOR_PAGE') {
      bullet.node.destroy()
      return
    }
    if (!this.bulletPool[bullet.bulletType]) this.bulletPool[bullet.bulletType] = new NodePool()
    this.bulletPool[bullet.bulletType].put(bullet.node)
  }

  onDestroy() {
    BulletManager.instance = null
  }
}
