
const FairyGUI = CS.FairyGUI;
const FairyEditor = CS.FairyEditor
import FileUtils from "./FileUtils";
import UIWindow, { WindData } from "./UIWindow"
const App = FairyEditor.App;

type FailureAssetData = {
    url: string,
    failure: string[],
}

export default class FindFailureAssetsWnd extends UIWindow {

    constructor() {
        super(new WindData("Extend", "FindFailureAssets"))
    }

    static show() {
        let url = FileUtils.joinUrl("Extend", "FindFailureAssets")
        if (UIWindow.FindUrl(url) == undefined) {
            UIWindow.add(new this)
        }

        super.show(url)
    }

    private state: CS.FairyGUI.Controller;
    private check: CS.FairyGUI.GButton
    private progress: CS.FairyGUI.GProgressBar
    private resList: CS.FairyGUI.GList;

    private assets = new Map<string, FindFailureAssetsWnd>()
    protected onInit(): void {
        super.onInit();
        this.state = this.contentPane.GetController("state");
        this.check = this.contentPane.GetChild("check").asButton;
        this.progress = this.contentPane.GetChild("progress").asProgress;
        this.resList = this.contentPane.GetChild("resList").asList;

        this.resList.itemRenderer = this.onItemRenderer.bind(this);

        this.resList.onClickItem.Add(this.onListClickItem.bind(this))

        this.check.onClick.Add(this.onCheckClick.bind(this))

        let cancel = this.contentPane.GetChild("close").asButton
        cancel.onClick.Add(this.onCancelClick.bind(this))

        this.resList.SetVirtual();
    }

    protected onShown(): void {
        super.onShown();

    }

    protected onHide(): void {
        super.onHide();
        this.resList.data = null;
        this.resList.numItems = 0;
    }

    private async onCheckClick() {
        if (this.state.selectedIndex == 0) {
            this.state.selectedIndex = 1;
            this.assets.clear();
            let pkgs = App.project.allPackages;
            this.progress.value = 0;

            this.progress.max = FileUtils.getAllPackageItemsCount();

            for (let index = 0; index < pkgs.Count; index++) {
                let pkg = pkgs.get_Item(index);
                if (this.state.selectedIndex == 0) break
                for (let j = 0; j < pkg.items.Count; j++) {
                    if (this.state.selectedIndex == 0) break
                    let item = pkg.items.get_Item(j);
                    this.progress.value += 1
                    if (item.type != CS.FairyEditor.FObjectType.COMPONENT) {
                        continue
                    }
                    //@ts-ignore
                    this.getFailureAssets(item, this.assets, 0)
                    if (this.progress.value % 30 == 0) {
                        await FileUtils.sleep(0)
                    }
                }
            }
            App.consoleView.Log("查找完毕")
            this.state.selectedIndex = 0;
            let asset = Array.from(this.assets).map(item => item[1]);
            this.resList.data = asset;
            this.resList.numItems = asset.length;

            this.contentPane.GetChild("projectCount").asTextField.templateVars = FileUtils.getTemplateVars(['value'],[asset.length.toString()]);

        } else {
            this.state.selectedIndex = 0;
        }
    }

    private onItemRenderer(index: number, obj: CS.FairyGUI.GComponent): void {
        let data = this.resList.data[index] as FailureAssetData;
        obj.data = data;
        let packageItem = App.project.GetItemByURL(data.url)
        obj.GetChild("title").text = packageItem.name

        obj.__onDispose = () => {
            obj.GetChild("title").text = ''
            obj.data = null;
        }
    }

    private onListClickItem(item: CS.FairyGUI.EventContext): void {
        let data = item.data.data as FailureAssetData;
        let packageItem = App.project.GetItemByURL(data.url)
        App.consoleView.Log(FileUtils.getUBBUrl(packageItem.GetURL(),`包含无效URL的组件:${packageItem.name}`))
        for (let index = 0; index < data.failure.length; index++) {
            App.consoleView.Log('无效URL:'+data.failure[index])
        }
    }

    private onCancelClick() {
        let self = this;
        this.Hide();
        FairyGUI.Timers.inst.Add(0.05, 1, () => {
            UIWindow.remove(self)
        })
    }
    /**查找失效资源 */
    private getFailureAssets(item: CS.FairyEditor.FPackageItem, map: Map<string, { url: string, failure: string[] }>, quertIndex) {
        let xml = CS.FairyEditor.XMLExtension.Load(item.file)
        if (!xml) {
            App.consoleView.LogError(`PackageItem找不到配置文件. Name:${item.name} Index:${quertIndex} File:${item.file}`)
            return quertIndex;
        }
        let rootElements = xml.Elements()
        for (let index = 0; index < rootElements.Count; index++) {
            let child = rootElements.get_Item(index)
            if (child.name != 'displayList') continue
            let childElements = child.Elements();
            for (let index = 0; index < childElements.Count; index++) {
                const element = childElements.get_Item(index);
                if (element.name == 'loader' || element.name == 'loader3D') {
                    if (element.GetAttribute('clearOnPublish')) continue
                    let url = element.GetAttribute('url')
                    if (!url) continue
                    //没清理依赖
                    let packageItem = App.project.GetItemByURL(url)
                    if (!packageItem) {
                        if (!map.has(item.GetURL())) {
                            map.set(item.GetURL(), {
                                url: item.GetURL(),
                                failure: []
                            })
                        }
                        map.get(item.GetURL()).failure.push(`name:${element.GetAttribute("name")} file:${element.GetAttribute("fileName")} url:${url}`)
                    }
                    else if (!map.has(packageItem.GetURL())) {
                        if (packageItem.type == FairyEditor.FPackageItemType.COMPONENT) {
                            quertIndex = this.getFailureAssets(packageItem, map, quertIndex)
                        }
                        quertIndex += 1;
                    }
                } else {
                    let src = element.GetAttribute("src")
                    if (!src) {
                        //系统资源 不需要依赖
                        continue
                    }
                    let pkg = element.GetAttribute("pkg")
                    if (!pkg) {
                        //自己依赖包的资源 所以不需要pkg
                        pkg = item.owner.id;
                    }
                    let url = `ui://${pkg}${src}`
                    if (src == null) App.consoleView.Log(element.name)
                    let packageItem = App.project.GetItemByURL(url)
                    if (!packageItem) {
                        if (!map.has(item.GetURL())) {
                            map.set(item.GetURL(), {
                                url: item.GetURL(),
                                failure: []
                            })
                        }
                        map.get(item.GetURL()).failure.push(`name:${element.GetAttribute("name")} file:${element.GetAttribute("fileName")} url:${url}`)
                    }
                    else if (!map.has(packageItem.GetURL())) {
                        if (packageItem.type == FairyEditor.FPackageItemType.COMPONENT) {
                            quertIndex = this.getFailureAssets(packageItem, map, quertIndex)
                        }
                        quertIndex += 1;
                    }
                }
            }
        }
        return quertIndex
    }

    
}

