import { message } from 'ant-design-vue';
import { utils, writeFile } from 'xlsx';

export interface ExportColumn<T> {
  title: string;
  dataIndex: keyof T | string;
  formatter?: (record: T) => unknown;
}

interface ExportOptions<T> {
  filename: string;
  columns: ExportColumn<T>[];
  fetchData: () => Promise<T[]>;
  beforeMessage?: string;
  successMessage?: string;
  /**
   * 是否自动插入“企业名称(companyName)”列（默认：true）
   * 用于 credit 模块子表导出统一补齐企业名称
   */
  includeCompanyName?: boolean;
}

export async function exportCreditData<T>({
  filename,
  columns,
  fetchData,
  beforeMessage,
  successMessage,
  includeCompanyName = true
}: ExportOptions<T>) {
  const hide = message.loading(beforeMessage || '正在导出数据...', 0);
  try {
    const list = await fetchData();
    const normalizedColumns = [...columns];
    if (
      includeCompanyName &&
      !normalizedColumns.some((c) => c.dataIndex === 'companyName')
    ) {
      const companyNameCol: ExportColumn<T> = {
        title: '企业名称',
        dataIndex: 'companyName'
      };
      if (
        normalizedColumns.length > 0 &&
        normalizedColumns[0].dataIndex === 'id'
      ) {
        normalizedColumns.splice(1, 0, companyNameCol);
      } else {
        normalizedColumns.unshift(companyNameCol);
      }
    }

    const headerRow = normalizedColumns.map((col) => col.title);
    const dataRows = (list || []).map((item) =>
      normalizedColumns.map((col) => {
        if (col.formatter) {
          return col.formatter(item) ?? '';
        }
        const key = col.dataIndex as string;
        return (item as any)?.[key] ?? '';
      })
    );

    const sheetName = filename.replace(/\s+/g, '_');
    const sheet = utils.aoa_to_sheet([headerRow, ...dataRows]);
    sheet['!cols'] = normalizedColumns.map(() => ({ wch: 20 }));

    const workbook = {
      SheetNames: [sheetName],
      Sheets: {
        [sheetName]: sheet
      }
    };

    writeFile(workbook, `${sheetName}.xlsx`);
    hide();
    message.success(successMessage || `成功导出 ${list?.length ?? 0} 条记录`);
  } catch (e: any) {
    hide();
    message.error(e?.message || '导出失败，请重试');
  }
}
