import { _decorator, Component, SpriteFrame, AudioClip, Animation, Sprite, Label, Node, color, AudioSource, tween, UIOpacity, assetManager, Texture2D, ImageAsset, resources } from 'cc';
const {ccclass, property} = _decorator;

@ccclass('MatchPanel')
export default class MatchPanel extends Component {
    @property({type: SpriteFrame})
    private frameBoy: SpriteFrame | null = null;
    @property({type: SpriteFrame})
    private frameGirl: SpriteFrame | null = null;
    @property({type: SpriteFrame})
    private genderBoy: SpriteFrame | null = null;
    @property({type: SpriteFrame})
    private genderGirl: SpriteFrame | null = null;
    @property({type: AudioClip})
    private matchSuccess: AudioClip | null = null;
    @property({type: Animation})
    private meteorLine: Animation | null = null;
    @property({type: Sprite})
    private frameSelf: Sprite | null = null;
    @property({type: Sprite})
    private avatarSelf: Sprite | null = null;
    @property({type: Sprite})
    private genderSelf: Sprite | null = null;
    @property({type: Label})
    private nameSelf: Label | null = null;
    @property({type: Sprite})
    private frameOther: Sprite | null = null;
    @property({type: Sprite})
    private avatarOther: Sprite | null = null;
    @property({type: Sprite})
    private genderOther: Sprite | null = null;
    @property({type: Label})
    private nameOther: Label | null = null;
    @property({type: Node})
    private backGround: Node | null = null;
    @property({type: Node})
    private content: Node | null = null;
    @property({type: Label})
    private labelMatching: Label | null = null;
    @property({type: Label})
    private labelTime: Label | null = null;
    @property({type: Label})
    private labelWaitingTime: Label | null = null;
    @property({type: Node})
    private points: Node | null = null;
    private waitingTime: number = 0;
    private countingTime: boolean = true;

    public static GENDER_BOY = "GENDER_BOY";
    public static GENDER_GIRL = "GENDER_GIRL";
    public static Instance: MatchPanel = null;

    protected onLoad(): void {
        MatchPanel.Instance = this;
    }

    protected onDestroy(): void {
        if (MatchPanel.Instance === this) MatchPanel.Instance = null;
    }

    protected update(dt: number): void {
        if (this.countingTime) {
            this.waitingTime += dt;
            this.labelTime.string = this._timeFormatMS(this.waitingTime*1000);
        }
    }

    public renderMyInfo(nickName: string, gender: string, avatar: SpriteFrame | string) {
        //render self info
        this.nameSelf.string = nickName;
        if (avatar instanceof SpriteFrame) {
            this.avatarSelf.spriteFrame = avatar;
        } else {
            this._loadSpriteFrame(avatar, (spriteFrame: SpriteFrame) => {
                this.avatarSelf.spriteFrame = spriteFrame;
            });
        }
        if (gender === MatchPanel.GENDER_GIRL) {
            this.frameSelf.spriteFrame = this.frameGirl;
            this.genderSelf.spriteFrame = this.genderGirl;
        } else {
            this.frameSelf.spriteFrame = this.frameBoy;
            this.genderSelf.spriteFrame = this.genderBoy;
        }

       //rendere other style according to self style
        if (gender === MatchPanel.GENDER_GIRL) {
            let pointColor = color(30, 144, 255, 255);
            this.frameOther.spriteFrame = this.frameBoy;
            this.genderOther.spriteFrame = this.genderBoy;
            this.points.children.forEach((child: Node) => {
                child.getComponent(Sprite).color = pointColor;
            });
        } else {
            let pointColor = color(255, 105, 180, 255);
            this.frameOther.spriteFrame = this.frameGirl;
            this.genderOther.spriteFrame = this.genderGirl;
            this.points.children.forEach((child: Node) => {
                child.getComponent(Sprite).color = pointColor;
            });
        }
    }

    public renderOtherInfo(nickName: string, gender: string, avatar: SpriteFrame | string) {
        //render other info
        this.nameOther.string = nickName;
        if (avatar instanceof SpriteFrame) {
            this.avatarOther.spriteFrame = avatar;
        } else {
            this._loadSpriteFrame(avatar, (spriteFrame: SpriteFrame) => {
                this.avatarOther.spriteFrame = spriteFrame;
            });
        }
        if (gender === MatchPanel.GENDER_GIRL) {
            this.frameOther.spriteFrame = this.frameGirl;
            this.genderOther.spriteFrame = this.genderGirl;
        } else {
            this.frameOther.spriteFrame = this.frameBoy;
            this.genderOther.spriteFrame = this.genderBoy;
        }

        this.countingTime = false;

        this.points.destroy();

        this.labelMatching.string = "匹配完成";
        this.meteorLine.play("MeteorLine");
        this.labelTime.node.destroy();
        this.labelWaitingTime.node.destroy();
        
        this._playOneShot(this.matchSuccess);

        let tweenAfter = tween(this.backGround.getComponent(UIOpacity))
            .to(0.5, {opacity: 55});
        tween(this.content.getComponent(UIOpacity))
            .delay(2)
            .to(1, {opacity: 0})
            .call(() => tweenAfter.start())
            .start()
    }

    //=====================private=====================

    private _timeFormatMS(millis:number) {
        let minute = Math.floor(millis / 1000 / 60);
        let second = Math.floor(millis / 1000 % 60);
        return (minute < 10 ? '0' : '') + minute + ':' + (second < 10 ? '0' : '') + second;
    }

    private _playOneShot(audioClip: AudioClip) {
        let as = this.node.getComponent(AudioSource);
        if (!as) as = this.node.addComponent(AudioSource);
        as.playOneShot(audioClip);
    }

    private _loadSpriteFrame(url: string, onSuccess: (spriteFrame: SpriteFrame) => void) {
        if (url.startsWith("data:image/")) {
            const img = new Image();
            img.src = url;
            const tex = new Texture2D();
            img.onload = () => {
                tex.reset({
                    width: img.width,
                    height: img.height,
                });
                tex.uploadData(img, 0, 0);
                const sp = new SpriteFrame();
                sp.texture = tex;
                onSuccess(sp);
            };
        } else if (url.startsWith("http")) {
            assetManager.loadRemote<ImageAsset>(url, {ext: ".jpg"}, (err, imageAsset) => {
                if (err) return;
                const spriteFrame = new SpriteFrame();
                const texture = new Texture2D();
                texture.image = imageAsset;
                spriteFrame.texture = texture;
                onSuccess(spriteFrame);
            });
        } else {
            resources.load(url + "/spriteFrame", SpriteFrame, (err, spriteFrame) => {
                if (err) return;
                onSuccess(spriteFrame);
            });
        }
    }
}


