import * as XLSX from 'xlsx';

const MAX_ROWS = 5000;

export type ParsedDrugNumberRow = {
  drug_name: string;
  drug_number: string;
};

function normalizeCell(value: unknown): string {
  if (value === null || value === undefined) {
    return '';
  }
  if (typeof value === 'number') {
    return Number.isInteger(value) ? String(value) : String(value).trim();
  }
  return String(value).trim();
}

/** 表头含空白或全角空格时仍能匹配 */
function pickByHeaderAliases(
  row: Record<string, unknown>,
  aliases: string[],
): string {
  for (const key of Object.keys(row)) {
    const k = key.replace(/\s+/g, '').replace(/\u3000/g, '');
    for (const alias of aliases) {
      if (k === alias.replace(/\s+/g, '').replace(/\u3000/g, '')) {
        return normalizeCell(row[key]);
      }
    }
  }
  return '';
}

function parseRowsByObjectKeys(
  rows: Record<string, unknown>[],
): { items: ParsedDrugNumberRow[]; invalidCount: number } {
  const items: ParsedDrugNumberRow[] = [];
  let invalidCount = 0;
  const n = Math.min(rows.length, MAX_ROWS);

  const numberAliases = [
    '药品编号',
    '药品编码',
    '编号',
    'drug_number',
    '编码',
  ];
  const nameAliases = ['药品名称', '药名', 'drug_name', '名称'];

  for (let i = 0; i < n; i++) {
    const row = rows[i];
    if (!row || typeof row !== 'object') {
      invalidCount++;
      continue;
    }

    let drugNumber =
      pickByHeaderAliases(row, numberAliases) ||
      normalizeCell(row['药品编号']) ||
      normalizeCell(row['药品编码']) ||
      normalizeCell(row['编号']) ||
      normalizeCell(row['drug_number']);

    let drugName =
      pickByHeaderAliases(row, nameAliases) ||
      normalizeCell(row['药品名称']) ||
      normalizeCell(row['药名']) ||
      normalizeCell(row['drug_name']);

    if (!drugName || !drugNumber) {
      const empty = !Object.values(row).some(
        (v) => normalizeCell(v) !== '',
      );
      if (empty) {
        continue;
      }
      invalidCount++;
      continue;
    }

    items.push({
      drug_name: drugName,
      drug_number: drugNumber,
    });
  }

  return { items, invalidCount };
}

/**
 * 标准「药品编码」表：第 1 列为编号、第 2 列为名称（表头行自动跳过）
 */
function parseRowsByPosition(sheet: XLSX.WorkSheet): {
  items: ParsedDrugNumberRow[];
  invalidCount: number;
  rowCount: number;
} {
  const aoa = XLSX.utils.sheet_to_json(sheet, {
    header: 1,
    defval: '',
  }) as unknown[][];

  const items: ParsedDrugNumberRow[] = [];
  let invalidCount = 0;
  if (aoa.length === 0) {
    return { items: [], invalidCount: 0, rowCount: 0 };
  }

  let start = 0;
  const h0 = normalizeCell(aoa[0]?.[0]);
  const h1 = normalizeCell(aoa[0]?.[1]);
  if (
    h0 &&
    (h0.includes('编号') ||
      h0.includes('编码') ||
      h0.includes('代码') ||
      /药品/.test(h0))
  ) {
    start = 1;
  }
  if (
    h1 &&
    (h1.includes('名称') || h1.includes('药名') || h1.includes('品名'))
  ) {
    start = 1;
  }

  const limit = Math.min(aoa.length, start + MAX_ROWS);
  for (let i = start; i < limit; i++) {
    const row = aoa[i];
    if (!row?.length) {
      continue;
    }
    const drugNumber = normalizeCell(row[0]);
    const drugName = normalizeCell(row[1]);
    if (!drugName || !drugNumber) {
      const anyCell = row.some((c) => normalizeCell(c) !== '');
      if (anyCell) {
        invalidCount++;
      }
      continue;
    }
    items.push({ drug_name: drugName, drug_number: drugNumber });
  }

  return { items, invalidCount, rowCount: aoa.length };
}

/**
 * 从第一张工作表解析「药品编号」「药品名称」列（兼容表头别名 + 列位置回退）
 */
export function parseDrugNumberExcelBuffer(buffer: ArrayBuffer): {
  items: ParsedDrugNumberRow[];
  invalidCount: number;
  rowCount: number;
} {
  const workbook = XLSX.read(buffer, { type: 'array' });
  const sheetName = workbook.SheetNames[0];
  if (!sheetName) {
    return { items: [], invalidCount: 0, rowCount: 0 };
  }
  const sheet = workbook.Sheets[sheetName];
  if (!sheet) {
    return { items: [], invalidCount: 0, rowCount: 0 };
  }

  const rows = XLSX.utils.sheet_to_json<Record<string, unknown>>(sheet, {
    defval: '',
  });

  let { items, invalidCount } = parseRowsByObjectKeys(rows);
  let rowCount = rows.length;

  if (items.length === 0) {
    const pos = parseRowsByPosition(sheet);
    items = pos.items;
    invalidCount = pos.invalidCount;
    rowCount = pos.rowCount;
  }

  return {
    items,
    invalidCount,
    rowCount,
  };
}

/**
 * 与后端 `normalizeDrugNumberForBatch` 对齐，用于对比是否变更
 */
export function normalizeDrugNumberForCompare(value: unknown): string {
  if (value === null || value === undefined || value === '') {
    return '';
  }
  if (typeof value === 'boolean') {
    return '';
  }
  if (typeof value === 'number') {
    if (Number.isInteger(value) || Math.floor(value) === value) {
      return String(Math.trunc(value));
    }
    return String(value).trim();
  }
  return String(value).trim();
}

export function isDrugNumberChanged(
  oldVal: unknown,
  newVal: unknown,
): boolean {
  return normalizeDrugNumberForCompare(oldVal) !== normalizeDrugNumberForCompare(newVal);
}
