/**
 * 总仓改价 Excel 解析
 * - 解析药品ID，便于精确匹配
 * - 价格优先读单元格「原始字符串 / 显示文本」，避免 IEEE 浮点
 */
import ExcelJS from 'exceljs';

import { roundPrice4 } from './priceCompare';

const MAX_ROWS = 5000;

export type ParsedWarehousePriceRow = {
  drug_id: number;
  drug_name: string;
  drug_number: string;
  market_price: number;
  price: number;
  unit_name: string;
};

export type ParseWarehousePriceResult = {
  items: ParsedWarehousePriceRow[];
  invalidCount: number;
  rowCount: number;
  hasUnitColumn: boolean;
};

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

function cellRawString(cell: ExcelJS.Cell): string {
  const v = cell.value;
  if (v === null || v === undefined) {
    return '';
  }
  // 导出时我们写的是字符串，打开后若仍是字符串则最可信
  if (typeof v === 'string') {
    return v.trim().replace(/,/g, '').replace(/￥/g, '');
  }
  if (typeof v === 'number') {
    // 不用直接 Number 展示；用足量有效位再交给 roundPrice4
    return String(v);
  }
  if (typeof v === 'object') {
    if ('result' in v && v.result !== null && v.result !== undefined) {
      return String((v as { result: unknown }).result).trim();
    }
    if ('text' in v && (v as { text?: string }).text != null) {
      return String((v as { text?: string }).text).trim();
    }
    if ('richText' in v && Array.isArray((v as { richText: { text: string }[] }).richText)) {
      return (v as { richText: { text: string }[] }).richText
        .map((p) => p.text)
        .join('')
        .trim();
    }
  }
  const display = String(cell.text ?? '').trim().replace(/,/g, '');
  return display;
}

function normalizeCell(value: ExcelJS.CellValue): string {
  if (value === null || value === undefined) {
    return '';
  }
  if (typeof value === 'object' && value && 'text' in value) {
    return String((value as { text?: string }).text ?? '').trim();
  }
  if (typeof value === 'number') {
    return Number.isInteger(value) ? String(value) : String(value).trim();
  }
  return String(value).trim();
}

const DRUG_ID_ALIASES = ['药品ID', '药品Id', 'drug_id', 'DrugId'];
const NUMBER_ALIASES = ['商品编码', '药品编码', 'ErpCode', 'drug_number'];
const NAME_ALIASES = ['通用名', '药品名称', '药名', 'drug_name'];
const MARKET_ALIASES = ['每克供货价', '供货价', 'market_price'];
const PRICE_ALIASES = ['每克零售价', '建议售价', '零售价', '当前零售价', 'price'];
const UNIT_ALIASES = ['单位', '计量单位', 'unit', 'unit_name'];

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 getCellNumber(row: ExcelJS.Row, col?: number): number {
  if (!col) {
    return 0;
  }
  const raw = cellRawString(row.getCell(col));
  if (raw === '' || !Number.isFinite(Number(raw))) {
    return 0;
  }
  return roundPrice4(raw);
}

function getCellText(row: ExcelJS.Row, col?: number): string {
  if (!col) {
    return '';
  }
  const cell = row.getCell(col);
  const fromValue = normalizeCell(cell.value);
  if (fromValue) {
    return fromValue;
  }
  return String(cell.text ?? '').trim();
}

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

export async function parseWarehousePriceExcelBuffer(
  buffer: ArrayBuffer,
): Promise<ParseWarehousePriceResult> {
  const workbook = new ExcelJS.Workbook();
  await workbook.xlsx.load(buffer);

  const sheet = workbook.worksheets[0];
  if (!sheet) {
    return { items: [], invalidCount: 0, rowCount: 0, hasUnitColumn: false };
  }

  const headerRow = sheet.getRow(1);
  const headerMap = buildHeaderIndexMap(headerRow);

  const drugIdCol = pickColumn(headerMap, DRUG_ID_ALIASES);
  const numberCol = pickColumn(headerMap, NUMBER_ALIASES);
  const nameCol = pickColumn(headerMap, NAME_ALIASES);
  const marketCol = pickColumn(headerMap, MARKET_ALIASES);
  const priceCol = pickColumn(headerMap, PRICE_ALIASES);
  const unitCol = pickColumn(headerMap, UNIT_ALIASES);
  const hasUnitColumn = !!unitCol;

  const items: ParsedWarehousePriceRow[] = [];
  let invalidCount = 0;
  const rowCount = Math.min(sheet.rowCount, MAX_ROWS + 1);

  for (let rowIndex = 2; rowIndex <= rowCount; rowIndex++) {
    const row = sheet.getRow(rowIndex);
    if (rowIsEmpty(row)) {
      continue;
    }

    const drugIdRaw = getCellText(row, drugIdCol);
    const drugId = Number.parseInt(drugIdRaw, 10) || 0;
    const drugNumber = getCellText(row, numberCol);
    const drugName = getCellText(row, nameCol);
    const marketPrice = getCellNumber(row, marketCol);
    const price = getCellNumber(row, priceCol);
    const unitName = getCellText(row, unitCol);

    if (
      drugId <= 0 &&
      !drugName &&
      !drugNumber &&
      marketPrice === 0 &&
      price === 0 &&
      !unitName
    ) {
      continue;
    }

    if (drugId <= 0 && !drugName && !drugNumber) {
      invalidCount++;
      continue;
    }

    items.push({
      drug_id: drugId,
      drug_name: drugName,
      drug_number: drugNumber,
      market_price: marketPrice,
      price,
      unit_name: unitName,
    });
  }

  return {
    items,
    invalidCount,
    rowCount: Math.max(0, rowCount - 1),
    hasUnitColumn,
  };
}
