import type { MileageExportInput, MileageWorkbookRow } from './mileageExport';

function excelColumn(index: number) {
  let value = index;
  let result = '';
  while (value > 0) {
    value -= 1;
    result = String.fromCharCode(65 + value % 26) + result;
    value = Math.floor(value / 26);
  }
  return result;
}

function localDateTime(value: Date) {
  return new Intl.DateTimeFormat('zh-CN', {
    year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false
  }).format(value).split('/').join('-');
}

export async function createMileageWorkbook(input: MileageExportInput) {
  const { Workbook } = await import('exceljs');
  const workbook = new Workbook();
  workbook.creator = '灵牛车辆数据中台';
  workbook.company = '灵牛科技';
  workbook.created = input.exportedAt ?? new Date();
  workbook.modified = input.exportedAt ?? new Date();
  workbook.calcProperties.fullCalcOnLoad = true;

  const sheet = workbook.addWorksheet('里程查询', {
    views: [{ state: 'frozen', xSplit: 2, ySplit: 6, activeCell: 'C7', showGridLines: false }],
    pageSetup: { orientation: 'landscape', fitToPage: true, fitToWidth: 1, fitToHeight: 0, paperSize: 9, margins: { left: .25, right: .25, top: .45, bottom: .45, header: .2, footer: .2 } },
    properties: { defaultRowHeight: 21 }
  });
  const firstDateColumn = 3;
  const lastDateColumn = firstDateColumn + input.dates.length - 1;
  const totalColumn = lastDateColumn + 1;
  const lastColumnLetter = excelColumn(totalColumn);
  const headerRowNumber = 6;
  const firstDataRow = headerRowNumber + 1;
  const lastDataRow = firstDataRow + input.vehicles.length - 1;
  const exportedAt = input.exportedAt ?? new Date();
  const sourceDescription = input.sources.map((source, index) => `${index + 1}. ${source.label}（${source.mileageType}）`).join('  ＞  ');

  const title = sheet.getCell('A1');
  title.value = '车辆里程查询明细';
  title.font = { name: 'Microsoft YaHei', size: 18, bold: true, color: { argb: 'FF17345C' } };
  title.alignment = { vertical: 'middle', horizontal: 'left' };
  title.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFE8F1FC' } };
  for (let column = 1; column <= totalColumn; column += 1) {
    const cell = sheet.getCell(1, column);
    cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFE8F1FC' } };
    cell.border = { bottom: { style: 'medium', color: { argb: 'FFBDD0E8' } } };
  }
  sheet.getRow(1).height = 38;

  sheet.getRow(2).values = ['日期范围', `${input.dateFrom} 至 ${input.dateTo}`, '车辆范围', `${input.vehicles.length} 辆`];
  sheet.getRow(3).values = ['来源优先级', sourceDescription];
  const periodTotal = input.mileageRows.reduce((sum, row) => sum + (Number.isFinite(row.dailyMileageKm) ? row.dailyMileageKm : 0), 0);
  sheet.getRow(4).values = ['区间总里程', null, '有效车辆日', `${input.mileageRows.length} 条`];
  sheet.getCell('B4').value = input.vehicles.length ? { formula: `SUM(${lastColumnLetter}${firstDataRow}:${lastColumnLetter}${lastDataRow})`, result: periodTotal } : 0;
  sheet.getCell('B4').numFmt = '#,##0.0" km"';
  for (let rowNumber = 2; rowNumber <= 4; rowNumber += 1) {
    const row = sheet.getRow(rowNumber);
    row.height = 25;
    row.eachCell({ includeEmpty: true }, (cell, columnNumber) => {
      cell.font = { name: 'Microsoft YaHei', size: 10, bold: columnNumber === 1 || columnNumber === 3, color: { argb: columnNumber === 1 || columnNumber === 3 ? 'FF53657D' : 'FF213149' } };
      cell.alignment = { vertical: 'middle', horizontal: columnNumber === 1 || columnNumber === 3 ? 'left' : 'right' };
      cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: rowNumber % 2 ? 'FFF8FAFD' : 'FFF2F6FB' } };
      cell.border = { bottom: { style: 'thin', color: { argb: 'FFE1E8F1' } } };
    });
  }
  sheet.getRow(5).height = 8;

  const header = sheet.getRow(headerRowNumber);
  header.values = ['车牌', 'VIN', ...input.dates.map((date) => new Date(`${date}T12:00:00Z`)), '区间总里程'];
  header.height = 30;
  header.eachCell((cell, columnNumber) => {
    const isDateHeader = columnNumber >= firstDateColumn && columnNumber <= lastDateColumn;
    cell.font = { name: 'Microsoft YaHei', size: 10, bold: true, color: { argb: columnNumber === totalColumn ? 'FF1C4F91' : 'FF304158' } };
    cell.alignment = {
      vertical: 'middle',
      horizontal: columnNumber <= 2 ? 'left' : isDateHeader ? 'center' : 'right'
    };
    cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: columnNumber === totalColumn ? 'FFDCEBFF' : 'FFEAF0F7' } };
    cell.border = { bottom: { style: 'medium', color: { argb: 'FFC3D0DF' } } };
    if (isDateHeader) cell.numFmt = 'm/d';
  });

  const rowsByVin = new Map<string, Map<string, MileageWorkbookRow>>();
  for (const row of input.mileageRows) {
    if (!rowsByVin.has(row.vin)) rowsByVin.set(row.vin, new Map());
    rowsByVin.get(row.vin)!.set(row.date, row);
  }
  input.vehicles.forEach((vehicle, index) => {
    const rowNumber = firstDataRow + index;
    const mileageByDate = rowsByVin.get(vehicle.vin) ?? new Map<string, MileageWorkbookRow>();
    const dailyValues = input.dates.map((date) => mileageByDate.get(date)?.dailyMileageKm ?? null);
    const total = dailyValues.reduce<number>((sum, value) => sum + (value ?? 0), 0);
    const row = sheet.getRow(rowNumber);
    row.values = [vehicle.plate || '未绑定', vehicle.vin, ...dailyValues, null];
    row.height = 25;
    row.eachCell({ includeEmpty: true }, (cell, columnNumber) => {
      cell.font = { name: columnNumber === 2 ? 'Consolas' : 'Microsoft YaHei', size: columnNumber === 2 ? 9 : 10, color: { argb: columnNumber === totalColumn ? 'FF1D4E89' : 'FF34445A' }, bold: columnNumber === 1 || columnNumber === totalColumn };
      cell.alignment = { vertical: 'middle', horizontal: columnNumber <= 2 ? 'left' : 'right' };
      cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: index % 2 ? 'FFF9FBFD' : 'FFFFFFFF' } };
      cell.border = { bottom: { style: 'thin', color: { argb: 'FFE6ECF3' } } };
      if (columnNumber >= firstDateColumn) cell.numFmt = '#,##0.0" km"';
    });
    const dateStart = excelColumn(firstDateColumn);
    const dateEnd = excelColumn(lastDateColumn);
    const totalCell = sheet.getCell(rowNumber, totalColumn);
    totalCell.value = { formula: `SUM(${dateStart}${rowNumber}:${dateEnd}${rowNumber})`, result: total };
    totalCell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: index % 2 ? 'FFEDF5FF' : 'FFF4F8FE' } };
    row.commit();
  });

  sheet.getColumn(1).width = 15;
  sheet.getColumn(2).width = 24;
  for (let column = firstDateColumn; column <= lastDateColumn; column += 1) sheet.getColumn(column).width = 12;
  sheet.getColumn(totalColumn).width = 17;
  if (input.vehicles.length) {
    sheet.autoFilter = { from: { row: headerRowNumber, column: 1 }, to: { row: lastDataRow, column: totalColumn } };
    sheet.addConditionalFormatting({
      ref: `${excelColumn(firstDateColumn)}${firstDataRow}:${excelColumn(lastDateColumn)}${lastDataRow}`,
      rules: [{
        type: 'colorScale', priority: 1,
        cfvo: [{ type: 'min' }, { type: 'percentile', value: 50 }, { type: 'max' }],
        color: [{ argb: 'FFFFFFFF' }, { argb: 'FFE8F2FF' }, { argb: 'FFB9D8FF' }]
      }]
    });
  }
  sheet.headerFooter.oddFooter = '&L灵牛车辆数据中台&C第 &P / &N 页&R导出于 ' + localDateTime(exportedAt);
  return workbook;
}
