import { SpriteFrame, Texture2D, ImageAsset, assetManager } from 'cc';
import { HttpUtil } from './HttpUtil';
import { WxSDK } from './WxSDK';
import { API_ENDPOINTS, getShareJoinUrl, API_TIMEOUT } from '../config/ApiConfig';
import {
    ApiEnvelope,
    CreateShareData,
    JoinShareData,
    ReportProgressData,
    ShareLevelData,
    CreatedShareItem,
    CreatedShareListData,
} from '../types/ApiTypes';
import { RuntimeLevelConfig } from '../types/LevelTypes';

/**
 * 分享管理器
 * 负责创建分享、加入分享、缓存分享关卡数据
 */
export class ShareManager {
    private static _instance: ShareManager | null = null;

    /** 分享模式的关卡数据（null 表示正常模式） */
    private _shareLevels: RuntimeLevelConfig[] | null = null;

    /** API 返回的原始关卡数据（保留 image1Url/image2Url 用于懒加载） */
    private _shareApiLevels: ShareLevelData[] = [];

    private _shareTitle: string = '';
    private _shareCode: string | null = null;
    private _createdShares: CreatedShareItem[] = [];

    /** 图片缓存：URL -> SpriteFrame */
    private _imageCache: Map<string, SpriteFrame> = new Map();

    static get instance(): ShareManager {
        if (!this._instance) {
            this._instance = new ShareManager();
        }
        return this._instance;
    }

    private constructor() {}

    get isShareMode(): boolean {
        return this._shareLevels !== null && this._shareLevels.length > 0;
    }

    get createdShares(): CreatedShareItem[] {
        return [...this._createdShares];
    }

    async createShare(title: string, levelIds: string[]): Promise<string | null> {
        try {
            const response = await HttpUtil.post<ApiEnvelope<CreateShareData>>(
                API_ENDPOINTS.SHARE_CREATE,
                { title, levelIds },
                API_TIMEOUT.DEFAULT,
            );

            if (!response.success || !response.data) {
                console.error('[ShareManager] 创建分享失败:', response.message);
                return null;
            }

            return response.data.shareCode;
        } catch (err) {
            console.error('[ShareManager] 创建分享异常:', err);
            return null;
        }
    }

    async joinShare(code: string): Promise<boolean> {
        try {
            const response = await HttpUtil.post<ApiEnvelope<JoinShareData>>(
                getShareJoinUrl(code),
                {},
                API_TIMEOUT.DEFAULT,
            );

            if (!response.success || !response.data) {
                console.error('[ShareManager] 加入分享失败:', response.message);
                return false;
            }

            const { shareCode, title, levels } = response.data;
            this._shareCode = shareCode;
            this._shareTitle = title;
            this._shareApiLevels = levels;

            const runtimeLevels: RuntimeLevelConfig[] = levels.map((level) => ({
                id: level.id,
                name: `第${level.level}关`,
                spriteFrame1: null,
                spriteFrame2: null,
                image1Description: level.image1Description,
                image2Description: level.image2Description,
                punchline: level.punchline,
                clue1: level.hint1,
                clue2: level.hint2,
                clue3: level.hint3,
                answer: level.answer,
                completed: false,
            }));

            // 预加载首关图片（两张并行加载）
            if (levels.length > 0) {
                const [sf1, sf2] = await Promise.all([
                    this._loadImage(levels[0].image1Url),
                    this._loadImage(levels[0].image2Url),
                ]);
                if (sf1) {
                    runtimeLevels[0].spriteFrame1 = sf1;
                }
                if (sf2) {
                    runtimeLevels[0].spriteFrame2 = sf2;
                }
            }

            this._shareLevels = runtimeLevels;
            console.log(`[ShareManager] 加入分享成功: ${title}, ${levels.length} 关`);
            return true;
        } catch (err) {
            console.error('[ShareManager] 加入分享异常:', err);
            return false;
        }
    }

    async fetchCreatedShares(): Promise<CreatedShareItem[] | null> {
        try {
            const response = await HttpUtil.get<ApiEnvelope<CreatedShareListData>>(
                API_ENDPOINTS.SHARE_CREATED,
                API_TIMEOUT.DEFAULT,
            );

            if (!response.success || !response.data) {
                console.error('[ShareManager] 获取我创建的挑战列表失败:', response.message);
                return null;
            }

            this._createdShares = response.data.items ?? [];
            console.log(`[ShareManager] 获取我创建的挑战列表成功: ${this._createdShares.length} 条`);
            return this.createdShares;
        } catch (err) {
            console.error('[ShareManager] 获取我创建的挑战列表异常:', err);
            return null;
        }
    }

    async ensureShareLevelReady(index: number): Promise<RuntimeLevelConfig | null> {
        if (!this._shareLevels || index < 0 || index >= this._shareLevels.length) {
            return null;
        }

        const config = this._shareLevels[index];
        if (config.spriteFrame1) {
            return config;
        }

        const apiLevel = this._shareApiLevels[index];
        if (apiLevel?.image1Url) {
            const [sf1, sf2] = await Promise.all([
                this._loadImage(apiLevel.image1Url),
                this._loadImage(apiLevel.image2Url),
            ]);
            if (sf1) {
                config.spriteFrame1 = sf1;
            }
            if (sf2) {
                config.spriteFrame2 = sf2;
            }
        }

        return config;
    }

    getShareLevelCount(): number {
        return this._shareLevels?.length ?? 0;
    }

    /**
     * 上报单关通关进度
     * @param levelId 关卡 ID
     * @param passed 是否通过
     * @param timeSpent 用时（秒）
     */
    async reportLevelProgress(
        levelId: string,
        passed: boolean,
        timeSpent: number,
    ): Promise<ReportProgressData | null> {
        if (!this._shareCode) {
            console.warn('[ShareManager] reportLevelProgress: 无分享码，跳过上报');
            return null;
        }

        try {
            const response = await HttpUtil.post<ApiEnvelope<ReportProgressData>>(
                API_ENDPOINTS.SHARE_PROGRESS,
                { shareCode: this._shareCode, levelId, passed, timeSpent },
                API_TIMEOUT.DEFAULT,
            );

            if (!response.success || !response.data) {
                console.error('[ShareManager] 上报进度失败:', response.message);
                return null;
            }

            console.log(
                `[ShareManager] 上报成功: passed=${response.data.passed}, withinTimeLimit=${response.data.withinTimeLimit}`,
            );
            return response.data;
        } catch (err) {
            console.error('[ShareManager] 上报进度异常:', err);
            return null;
        }
    }

    triggerWxShare(title: string, shareCode: string): void {
        WxSDK.shareAppMessage({
            title: title || '来挑战我出的谐音梗吧！',
            query: `shareCode=${shareCode}`,
        });
    }

    clearShareMode(): void {
        this._shareLevels = null;
        this._shareApiLevels = [];
        this._shareTitle = '';
        this._shareCode = null;
        this._imageCache.clear();
    }

    private _loadImage(url: string): Promise<SpriteFrame | null> {
        const cached = this._imageCache.get(url);
        if (cached) {
            return Promise.resolve(cached);
        }

        return new Promise((resolve) => {
            assetManager.loadRemote<ImageAsset>(url, (err, imageAsset) => {
                if (err) {
                    console.error('[ShareManager] 加载图片失败:', url, err);
                    resolve(null);
                    return;
                }
                const texture = new Texture2D();
                texture.image = imageAsset;
                const spriteFrame = new SpriteFrame();
                spriteFrame.texture = texture;
                this._imageCache.set(url, spriteFrame);
                resolve(spriteFrame);
            });
        });
    }
}
