import { JsonAsset, resources, TextAsset } from "cc";

export interface DataBase{
    id: number;
}

//一个文件 对应一个数据操作者
class DataCtrl{
    private _datas: Map<number, DataBase> = new Map();
    constructor(asset: JsonAsset | TextAsset){
        if(asset instanceof JsonAsset){
            const datas: DataBase[] = <DataBase[]>asset.json;
            for(const data of datas){
                this._datas.set(Number(data.id), data);
            }
            return;
        }
        //表格数据
        if(asset instanceof TextAsset){
            this._parseCSV(asset.text);
        }
    }
    private _parseCSV(text: string){
        const lines: string[] = text.split("\r\n");
        //表格中 单元格以逗号,分开
        const keys: string[] = lines[0].split(",");
        const types: string[] = lines[1].split(",");
        //有用的数据
        for(let i = 2; i < lines.length - 1; i++){
            const cols: string[] = lines[i].split(",");
            //每一行就是一个数据 创建一个空对象 存储数据
            let obj = {};
            for(let j = 1; j <cols.length; j++){
                //获取当前字符串值 根据类型定数据
                let val = cols[j];
                let v;
                switch(types[j]){
                    case "boolean":
                        v = Boolean(Number(val));
                        break;
                    case "string":
                        v = val;
                        break;
                    case "number":
                        v = Number(val);
                        break;
                    case "string[]":
                        v = val.split(";");
                        break;
                    case "number[]":
                        v = val.split(";");
                        let arr:number[] = [];
                        for(const info of v){
                            arr.push(Number(info));
                        }
                        v = arr;
                        break;
                    default:
                        break;
                }
                obj[keys[j]] = v;
            }
            const data: DataBase = <DataBase>obj;
            this._datas.set(Number(data.id), data);
        }
    }

    //通过id获取某个数据
    getData<T extends DataBase>(id: number):T{
        return <T>this._datas.get(id);
    }

    //获取当前文件解析的所有数据
    getAllData<T extends DataBase>(): T[]{
        return <T[]>Array.from(this._datas.values());
    }
}

//管理所有数据操作者
class DataManager{
    private _dataCtrls: Map<string, DataCtrl> = new Map();
    static instance: DataManager = null;

    async loadDataDir(dir: string){
        const assets: TextAsset[] | JsonAsset[] = await new Promise((values, reject)=>{
            resources.loadDir(dir,(err: Error, assets: TextAsset[] | JsonAsset[])=>{
                if(err){
                    reject(err);
                }
                else{
                    values(assets);
                }
            })
        })

        for(const asset of assets){
            this._dataCtrls.set(asset.name, new DataCtrl(asset));
        }
    }

    getData<T extends DataBase>(id: number, ctrlName?: string):T{
        //通过文件名 获取 数据操作者
        if(ctrlName){
            return this._dataCtrls.get(ctrlName).getData<T>(id);
        }
        //遍历所有的数据操作者 看看谁有id 为 id 的数据
        for(const ctrl of Array.from(this._dataCtrls.values())){
            const data = ctrl.getData<T>(id);
            if(data){return data;}
        }
        //都没有
        return null;
    }

    getAllDataByName<T extends DataBase>(name: string):T[]{
        //获取文件名为 name 的数据操作者的所有数据
        return this._dataCtrls.get(name).getAllData<T>();
    }
}

export const dataMgr: DataManager = DataManager.instance = new DataManager();