import { _decorator, Component, Node, Vec3, input, Input, EventTouch, Camera, view, tween, Animation, Collider2D, Contact2DType, Label, Color, Canvas } from 'cc';
import { TiledMapPathfinder } from './TiledMapPathfinder';
const { ccclass, property } = _decorator;

@ccclass('PlayerController')
export class PlayerController extends Component {
  @property(Canvas)
  canvas: Canvas | null = null;

  @property(Node)
  player: Node | null = null;  // 玩家节点

  @property(Camera)
  camera: Camera | null = null;  // 主摄像机

  @property(TiledMapPathfinder)
  pathfinder: TiledMapPathfinder | null = null;  // 寻路组件

  @property({ range: [1, 300] })
  moveSpeed: number = 300;  // 移动速度（像素/秒）

  @property
  mapWidth: number = 1080;  // 地图宽度

  @property
  mapHeight: number = 2560;  // 地图高度

  private isMoving: boolean = false;
  private isAttacking: boolean = false;
  private currentPath: Vec3[] = [];
  private currentPathIndex: number = 0;
  private originalPosition: Vec3 = new Vec3();
  private currentAnimation: string = 'stand'; // 当前播放的动画
  private lastTargetPosition: Vec3 = new Vec3(); // 上一个目标位置，用于方向判断
  private isUpgraded: boolean = false; // 玩家是否已升级

  // 道具列表
  private props: Node[] = [];

  onLoad() {
    // 注册触摸事件
    input.on(Input.EventType.TOUCH_START, this.onTouchStart, this);

    let collider = this.player.getComponent(Collider2D);
    if (collider) {
      // 监听碰撞事件
      collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
    }

    this.initProps();
  }

  onDestroy() {
    // 移除触摸事件
    input.off(Input.EventType.TOUCH_START, this.onTouchStart, this);
  }

  start() {
    if (this.player) {
      this.originalPosition.set(this.player.position);
    }
  }

  initProps() {
    if (!this.canvas) {
      console.warn('Canvas未设置，无法初始化道具');
      return;
    }

    // 查找Canvas下的Props节点
    const propsNode = this.canvas.node.getChildByName('Props');
    if (!propsNode) {
      console.warn('未找到Props节点，请确保Canvas下有名为"Props"的节点');
      return;
    }

    // 清空现有的道具列表
    this.props.length = 0;

    // 获取Props节点下的所有子节点
    for (let i = 0; i < propsNode.children.length; i++) {
      const child = propsNode.children[i];
      this.props.push(child);
      console.log(`添加道具: ${child.name}`);

      // 为每个道具添加悬浮动画
      this.addFloatingAnimation(child);
    }

    console.log(`初始化道具完成，共找到 ${this.props.length} 个道具`);
  }

  /**
   * 为道具添加悬浮动画
   */
  private addFloatingAnimation(propNode: Node) {
    if (!propNode) return;

    // 保存原始位置
    const originalY = propNode.position.y;
    const floatHeight = 10; // 悬浮高度（像素）
    const floatDuration = 2; // 悬浮周期（秒）

    // 创建上下浮动的动画
    tween(propNode)
      .to(floatDuration / 2, { position: new Vec3(propNode.position.x, originalY + floatHeight, propNode.position.z) }, {
        easing: 'sineInOut'
      })
      .to(floatDuration / 2, { position: new Vec3(propNode.position.x, originalY, propNode.position.z) }, {
        easing: 'sineInOut'
      })
      .union() // 将动画串联起来
      .repeatForever() // 无限重复
      .start();

    console.log(`为道具 ${propNode.name} 添加悬浮动画`);
  }

  private onTouchStart(event: EventTouch) {
    if (!this.player || !this.camera || !this.pathfinder || this.isAttacking) return;

    // 获取触摸点的UI坐标
    const touchLocation = event.getUILocation();

    // 将UI坐标转换为世界坐标
    const worldPos = this.screenToWorldPoint(touchLocation);

    console.log(`触摸UI坐标: (${touchLocation.x}, ${touchLocation.y})`);
    console.log(`转换后世界坐标: (${worldPos.x.toFixed(2)}, ${worldPos.y.toFixed(2)})`);

    this.moveToPositionWithPathfinding(worldPos);
  }

  private screenToWorldPoint(screenPos: { x: number, y: number }): Vec3 {
    if (!this.camera) {
      console.error('Camera未设置，无法进行坐标转换');
      return new Vec3(screenPos.x, screenPos.y, 0);
    }

    // 获取可见区域大小
    const visibleSize = view.getVisibleSize();

    // 计算屏幕中心点
    const centerX = visibleSize.width * 0.5;
    const centerY = visibleSize.height * 0.5;

    // 将屏幕坐标转换为以屏幕中心为原点的坐标
    const normalizedX = screenPos.x - centerX;
    const normalizedY = screenPos.y - centerY;

    // 获取相机的正交高度
    const orthoHeight = this.camera.orthoHeight;

    // 计算屏幕坐标到世界坐标的缩放比例
    // 屏幕高度的一半对应 orthoHeight 的世界单位
    const scaleY = orthoHeight / (visibleSize.height * 0.5);
    const scaleX = scaleY; // 保持宽高比一致

    // 将屏幕坐标转换为世界坐标（相对于相机中心）
    const worldOffsetX = normalizedX * scaleX;
    const worldOffsetY = normalizedY * scaleY;

    // 考虑相机的位置偏移
    const cameraPos = this.camera.node.position;

    // 计算最终的世界坐标
    const worldX = worldOffsetX + cameraPos.x;
    const worldY = worldOffsetY + cameraPos.y;

    return new Vec3(worldX, worldY, 0);
  }


  private moveToPositionWithPathfinding(worldPos: Vec3) {
    if (!this.player || !this.pathfinder) return;

    // 停止当前移动
    this.stopMovement();

    // 限制目标位置在地图边界内
    const clampedPos = this.clampPlayerPosition(worldPos);

    // 检查目标位置是否可行走
    if (!this.pathfinder.isWorldPositionWalkable(clampedPos)) {
      console.log('目标位置不可行走，寻找最近的可行走位置');
      const closestWalkable = this.pathfinder.getClosestWalkablePosition(clampedPos);
      if (!closestWalkable) {
        console.warn('找不到可行走的位置');
        return;
      }
      clampedPos.set(closestWalkable);
    }

    // 使用寻路算法计算路径
    const startPos = this.player.position;
    this.currentPath = this.pathfinder.findPath(startPos, clampedPos);

    if (this.currentPath.length === 0) {
      console.warn('无法找到路径');
      return;
    }

    console.log(`找到路径，包含${this.currentPath.length}个点`);

    // 开始沿路径移动
    this.currentPathIndex = 0;
    this.isMoving = true;
    this.moveToNextWaypoint();
  }

  // 限制玩家位置在地图边界内
  private clampPlayerPosition(position: Vec3): Vec3 {
    // 计算地图边界（地图锚点为0.5,0.5，所以范围是-mapWidth/2到+mapWidth/2）
    const mapHalfWidth = this.mapWidth * 0.5;
    const mapHalfHeight = this.mapHeight * 0.5;

    // 限制玩家位置
    const clampedPosition = position.clone();
    clampedPosition.x = Math.max(-mapHalfWidth, Math.min(mapHalfWidth, position.x));
    clampedPosition.y = Math.max(-mapHalfHeight, Math.min(mapHalfHeight, position.y));

    return clampedPosition;
  }

  /**
   * 根据移动方向获取对应的动画名称
   */
  private getAnimationNameByDirection(currentPos: Vec3, targetPos: Vec3): string {
    const deltaX = targetPos.x - currentPos.x;
    const deltaY = targetPos.y - currentPos.y;

    // 如果移动距离很小，保持当前动画
    const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
    if (distance < 1) {
      return this.currentAnimation;
    }

    // 计算主要移动方向
    const absX = Math.abs(deltaX);
    const absY = Math.abs(deltaY);

    // 添加角度判断，更精确地确定方向
    const angle = Math.atan2(deltaY, deltaX) * 180 / Math.PI; // 转换为角度

    if (absX > absY) {
      // 水平移动为主
      return deltaX > 0 ? 'walk3' : 'walk5';
    } else {
      // 垂直移动为主
      return deltaY > 0 ? 'walk3' : 'walk5'; // 上移用walk3，下移用walk5
    }
  }

  /**
   * 切换动画，避免不必要的切换
   */
  private switchAnimation(animationName: string) {
    if (!this.player) {
      console.warn('Player节点未设置，无法切换动画');
      return;
    }

    // 如果玩家已升级，在动画名称后添加 "_2" 后缀
    let finalAnimationName = animationName;
    if (this.isUpgraded && !animationName.endsWith('_2')) {
      finalAnimationName = animationName + '_2';
    }

    if (this.currentAnimation === finalAnimationName) {
      return; // 已经是目标动画，不需要切换
    }


    const animation = this.player.getComponent(Animation);
    if (animation) {
      // 检查动画是否存在
      const state = animation.getState(finalAnimationName);
      if (!state) {
        console.warn(`动画 ${finalAnimationName} 不存在，使用默认动画`);
        this.currentAnimation = 'stand';
        animation.play('stand');
        return;
      }

      this.currentAnimation = finalAnimationName;
      animation.play(finalAnimationName);
      console.log(`切换动画: ${finalAnimationName}`);
    } else {
      console.warn('未找到Animation组件，无法播放动画');
    }
  }

  /**
   * 移动到路径中的下一个路径点
   */
  private moveToNextWaypoint() {
    if (this.currentAnimation === 'attack') {
      return
    }

    if (!this.player || this.currentPath.length === 0 || this.currentPathIndex >= this.currentPath.length) {
      this.isMoving = false;
      this.switchAnimation('stand');
      console.log('路径移动完成');
      return;
    }



    const targetPos = this.currentPath[this.currentPathIndex];
    const currentPos = this.player.position;

    // 根据移动方向选择动画
    const animationName = this.getAnimationNameByDirection(currentPos, targetPos);

    // 切换到对应的动画
    this.switchAnimation(animationName);

    // 计算移动距离和时间
    const distance = Vec3.distance(currentPos, targetPos);
    const moveTime = distance / this.moveSpeed;

    console.log(`移动到路径点${this.currentPathIndex}: (${targetPos.x.toFixed(2)}, ${targetPos.y.toFixed(2)})`);

    // 记录目标位置用于方向判断
    this.lastTargetPosition.set(targetPos);

    // 使用缓动移动到目标位置
    tween(this.player)
      .to(moveTime, { position: targetPos }, {
        onComplete: () => {
          this.currentPathIndex++;
          this.moveToNextWaypoint();
        }
      })
      .start();
  }

  /**
   * 停止当前移动
   */
  private stopMovement() {
    if (this.player) {
      tween(this.player).stop();
    }
    this.isMoving = false;
    this.currentPath = [];
    this.currentPathIndex = 0;

    // 停止移动时播放站立动画
    this.switchAnimation('stand');
  }

  update(deltaTime: number) {
    // 更新逻辑现在主要由缓动系统处理
    // 这里可以添加其他需要每帧更新的逻辑
  }

  onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D) {
    if (otherCollider.node.name.startsWith('guai_')) {
      this.handleAttack(otherCollider);
    }
  }

  /**
   * 处理攻击逻辑
   */
  private handleAttack(otherCollider: Collider2D) {
    this.isAttacking = true;
    console.log('开始攻击，怪物名称：', otherCollider.node.name);

    // 获取玩家和怪物的生命值
    const playerHpLabel = this.player.getChildByName('hp');
    const monsterHpLabel = otherCollider.node.getChildByName('hp');

    if (!playerHpLabel || !monsterHpLabel) {
      console.warn('未找到生命值标签，玩家hp:', playerHpLabel, '怪物hp:', monsterHpLabel);
      this.isAttacking = false;
      return;
    }

    // 获取生命值数值
    const playerLabel = playerHpLabel.getComponent(Label);
    const monsterLabel = monsterHpLabel.getComponent(Label);

    if (!playerLabel || !monsterLabel) {
      console.warn('未找到Label组件');
      this.isAttacking = false;
      return;
    }

    const playerHp = parseInt(playerLabel.string) || 0;
    const monsterHp = parseInt(monsterLabel.string) || 0;
    console.log('玩家生命值:', playerHp, '怪物生命值:', monsterHp);

    // 播放攻击动画
    const monsterAnimation = otherCollider.node.getComponent(Animation);
    if (monsterAnimation) {
      monsterAnimation.play(`${otherCollider.node.name}_attack`);
    }
    this.switchAnimation('attack');

    // 2秒后判定攻击结果
    this.scheduleOnce(async () => {
      // 比较生命值，判断输赢
      console.log('判定攻击结果，玩家HP:', playerHp, '怪物HP:', monsterHp);
      if (playerHp >= monsterHp) {
        // 玩家获胜
        console.log('玩家获胜！更新玩家生命值为:', playerHp + monsterHp);

        // 玩家生命值增加怪物生命值
        const newPlayerHp = playerHp + monsterHp;
        playerLabel.string = newPlayerHp.toString();

        // 播放生命值标签的强调动画
        this.playLabelEmphasisAnimation(playerLabel);

        // 播放怪物死亡动画
        if (monsterAnimation) {
          monsterAnimation.play(`${otherCollider.node.name}_die`);
        }

        // 如果是攻击 guai_2 并且成功，创建道具飞向 player 的动画
        if (otherCollider.node.name === 'guai_2') {
          await this.createPropsFlyToPlayerAnimation()
        }

        // 1秒后怪物消失
        this.scheduleOnce(() => {
          otherCollider.node.destroy();
          console.log('怪物已消失');
        }, 1);

        this.switchAnimation('stand'); // 玩家站立
      } else {
        // 怪物获胜
        console.log('怪物获胜！玩家生命值变为0');

        // 玩家生命值变为0
        playerLabel.string = '0';

        // 播放生命值标签的失败动画
        this.playLabelFailAnimation(playerLabel);

        // 玩家死亡动画
        this.switchAnimation('die');

        // 怪物站立动画
        if (monsterAnimation) {
          monsterAnimation.play(`${otherCollider.node.name}_stand`);
        }
      }

      this.isAttacking = false;
    }, 2);
  }

  /**
   * 播放生命值标签强调动画（成功时）
   */
  private playLabelEmphasisAnimation(label: Label) {
    if (!label) return;

    const originalScale = label.node.scale.clone();
    const originalColor = label.color.clone();

    // 创建强调动画序列
    tween(label.node)
      .to(0.1, { scale: new Vec3(originalScale.x * 1.2, originalScale.y * 1.2, originalScale.z) })
      .to(0.1, { scale: originalScale })
      .to(0.1, { scale: new Vec3(originalScale.x * 1.1, originalScale.y * 1.1, originalScale.z) })
      .to(0.1, { scale: originalScale })
      .start();

    // 颜色闪烁效果
    tween(label)
      .to(0.1, { color: new Color(255, 255, 0) }) // 黄色
      .to(0.1, { color: new Color(0, 255, 0) })   // 绿色
      .to(0.1, { color: originalColor })
      .start();
  }

  /**
   * 播放生命值标签失败动画（失败时）
   */
  private playLabelFailAnimation(label: Label) {
    if (!label) return;

    const originalScale = label.node.scale.clone();
    const originalColor = label.color.clone();

    // 创建失败动画序列 - 震动效果
    tween(label.node)
      .to(0.05, { position: new Vec3(label.node.position.x - 5, label.node.position.y, label.node.position.z) })
      .to(0.05, { position: new Vec3(label.node.position.x + 5, label.node.position.y, label.node.position.z) })
      .to(0.05, { position: new Vec3(label.node.position.x - 5, label.node.position.y, label.node.position.z) })
      .to(0.05, { position: new Vec3(label.node.position.x + 5, label.node.position.y, label.node.position.z) })
      .to(0.05, { position: label.node.position })
      .start();

    // 颜色变红效果
    tween(label)
      .to(0.1, { color: new Color(255, 0, 0) })   // 红色
      .to(0.1, { color: new Color(128, 0, 0) })   // 暗红色
      .to(0.1, { color: originalColor })
      .start();
  }

  /**
   * 创建道具飞向玩家的动画（同步方法）
   */
  private async createPropsFlyToPlayerAnimation(): Promise<void> {
    if (!this.player || this.props.length === 0) {
      console.warn('玩家或道具不存在，无法创建飞行动画');
      return;
    }

    console.log('创建道具飞向玩家的动画');

    // 获取玩家位置
    const playerPos = this.player.position.clone();

    // 创建所有道具的飞行动画承诺
    const flyPromises: Promise<void>[] = [];

    // 为每个道具创建飞行动画
    this.props.forEach((prop, index) => {
      if (!prop || !prop.isValid) return;

      // 保存道具原始位置
      const originalPos = prop.position.clone();

      // 计算飞行时间（根据距离调整）
      const distance = Vec3.distance(originalPos, playerPos);
      const flyDuration = Math.max(0.5, distance / 500); // 最少0.5秒，速度500像素/秒

      // 添加延迟，让道具依次飞向玩家
      const delay = index * 0.1;

      // 停止道具的悬浮动画
      tween(prop).stop();

      // 创建飞行动画的承诺
      const flyPromise = new Promise<void>((resolve) => {
        this.scheduleOnce(() => {
          tween(prop)
            .to(flyDuration, {
              position: new Vec3(playerPos.x, playerPos.y, playerPos.z)
            }, {
              easing: 'quadOut',
              onComplete: () => {
                // 道具到达玩家位置后消失
                prop.destroy();
                console.log(`道具 ${prop.name} 已到达玩家位置并消失`);
                resolve();
              }
            })
            .start();
        }, delay);
      });

      flyPromises.push(flyPromise);
    });

    // 等待所有道具飞行动画完成
    await Promise.all(flyPromises);

    // 所有动画完成后，播放升级动画并设置升级状态
    this.playLevelUpAnimation();
    this.isUpgraded = true;
    console.log('所有道具飞行动画完成，玩家已升级，后续动画将使用升级版本');
  }

  /**
   * 播放玩家升级动画
   */
  private playLevelUpAnimation() {
    if (!this.player) {
      console.warn('玩家节点不存在，无法播放升级动画');
      return;
    }

    // 查找levelUp子节点
    const levelUpNode = this.player.getChildByName('levelUp');
    if (!levelUpNode) {
      console.warn('未找到levelUp子节点');
      return;
    }

    // 获取动画组件
    const levelUpAnimation = levelUpNode.getComponent(Animation);
    if (!levelUpAnimation) {
      console.warn('levelUp节点未找到Animation组件');
      return;
    }

    console.log('播放玩家升级动画');

    // 播放升级动画
    levelUpAnimation.play('levelUp');
  }
}