import ExcelJS from 'exceljs';

const MAX_ROWS = 2000;

export type ParsedGoldenFormulaRow = {
  name: string;
  clause_number: string;
  drugs_json: string;
  herb_overview: string;
  original_formula: string;
  indication_original: string;
  indication_translation: string;
  pinyin_initials: string;
  pinyin: string;
  status: number;
  sort: number;
};

export type ParseGoldenFormulaResult = {
  items: ParsedGoldenFormulaRow[];
  invalidCount: number;
  rowCount: number;
  firstInvalidReason?: string;
};

function normalizeCell(value: ExcelJS.CellValue): string {
  if (value === null || value === undefined) return '';
  if (typeof value === 'object') {
    if ('richText' in value && Array.isArray((value as any).richText)) {
      return (value as any).richText
        .map((p: { text?: string }) => p?.text ?? '')
        .join('')
        .trim();
    }
    if ('text' in value) return String((value as any).text ?? '').trim();
    if ('result' in value) {
      return normalizeCell((value as any).result as ExcelJS.CellValue);
    }
  }
  if (typeof value === 'number') {
    return Number.isInteger(value) ? String(value) : String(value).trim();
  }
  if (typeof value === 'boolean') return value ? '1' : '0';
  return String(value).trim();
}

function normalizeHeader(value: string): string {
  return value.replace(/\s+/g, '').replace(/\u3000/g, '');
}

const NAME_ALIASES = ['药方名字', '药方名称', '方名', 'name'];
const CLAUSE_ALIASES = ['条文编号', '条文', '条款', 'clause_number'];
const DRUGS_ALIASES = ['药品JSON', '药品json', '药品', 'drugs_json', 'drugs'];
const HERB_ALIASES = ['药材速览', '速览', 'herb_overview'];
const ORIGINAL_ALIASES = ['原方', '原方全文', 'original_formula', '方文'];
const IND_ORI_ALIASES = [
  '药方主治(文言文)',
  '药方主治（文言文）',
  '药方主治原文',
  '主治文言文',
  '文言文',
  'indication_original',
];
const IND_TR_ALIASES = [
  '现代主治(白话文)',
  '现代主治（白话文）',
  '现代主治',
  '白话文',
  '药方主治(译文)',
  '药方主治（译文）',
  '药方主治译文',
  '主治译文',
  'indication_translation',
];
const PY_ABBR_ALIASES = ['拼音首拼', '药方拼音首拼', '首拼', 'pinyin_initials'];
const PY_FULL_ALIASES = ['拼音全拼', '药方拼音全拼', '全拼', 'pinyin'];
const STATUS_ALIASES = ['状态', 'status'];
const SORT_ALIASES = ['排序', 'sort'];

function buildHeaderIndexMap(headerRow: ExcelJS.Row): Record<string, number> {
  const map: Record<string, number> = {};
  headerRow.eachCell({ includeEmpty: true }, (cell, colNumber) => {
    const key = normalizeHeader(normalizeCell(cell.value));
    if (key) map[key] = colNumber;
  });
  return map;
}

function pickColumn(
  headerMap: Record<string, number>,
  aliases: string[],
): number | undefined {
  for (const alias of aliases) {
    const col = headerMap[normalizeHeader(alias)];
    if (col) return col;
  }
  return undefined;
}

function getCellText(row: ExcelJS.Row, col?: number): string {
  if (!col) return '';
  return normalizeCell(row.getCell(col).value);
}

function getCellInt(row: ExcelJS.Row, col?: number, fallback = 0): number {
  if (!col) return fallback;
  const raw = normalizeCell(row.getCell(col).value);
  if (raw === '') return fallback;
  const n = Number(raw);
  return Number.isFinite(n) ? Math.trunc(n) : fallback;
}

function rowIsEmpty(row: ExcelJS.Row): boolean {
  let hasValue = false;
  row.eachCell({ includeEmpty: false }, (cell) => {
    if (normalizeCell(cell.value) !== '') hasValue = true;
  });
  return !hasValue;
}

function pickImportSheet(workbook: ExcelJS.Workbook): ExcelJS.Worksheet | undefined {
  const byName = workbook.worksheets.find((s) => s.name === '金方导入');
  return byName || workbook.worksheets[0];
}

/**
 * 解析金方导入 Excel（首行为表头）
 * 药品JSON 列原样保留字符串，由后端再校验
 */
export async function parseGoldenFormulaExcelBuffer(
  buffer: ArrayBuffer,
): Promise<ParseGoldenFormulaResult> {
  const workbook = new ExcelJS.Workbook();
  await workbook.xlsx.load(buffer);
  const sheet = pickImportSheet(workbook);
  if (!sheet) {
    return { items: [], invalidCount: 0, rowCount: 0 };
  }
  const headerRow = sheet.getRow(1);
  const headerMap = buildHeaderIndexMap(headerRow);
  const nameCol = pickColumn(headerMap, NAME_ALIASES);
  if (!nameCol) {
    throw new Error('模板表头缺少「药方名字」列，请重新下载模板');
  }
  const clauseCol = pickColumn(headerMap, CLAUSE_ALIASES);
  const drugsCol = pickColumn(headerMap, DRUGS_ALIASES);
  const herbCol = pickColumn(headerMap, HERB_ALIASES);
  const originalCol = pickColumn(headerMap, ORIGINAL_ALIASES);
  const indOriCol = pickColumn(headerMap, IND_ORI_ALIASES);
  const indTrCol = pickColumn(headerMap, IND_TR_ALIASES);
  const pyAbbrCol = pickColumn(headerMap, PY_ABBR_ALIASES);
  const pyFullCol = pickColumn(headerMap, PY_FULL_ALIASES);
  const statusCol = pickColumn(headerMap, STATUS_ALIASES);
  const sortCol = pickColumn(headerMap, SORT_ALIASES);
  const items: ParsedGoldenFormulaRow[] = [];
  let invalidCount = 0;
  let rowCount = 0;
  let firstInvalidReason: string | undefined;
  const maxRow = Math.min(sheet.rowCount || 0, MAX_ROWS + 1);
  for (let rowNumber = 2; rowNumber <= maxRow; rowNumber++) {
    const row = sheet.getRow(rowNumber);
    if (rowIsEmpty(row)) continue;
    rowCount++;
    if (items.length >= MAX_ROWS) break;
    const name = getCellText(row, nameCol);
    if (!name) {
      invalidCount++;
      if (!firstInvalidReason) firstInvalidReason = `第${rowNumber}行：药方名字为空`;
      continue;
    }
    const statusRaw = getCellInt(row, statusCol, 1);
    items.push({
      name,
      clause_number: getCellText(row, clauseCol),
      drugs_json: getCellText(row, drugsCol),
      herb_overview: getCellText(row, herbCol),
      original_formula: getCellText(row, originalCol),
      indication_original: getCellText(row, indOriCol),
      indication_translation: getCellText(row, indTrCol),
      pinyin_initials: getCellText(row, pyAbbrCol),
      pinyin: getCellText(row, pyFullCol),
      status: statusRaw === 0 ? 0 : 1,
      sort: getCellInt(row, sortCol, 0),
    });
  }
  return { items, invalidCount, rowCount, firstInvalidReason };
}
