import { _decorator, error, TextAsset } from 'cc'
import { CsvParser } from './CsvParser'
import { Constants } from '../../data/Constants'
import { Logger } from '../../extend/Logger'
import { Singleton } from '../manager/Singleton'
import { bundleMgr } from '../manager/BundleManager'
const { ccclass, property } = _decorator
//wws
@ccclass('CsvManager')
class CsvManager extends Singleton {
   // 表格所在的目录
   private _directory: string = 'csv'
   // 表格解析器单例
   private _parser: CsvParser = new CsvParser()

   /*调用事例 加载所有CSV表
    await csvMgr.loadAll(
        (finished, total) => {
            Logger.log(`加载进度: ${finished}/${total}`);
        },
        (isAllFinished, tableName, data) => {
            Logger.log(`CSV加载完成`+ tableName);
        }
    );
    //获取表数据(异步)
    let levels = csvMgr.getTable("levels")
    Logger.log("物品表数据:", JSON.stringify(levels));
    //获取表数据 (异步)
    csvMgr.getTable("item").then(table => {
        Logger.log("物品表数据:", table);
    });*/

   /**
    * 加载所有CSV配置表
    * @param onProgress @param onProgress 进度回调 (isAllFinished: 是否全部完成, tableName: 表名, data: 表数据)
    * @returns 当所有表加载完成或出错时resolve/reject
    */
   public async loadAll(
      onProgress?: (
         isAllFinished: boolean,
         finishCount: number,
         total: number,
         tableName?: string,
         data?: any[]
      ) => void
   ): Promise<void> {
      try {
         const bundle = await bundleMgr.getBundle(Constants.bundleName.data)
         //1. 获取目录下所有CSV文件列表（不实际加载资源）
         const fileList: Array<any> = bundle.getDirWithPath(this._directory)
         if (fileList.length === 0) {
            Logger.warn(`目录 ${this._directory} 下未找到CSV文件`)
            return
         }
         const total = fileList.length
         let loadedCount = 0
         //2. 逐个加载文件
         for (const file of fileList) {
            const asset = await this._loadSingleTable(file.path)
            //解析数据并缓存
            const data = this._parser.addTable(asset.name, asset.text)
            //更新进度和回调
            loadedCount++
            const tableName = file.path.split('/').pop()
            onProgress?.(loadedCount == total, loadedCount, total, tableName, data)
         }
      } catch (err) {
         error('加载CSV表过程中发生错误:', err)
         throw err // 重新抛出错误，让调用方可以捕获
      }
   }

   /**
    * 加载单个CSV表
    * @param path 表路径
    * @returns Promise<TextAsset> 加载成功的TextAsset
    * @private
    */
   private async _loadSingleTable(path: string): Promise<TextAsset> {
      const bundle = await bundleMgr.getBundle(Constants.bundleName.data)
      return new Promise<TextAsset>((resolve, reject) => {
         bundle.load(path, TextAsset, (err, asset) => {
            if (err || !asset) {
               reject(err || new Error(`加载资源 ${path} 失败`))
            } else {
               resolve(asset)
            }
         })
      })
   }

   /**
    * 调用事例 csvMgr.getTableArr('weapon');
    * 异步获取表数据（如果表未加载会自动加载）
    * @param tableName 表名
    * @returns Promise<T[]> 表数据数组
    */
   public getTableArr(tableName: string): any {
      return this._parser.getTableArr(tableName)
   }

   /**调用事例 csvMgr.findOne('weapon', w => w.quality === 'epic')
    * 查询单条记录
    * @param tableName 表名
    * @param predicate 查询条件函数
    * @returns 匹配的第一条记录或undefined
    */
   public findOne<T = any>(tableName: string, predicate: (item: T) => boolean): T | undefined {
      return this.getTableArr(tableName).find(predicate)
   }

   /**
    * 查询多条记录
    * @param tableName 表名
    * @param predicate 查询条件函数
    * @returns 匹配的所有记录数组
    */
   public findMany<T = any>(tableName: string, predicate: (item: T) => boolean): T[] {
      return this.getTableArr(tableName).filter(predicate)
   }
}
//全局单例
export const csvMgr = CsvManager.ins()
