import { _decorator, Button, Color, Component, instantiate, JsonAsset, Label, Layout, Node, ScrollView, sp, Sprite, SpriteAtlas, tween, UITransform, Vec3 } from 'cc';
import { ScrollControl } from './ScrollControl';
import { fixNum, getTimezoneOffsetString, getTranslate, hideAllChildren, isBrahmic, updateLang, waitNextFrame } from './Tools';
const { ccclass, property } = _decorator;

@ccclass('HistoryDetail')
export class HistoryDetail extends Component {

    @property(JsonAsset)
    langJson: JsonAsset | null = null;

    /**loading 动画节点*/
    @property(Node)
    loading: Node = null

    @property(Node)
    pnl_title: Node = null;

    @property(Node)
    item_round_winning: Node = null;
    @property(ScrollView)
    list_round_winning: ScrollView = null;

    @property(Node)
    item_detail: Node = null;
    @property(ScrollView)
    list_detail: ScrollView = null;

    @property(Node)
    item_symbol: Node = null;

    @property(Node)
    item_win_kind: Node = null;

    @property(Node)
    flip: Node = null;

    @property(ScrollControl)
    scrollControl: ScrollControl = null

    @property(SpriteAtlas)
    symbolsAtlas: SpriteAtlas = null!;

    dict = null
    data: any = null

    protected onLoad(): void {
        this.node.on("show_history_formula_detail", this.showFormulaDetail, this)

        this.node.on("hide_history_formula_detail", this.hideFormulaDetail, this)
        this.node.on("remark_round_winning_list", this.remarkRoundWinningList, this)


        this.list_round_winning.node.active = false

        this.item_round_winning.active = false
        this.item_symbol.active = false
        this.item_win_kind.active = false
        this.item_detail.active = false

    }

    protected start(): void {
    }

    protected onDisable(): void {
        this.node.off("show_history_formula_detail", this.showFormulaDetail, this)
        this.node.off("hide_history_formula_detail", this.hideFormulaDetail, this)
        this.node.off("remark_round_winning_list", this.remarkRoundWinningList, this)
    }

    setDetailData(data,lang:string) {

        this.data = null

        this.data = JSON.parse(JSON.stringify(data));

        this.dict = this.langJson.json[lang] ?? this.langJson.json["en"];
        updateLang(this.node, this.dict, lang)


        // console.error(`0 this.data.panDetails.length, ${this.data.panDetails.length}`)
        // for (let i = 0; i < 100; i++) {
        //     let one = JSON.parse(JSON.stringify(data.panDetails[0]))
        //     this.data.panDetails.push(one)
        // }
        // console.error(`0 this.data.panDetails.length, ${this.data.panDetails.length}`)

    }

    loadRoundWinningList(scoreInfos) {

        this.data.scoreInfos = scoreInfos

        const content = this.list_round_winning.content
        content.destroyAllChildren()
        const currencySymbol = this.data.currencySymbol

        const yellowColor = new Color(0xFF, 0xAE, 0x00)

        scoreInfos.forEach((v, i) => {
            const item = instantiate(this.item_round_winning)
            const txt_round = item.getChildByName("txt_round").getComponent(Label)
            const txt_score = item.getChildByName("txt_score").getComponent(Label)
            if (i == 0) {
                txt_round.string = getTranslate(this.dict, "Normal Spin")
                txt_round.color = yellowColor
                txt_score.color = yellowColor
            } else {
                txt_round.string = getTranslate(this.dict, "Free Spin:") + ` ${i}/${scoreInfos.length - 1}`
                txt_round.color = Color.WHITE
                txt_score.color = Color.WHITE
            }

            txt_score.string = `${currencySymbol}${fixNum(v.Score)}`

            item.name = v.StartIndex.toString()

            item.position = new Vec3()
            content.addChild(item)
        });
    }

    jumpToPage(event) {
        const item = event.target as any as Node
        const page = item.name

        this.scrollControl.jumpToPage(Number(page))
        this.hideRoundWinningList()
    }

    remarkRoundWinningList(page) {

        const txt_spin = this.pnl_title.getChildByName("txt_spin").getComponent(Label)

        if (!this.data) {
            return
        }

        if (!this.data.scoreInfos) {
            txt_spin.string = getTranslate(this.dict, "Normal Spin")
            return
        }

        let maxIdx = this.data.scoreInfos.length - 1
        let findIndex = maxIdx
        for (let i = maxIdx; i >= 0; i--) {
            let scoreInfo = this.data.scoreInfos[i]
            if (page >= scoreInfo.StartIndex) {
                findIndex = i
                break
            }
        }

        // console.log(`findIndex, ${findIndex}`)

        if (findIndex == 0) {
            txt_spin.string = getTranslate(this.dict, "Normal Spin")
        } else {
            txt_spin.string = getTranslate(this.dict, "Free Spin:") + `${findIndex}/${maxIdx}`
        }

        const yellowColor = new Color(0xFF, 0xAE, 0x00)
        this.list_round_winning.content.children.forEach((item, i) => {
            const txt_round = item.getChildByName("txt_round").getComponent(Label)
            const txt_score = item.getChildByName("txt_score").getComponent(Label)
            if (i == findIndex) {
                txt_round.color = yellowColor
                txt_score.color = yellowColor
            } else {
                txt_round.color = Color.WHITE
                txt_score.color = Color.WHITE
            }
        })
    }

    showRoundWinningList() {
        let isActive = this.list_round_winning.node.active
        if (isActive) {
            this.hideRoundWinningList()
            return
        }

        const node = this.list_round_winning.node
        const content = this.list_round_winning.content
        content.children.forEach(v => { v.active = true })
        node.active = true

        let startVec = new Vec3(0, 3000)
        let endVec = new Vec3(0, 800)

        node.position = startVec
        tween(node).to(0.2, { position: endVec }).call(() => {
            let sp = this.pnl_title.getChildByName("txt_spin").getChildByName("sp")
            sp.scale = new Vec3(1, -1)
        }).start()
    }

    hideRoundWinningList() {
        const node = this.list_round_winning.node
        const content = this.list_round_winning.content

        let startVec = new Vec3(0, 3000)
        tween(this.list_round_winning.node).to(0.2, { position: startVec })
            .call(() => {
                content.children.forEach(v => { v.active = false })
                node.active = false
                let sp = this.pnl_title.getChildByName("txt_spin").getChildByName("sp")
                sp.scale = new Vec3(1, 1)
            }).start()
    }

    // 加载一盘数据
    loadOne(item: Node, pan, idx) {

        item.position = new Vec3()
        this.list_detail.content.addChild(item)

        const currencySymbol = this.data.currencySymbol
        const currency = this.data.currency

        const info = item.getChildByName("info");
        info.getChildByName("txt_transaction").getComponent(Label).string = this.data.roundId;

        let bet = idx == 0 ? fixNum(pan.Bet) : fixNum(0)
        info.getChildByName("txt_bet").getComponent(Label).string = bet;

        info.getChildByName("Label_Bet").getComponent(Label).string = getTranslate(this.dict, "Bet") + `(${currencySymbol})`;

        info.getChildByName("txt_profit").getComponent(Label).string = fixNum(pan.ProfitScore);
        info.getChildByName("Label_Profit").getComponent(Label).string = getTranslate(this.dict, "Profit") + `(${currencySymbol})`;

        info.getChildByName("txt_balance_before").getComponent(Label).string = fixNum(pan.Balance - pan.ProfitScore) + "➡️";
        info.getChildByName("txt_balance_after").getComponent(Label).string = fixNum(pan.Balance);

        info.getChildByName("Label_Balance").getComponent(Label).string = getTranslate(this.dict, "Balance") + `(${currencySymbol})`;

        const content = item.getComponent(ScrollView).content;

        const bet_info = content.getChildByName("bet_info")
        if (pan.RoundInfo) {
            const txt_round = bet_info.getChildByName("txt_round").getComponent(Label)
            txt_round.string = getTranslate(this.dict, "Round:") + ` ${pan.RoundInfo.Current}/${pan.RoundInfo.Total}`
        } else {
            bet_info.getChildByName("txt_round").active = false
        }

        // 顶上四个横着摆的
        const hor_symbols = content.getChildByName("hor_symbols")
        hor_symbols.destroyAllChildren()
        pan.PanColor.Top.forEach((v, i) => {
            const item_symbol = instantiate(this.item_symbol)

            const bg = item_symbol.getChildByName("bg").getComponent(Sprite)
            const path_bg = `symbol_bg_${v}`
            bg.spriteFrame = this.symbolsAtlas.getSpriteFrame(path_bg)

            const symbol = item_symbol.getChildByName("symbol").getComponent(Sprite)
            const path_symbol = `symbol_${v}_x1`
            symbol.spriteFrame = this.symbolsAtlas.getSpriteFrame(path_symbol)

            //顶部横着的一排全是铁框
            const frame = item_symbol.getChildByName("frame").getComponent(Sprite)
            const path_frame = `frame_0`
            frame.spriteFrame = this.symbolsAtlas.getSpriteFrame(path_frame)
            // scatter 和 wild symbol没有金/银/铁框
            frame.node.active = !this.isScatterOrWild(v)

            item_symbol.position = new Vec3()
            item_symbol.active = true
            hor_symbols.addChild(item_symbol)
        })

        // 下面几列竖着摆的
        // 5行6列 的网格，固定有6个竖列， 每一列2～5个symbol
        const vert_symbols = content.getChildByName("vert_symbols")
        vert_symbols.children.forEach(vert => { vert.destroyAllChildren() });
        let curCrossIdx = 1

        // 每一竖列最多有5个symbol
        const EACH_LINE_MAX_SYMBOL = 5

        let curSymbolIdx = pan.CroSymbols[curCrossIdx]?.PosFirst

        // console.log(`curCrossIdx=${curCrossIdx}`)
        // console.log(`curSymbolIdx=${curSymbolIdx}`)

        for (let i = 0; i < pan.PanColor.Bottom.length;) {
            // 如果i不等于当前需要处理的连体符号，正常生成一个symbol
            if (i != curSymbolIdx) {
                const item_symbol = instantiate(this.item_symbol)
                let v = pan.PanColor.Bottom[i]

                const bg = item_symbol.getChildByName("bg").getComponent(Sprite)
                const path_bg = `symbol_bg_${v}`
                bg.spriteFrame = this.symbolsAtlas.getSpriteFrame(path_bg)

                const symbol = item_symbol.getChildByName("symbol").getComponent(Sprite)
                const path_symbol = `symbol_${v}_x1`
                symbol.spriteFrame = this.symbolsAtlas.getSpriteFrame(path_symbol)

                //单个symbol 只有铁框
                const frame = item_symbol.getChildByName("frame").getComponent(Sprite)
                const path_frame = `frame_0`
                frame.spriteFrame = this.symbolsAtlas.getSpriteFrame(path_frame)

                // scatter 和 wild symbol没有金/银/铁框
                frame.node.active = !this.isScatterOrWild(v)

                item_symbol.position = new Vec3()
                item_symbol.active = true

                // 通过 i 计算在第几行第几列

                let row = i % EACH_LINE_MAX_SYMBOL
                let line = Math.floor(i / EACH_LINE_MAX_SYMBOL)

                // console.log(`第${i}个元素在，第${row}横行，第${line}竖列`)

                vert_symbols.children[line].addChild(item_symbol)

                i++
            } else {
                // console.log(`当前处理到CroSymbols ,curCrossIdx=${curCrossIdx}`)
                // console.log(`遇到了连体元素i=${i},curSymbolIdx = ${curSymbolIdx}`)

                const item_symbol = instantiate(this.item_symbol)
                let v = pan.PanColor.Bottom[i]

                let length = pan.CroSymbols[curCrossIdx].PosLast - pan.CroSymbols[curCrossIdx].PosFirst + 1

                // console.log(`${length}连框`)

                // 组件长度拉长
                item_symbol.getComponent(UITransform).height = item_symbol.getComponent(UITransform).height * length;

                // 背景拉长
                const bg = item_symbol.getChildByName("bg").getComponent(Sprite)
                const path_bg = `symbol_bg_${v}`
                bg.spriteFrame = this.symbolsAtlas.getSpriteFrame(path_bg);
                bg.node.getComponent(UITransform).height = bg.node.getComponent(UITransform).height * length;

                if (this.isScatterOrWild(v)) {

                    const symbol = item_symbol.getChildByName("symbol").getComponent(Sprite)
                    const path_symbol = `symbol_${v}_x${length}`
                    symbol.spriteFrame = this.symbolsAtlas.getSpriteFrame(path_symbol)

                    //scatter&wild 没有框
                    const frame = item_symbol.getChildByName("frame").getComponent(Sprite)
                    frame.node.active = false

                } else {

                    const symbol = item_symbol.getChildByName("symbol").getComponent(Sprite)
                    const path_symbol = `symbol_${v}_x1`
                    symbol.spriteFrame = this.symbolsAtlas.getSpriteFrame(path_symbol)

                    // pan.CroSymbols?.curCrossIdx?.Type
                    const frame = item_symbol.getChildByName("frame").getComponent(Sprite)
                    const path_frame = `frame_${pan.CroSymbols[curCrossIdx]?.Type}`
                    frame.spriteFrame = this.symbolsAtlas.getSpriteFrame(path_frame)

                    let height = frame.node.getComponent(UITransform).height * length;
                    frame.node.getComponent(UITransform).height = height;
                }

                item_symbol.position = new Vec3()
                item_symbol.active = true

                // 通过 i 计算在第几行第几列
                let tmp = i
                let row = tmp % EACH_LINE_MAX_SYMBOL
                let line = Math.floor(tmp / EACH_LINE_MAX_SYMBOL)

                // console.log(`第${i}个元素在，第${line}竖列，第${row}横行`)

                vert_symbols.children[line].addChild(item_symbol)

                curCrossIdx += 1
                curSymbolIdx = pan.CroSymbols[curCrossIdx]?.PosFirst

                // 连体symbol的数据视为一个
                i = i + length
            }
        }

        // No Winning Combination
        const node_no_winning = content.getChildByName("node_no_winning")
        node_no_winning.active = pan.Score <= 0

        // 
        const node_feature_buy = content.getChildByName("node_feature_buy")
        const isActive = this.data.isBuy && idx == 0
        node_feature_buy.active = isActive

        // Win Multiplier x ?
        const node_win_multiplier = content.getChildByName("node_win_multiplier")
        const txt_win_multiplier = node_win_multiplier.getChildByName("txt_win_multiplier")
        txt_win_multiplier.getComponent(Label).string = getTranslate(this.dict, "Win Multiplier") + " x " + pan.WinMultiPlier
        node_win_multiplier.active = true

        // scatter 数量统计 node_scatter
        if (pan.ScNum >= 4 && pan.GetGamesTimes >= 10) {
            const node_scatter = content.getChildByName("node_scatter")
            const txt_scatter_num = node_scatter.getChildByName("txt_scatter_num").getComponent(Label)
            txt_scatter_num.string = "x " + pan.ScNum

            const txt_free_spin = node_scatter.getChildByName("txt_free_spin").getComponent(Label)
            txt_free_spin.string = pan.GetGamesTimes + " " + getTranslate(this.dict, "Free Spins")

            node_scatter.active = true
        }else{
            const node_scatter = content.getChildByName("node_scatter")
            node_scatter.removeFromParent()
            node_scatter.destroy()
        }

        const symbolWinInfosKeys = Object.keys(pan.WinInfo.Desc)

        // 赢分符号统计
        if (symbolWinInfosKeys.length > 0) {
            const node_formula = content.getChildByName("node_formula")

            symbolWinInfosKeys.forEach((v) => {
                // console.log("symbol:", v, " = ", pan.SymbolWinInfos[v])

                const symbolWinInfo = pan.pan.WinInfo.Desc[v]
                const item_win_kind = instantiate(this.item_win_kind)

                item_win_kind.name = `item_win_kind_${v}`

                const sp = item_win_kind.getChildByName("sp").getComponent(Sprite)
                const path_symbol = `symbol_${v}_x1`
                sp.spriteFrame = this.symbolsAtlas.getSpriteFrame(path_symbol)

                const txt_kind = item_win_kind.getChildByName("txt_kind").getComponent(Label)
                txt_kind.string = symbolWinInfo.WinAxisNum.toString() + " " + getTranslate(this.dict, "of a Kind")

                const txt_ways = item_win_kind.getChildByName("txt_ways").getComponent(Label)
                txt_ways.string = symbolWinInfo.Ways.toString() + " " + getTranslate(this.dict, "way(s)")

                const txt_win = item_win_kind.getChildByName("txt_win").getComponent(Label)
                txt_win.string = currencySymbol + fixNum(symbolWinInfo.Score)

                const txt_formula = item_win_kind.getChildByName("txt_formula").getComponent(Label)
                txt_formula.string = symbolWinInfo.Formula

                const formula_detail = item_win_kind.getChildByName("formula_detail")
                const txt_formual_detail = formula_detail.getChildByName("txt_formual_detail").getComponent(Label)
                txt_formual_detail.string = symbolWinInfo.FormulaDetail
                formula_detail.active = false

                item_win_kind.position = new Vec3()
                item_win_kind.active = true


                node_formula.addChild(item_win_kind)
            })

            // 每一条 item_win_kind 可以点开 自己的 formula_detail
            // 要求列表前面的item_win_kind弹出来formula_detail ，盖住后面的 item_win_kind
            // 但 addChild的顺序决定后 后面会盖住前面，所以这里要反转一下
            // 而且一定要关掉 Layout ，因为它会把 SiblingIndex最小的放到最上面
            const lyt = node_formula.getComponent(Layout)
            lyt.updateLayout()
            lyt.enabled = false

            const children = node_formula.children.slice().reverse();
            children.forEach((child, i) => {
                child.active = true
                child.setSiblingIndex(i);
            });

            const contentlyt = content.getComponent(Layout)
            contentlyt.updateLayout()
            contentlyt.enabled = false
            // 多给一截滑动空间
            content.getComponent(UITransform).height = content.getComponent(UITransform).height + 160
        }

        


        hideAllChildren(item)

    }

    async loadDetailList() {

        // 时间
        let pnl_title = this.node.getChildByName("pnl_title")
        let txt_time = pnl_title.getChildByName("txt_time").getComponent(Label)
        const timestamp = this.data.startTime;
        const date = new Date(timestamp * 1000); // JS 使用毫秒，所以要 *1000

        const pad = (n: number) => (n < 10 ? '0' + n : String(n));
        const formatted = `${date.getFullYear()}/${pad(date.getMonth() + 1)}/${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`;

        let str = formatted + getTimezoneOffsetString()
        txt_time.string = str

        const currencySymbol = this.data.currencySymbol
        const currency = this.data.currency

        const scoreInfos = this.data.panDetails[0].ScoreInfos
        const btn_winning_list = this.pnl_title.getChildByName("txt_spin").getChildByName("btn_winning_list").getComponent(Button)
        const sp = this.pnl_title.getChildByName("txt_spin").getChildByName("sp")
        if (scoreInfos) {
            this.loadRoundWinningList(scoreInfos)
            btn_winning_list.interactable = true
            sp.active = true
        } else {
            btn_winning_list.interactable = false
            sp.active = false
        }


        this.data.panDetails.forEach(async (pan, idx) => {
            const item = instantiate(this.item_detail);
            item.active = true
            this.loadOne(item, pan, idx)

            if (idx == this.data.panDetails.length - 1) {
                // console.log("已全部生成完")
                this.hideLoading()
                this.scrollControl.jumpToPage(0)
            }

            // 等待下一帧再生成下一个
            await waitNextFrame();
        })

        this.scrollControl.vert_scrollView = this.list_detail.content.children[0].getComponent(ScrollView)
        this.list_detail.node.active = true
    }


    // wild 是0， scatter 是1
    isScatterOrWild(v) {
        return v == 0 || v == 1
    }

    clickPageUp() {
        this.scrollControl.pageUp()
    }

    clickPageDown() {
        this.scrollControl.pageDown()
    }

    async entryFinish() {
        // this.node.children.forEach((node, i) => {
        //     node.active = true
        // })

        this.showLoading()
        await this.loadDetailList()
    }

    removeReturnBtn() {
        let btn_return = this.node.getChildByName("btn_return")
        btn_return.destroy()
    }
    clickReturn() {
        const self = this
        tween(this.node).to(0.2, { position: new Vec3(2000, 0) })
            .call(() => {
                self.node.destroy()
            })
            .start()
    }

    // 传过来的是 item_win_kind
    showFormulaDetail(item_win_kind) {

        // 隐藏其他的formula_detail
        item_win_kind.parent.children.forEach(child => {
            if (child != item_win_kind)
                child.getChildByName("formula_detail").active = false
        })

        // 显示就隐藏，隐藏就显示
        let isActive = item_win_kind.getChildByName("formula_detail").active
        item_win_kind.getChildByName("formula_detail").active = !isActive

    }

    // 传过来的是 item_win_kind
    showFormulaDetail2(event) {
        const btn = event.target as Node as any
        const item_win_kind = btn.parent
        // 隐藏其他的formula_detail
        item_win_kind.parent.children.forEach(child => {
            if (child != item_win_kind)
                child.getChildByName("formula_detail").active = false
        })

        // 显示就隐藏，隐藏就显示
        let isActive = item_win_kind.getChildByName("formula_detail").active
        item_win_kind.getChildByName("formula_detail").active = !isActive

    }

    hideFormulaDetail(scrollVeiw: ScrollView) {
        const node_formula = scrollVeiw.content.getChildByName("node_formula")
        node_formula.children.forEach(node => {
            node.getChildByName("formula_detail").active = false
        })
    }
    showLoading() {
        this.loading.active = true
        let sk = this.loading.getComponent(sp.Skeleton)
        sk.paused = false
        sk.loop = true
    }

    hideLoading() {
        let sk = this.loading.getComponent(sp.Skeleton)
        sk.paused = true
        sk.loop = false

        this.loading.active = false

    }
}

