import { _decorator, Node, Button, Label, tween, Vec3, UIOpacity, UITransform, Color, instantiate } from 'cc';
import { BaseView } from 'db://assets/scripts/core/BaseView';
import { ViewManager } from 'db://assets/scripts/core/ViewManager';
import { WxSDK, checkPrivacySetting, requirePrivacyAuthorize } from 'db://assets/scripts/utils/WxSDK';
import { StaminaManager } from 'db://assets/scripts/utils/StaminaManager';
import { ToastManager } from 'db://assets/scripts/utils/ToastManager';
import { StaminaInfo } from 'db://assets/scripts/types/ApiTypes';
const { ccclass, property } = _decorator;

/**
 * 首页组件
 * 继承 BaseView，实现页面生命周期
 */
@ccclass('PageHome')
export class PageHome extends BaseView {
    /** 默认体力上限 */
    private static readonly DEFAULT_STAMINA_MAX = 50;

    @property({ type: Node, tooltip: '开始游戏按钮' })
    startGameBtn: Node | null = null;

    @property({ type: Node, tooltip: 'PK按钮' })
    pkBtn: Node | null = null;

    /** 体力值显示标签 */
    @property(Label)
    liveLabel: Label | null = null;

    /** 飞行动画持续时间（秒） */
    private static readonly FLY_DURATION = 0.5;

    /** 到达后弹跳持续时间（秒） */
    private static readonly BOUNCE_DURATION = 0.15;

    /** 浮动文本动画持续时间（秒） */
    private static readonly FLOAT_DURATION = 0.8;

    /** 浮动文本上移距离 */
    private static readonly FLOAT_OFFSET_Y = 120;

    /** 是否正在播放体力消耗动画 */
    private _isAnimating: boolean = false;

    /**
     * 页面首次加载时调用
     */
    onViewLoad(): void {
        console.log('[PageHome] onViewLoad');
        this._initButtons();
        this._initWxShare();
        // 检查隐私授权
        this._checkPrivacyAuthorization();
    }

    /**
     * 初始化微信分享功能
     */
    private _initWxShare(): void {
        WxSDK.initShare({
            title: '写英语',
            imageUrl: '',
            query: ''
        });
    }

    /**
     * 检查隐私授权状态
     */
    private async _checkPrivacyAuthorization(): Promise<void> {
        if (!WxSDK.isWechat()) {
            console.log('[PageHome] 非微信环境，跳过隐私授权检查');
            return;
        }

        try {
            const { needAuthorization } = await checkPrivacySetting();
            if (needAuthorization) {
                console.log('[PageHome] 用户未授权隐私，引导授权');
                await requirePrivacyAuthorize();
            } else {
                console.log('[PageHome] 用户已授权隐私');
            }
        } catch (err) {
            console.warn('[PageHome] 隐私授权检查异常:', err);
        }
    }

    /**
     * 初始化按钮事件
     */
    private _initButtons(): void {
        if (this.startGameBtn) {
            this.startGameBtn.on(Button.EventType.CLICK, this._onStartGameClick, this);
        }
        if (this.pkBtn) {
            this.pkBtn.on(Button.EventType.CLICK, this._onPkClick, this);
        }
    }

    /**
     * 开始游戏按钮点击回调
     */
    private _onStartGameClick(): void {
        if (this._isAnimating) return;

        console.log('[PageHome] 开始游戏按钮点击');

        // 体力检查
        if (!StaminaManager.instance.hasStamina()) {
            ToastManager.show('体力不足，请等待恢复');
            return;
        }

        this._isAnimating = true;
        this._playStaminaCostAnimation()
            .then(() => {
                ViewManager.instance.open('PageLevel');
            })
            .catch(err => {
                console.error('[PageHome] 体力消耗动画异常:', err);
                // 异常兜底：直接进入关卡
                ViewManager.instance.open('PageLevel');
            })
            .finally(() => {
                this._isAnimating = false;
            });
    }

    /**
     * PK按钮点击回调
     */
    private _onPkClick(): void {
        console.log('[PageHome] PK按钮点击');
        ViewManager.instance.open('PageWriteLevels');
    }

    // ========== 体力消耗动画 ==========

    /**
     * 通过节点路径查找 IconLive
     */
    private _findIconLive(): Node | null {
        return this.node
            .getChildByName('TopLayout')
            ?.getChildByName('Live')
            ?.getChildByName('IconLive') ?? null;
    }

    /**
     * 将节点的世界坐标转换为目标父节点的本地坐标
     */
    private _worldToLocal(worldPos: Vec3, parent: Node): Vec3 {
        const parentTransform = parent.getComponent(UITransform);
        if (!parentTransform) return worldPos;
        return parentTransform.convertToNodeSpaceAR(worldPos);
    }

    /**
     * 获取节点的世界坐标
     */
    private _getWorldPos(node: Node): Vec3 {
        const transform = node.getComponent(UITransform);
        if (!transform) return node.worldPosition.clone();
        return transform.convertToWorldSpaceAR(Vec3.ZERO);
    }

    /**
     * 播放体力消耗动画
     * 1. 克隆 IconLive 飞向 StarGame 按钮
     * 2. 到达后弹跳
     * 3. "体力值-1" 浮动文本上移渐隐
     * 4. 同步更新体力数字
     */
    private _playStaminaCostAnimation(): Promise<void> {
        return new Promise<void>((resolve) => {
            const iconLive = this._findIconLive();
            const targetBtn = this.startGameBtn;

            if (!iconLive || !targetBtn) {
                console.warn('[PageHome] 动画节点未找到，跳过动画');
                resolve();
                return;
            }

            // --- 坐标计算 ---
            const iconWorldPos = this._getWorldPos(iconLive);
            const targetWorldPos = this._getWorldPos(targetBtn);
            const rootNode = this.node;

            // 起始和终点在 root 本地空间的坐标
            const startLocal = this._worldToLocal(iconWorldPos, rootNode);
            const endLocal = this._worldToLocal(targetWorldPos, rootNode);

            // --- 克隆飞行节点 ---
            const flyNode = instantiate(iconLive);
            flyNode.name = '_flyIcon';
            flyNode.setPosition(startLocal);
            // 保持与原始 IconLive 相同的缩放
            flyNode.setScale(iconLive.worldScale.clone());
            rootNode.addChild(flyNode);

            // 隐藏原始 IconLive
            iconLive.active = false;

            // --- 飞行路径（带弧度的抛物线效果） ---
            // 中间控制点：x 取中点，y 取较高值 + 偏移形成弧线
            const midX = (startLocal.x + endLocal.x) / 2;
            const midY = Math.max(startLocal.y, endLocal.y) + 150;
            const midPoint = new Vec3(midX, midY, 0);

            // 阶段1：飞到弧线顶点
            const halfDuration = PageHome.FLY_DURATION / 2;

            tween(flyNode)
                .to(halfDuration, { position: midPoint }, { easing: 'quadOut' })
                .to(halfDuration, { position: endLocal }, { easing: 'quadIn' })
                // 阶段2：到达弹跳
                .to(PageHome.BOUNCE_DURATION / 2, { scale: new Vec3(0.4, 0.4, 1) }, { easing: 'quadOut' })
                .to(PageHome.BOUNCE_DURATION / 2, { scale: new Vec3(0.3, 0.3, 1) }, { easing: 'quadIn' })
                .call(() => {
                    // 飞行完成 — flyNode 使命结束，立即清理
                    flyNode.destroy();
                    iconLive.active = true;

                    // 创建浮动文本
                    this._showFloatText(targetBtn, rootNode);

                    // 乐观更新体力数字
                    this._optimisticUpdateStamina();

                    // 等浮动文本播完再 resolve（用 setTimeout，不依赖已销毁节点的 tween）
                    setTimeout(() => resolve(), PageHome.FLOAT_DURATION * 1000);
                })
                .start();
        });
    }

    /**
     * 显示浮动提示文本 "体力值-1"
     * 从按钮位置向上漂移并渐隐
     */
    private _showFloatText(anchorNode: Node, parentNode: Node): void {
        // 创建文本节点
        const textNode = new Node('_floatText');
        textNode.addComponent(UITransform);

        const label = textNode.addComponent(Label);
        label.string = '体力值-1';
        label.fontSize = 36;
        label.lineHeight = 40;
        label.color = new Color(255, 80, 80, 255);
        label.isBold = true;

        // 复用 liveLabel 的字体（如果有）
        if (this.liveLabel?.font) {
            label.font = this.liveLabel.font;
        }

        // 添加 UIOpacity 用于渐隐
        const opacity = textNode.addComponent(UIOpacity);
        opacity.opacity = 255;

        // 定位到按钮上方
        const anchorWorldPos = this._getWorldPos(anchorNode);
        const localPos = this._worldToLocal(anchorWorldPos, parentNode);
        // 起始位置在按钮上方偏移
        localPos.y += 120;
        textNode.setPosition(localPos);

        parentNode.addChild(textNode);

        // 向上漂移 + 渐隐
        const floatTarget = new Vec3(localPos.x, localPos.y + PageHome.FLOAT_OFFSET_Y, 0);
        tween(textNode)
            .to(PageHome.FLOAT_DURATION, { position: floatTarget }, { easing: 'quadOut' })
            .call(() => {
                textNode.destroy();
            })
            .start();

        tween(opacity)
            .delay(PageHome.FLOAT_DURATION * 0.3)
            .to(PageHome.FLOAT_DURATION * 0.7, { opacity: 0 }, { easing: 'quadIn' })
            .start();
    }

    /**
     * 乐观更新体力标签（本地 -1 预扣显示）
     */
    private _optimisticUpdateStamina(): void {
        if (!this.liveLabel) return;

        const stamina = StaminaManager.instance.getStamina();
        const maxStamina = this._getStaminaMax(stamina);
        const displayCurrent = Math.max(0, stamina.current - 1);
        this.liveLabel.string = `${displayCurrent}/${maxStamina}`;
    }

    /**
     * 页面每次显示时调用
     */
    onViewShow(): void {
        console.log('[PageHome] onViewShow');
        this.updateStaminaLabel();

        // 保险恢复：防止动画中途被打断导致 IconLive 隐藏残留
        const iconLive = this._findIconLive();
        if (iconLive && !iconLive.active) {
            iconLive.active = true;
        }
    }

    /**
     * 获取体力上限
     */
    private _getStaminaMax(stamina: StaminaInfo): number {
        return typeof stamina.max === 'number' ? stamina.max : PageHome.DEFAULT_STAMINA_MAX;
    }

    /**
     * 更新体力值显示
     */
    private updateStaminaLabel(): void {
        if (this.liveLabel) {
            const stamina = StaminaManager.instance.getStamina();
            const maxStamina = this._getStaminaMax(stamina);
            this.liveLabel.string = `${stamina.current}/${maxStamina}`;
        }
    }

    /**
     * 页面隐藏时调用
     */
    onViewHide(): void {
        console.log('[PageHome] onViewHide');
    }

    /**
     * 页面销毁时调用
     */
    onViewDestroy(): void {
        console.log('[PageHome] onViewDestroy');
        // 移除按钮事件监听
        if (this.startGameBtn) {
            this.startGameBtn.off(Button.EventType.CLICK, this._onStartGameClick, this);
        }
        if (this.pkBtn) {
            this.pkBtn.off(Button.EventType.CLICK, this._onPkClick, this);
        }
    }
}
