import * as XLSX from "xlsx";
import type { GridColumn } from "@/components/grid/data-grid";

// DataGrid의 GridColumn을 그대로 받아 쓸 수 있는 확장 타입.
// 페이지에서 DataGrid에 넘기는 columns 변수를 그대로 버튼에 넘기면 됨.
// excelFormatter/excelTitle 은 엑셀 출력 전용 override (옵션).
export type ExcelColumn = Omit<GridColumn, "columns"> & {
  columns?: ExcelColumn[];
  excelFormatter?: (row: Record<string, unknown>) => string | number | Date | null;
  excelTitle?: string;
};

function flattenCols(cols: ExcelColumn[]): ExcelColumn[] {
  const out: ExcelColumn[] = [];
  for (const c of cols) {
    if (c.columns && c.columns.length > 0) out.push(...flattenCols(c.columns));
    else out.push(c);
  }
  return out;
}

function cellValue(col: ExcelColumn, row: Record<string, unknown>): string | number | Date | null {
  if (col.excelFormatter) return col.excelFormatter(row);
  if (!col.field) return "";
  const v = row[col.field];
  if (v === null || v === undefined || v === "") return "";
  if (col.formatter === "money") {
    const n = Number(String(v).replace(/,/g, ""));
    return isNaN(n) ? String(v) : n;
  }
  if (typeof v === "number") return v;
  if (v instanceof Date) return v;
  return String(v);
}

export interface ExcelExportOptions {
  data: Record<string, unknown>[];
  columns: ExcelColumn[];
  filename: string;
  sheetName?: string;
}

// 공통 Excel 다운로드. 체크박스/선택 컬럼은 자동 제외.
export function exportToExcel({ data, columns, filename, sheetName = "Sheet1" }: ExcelExportOptions): void {
  const flat = flattenCols(columns).filter((c) => {
    if (c.visible === false) return false;
    if (!c.field && !c.excelFormatter) return false;
    if (c.formatter === "checkbox" || c.formatter === "rowSelection") return false;
    return true;
  });
  const header = flat.map((c) => c.excelTitle ?? c.title);
  const body = data.map((row) => flat.map((c) => cellValue(c, row)));
  const ws = XLSX.utils.aoa_to_sheet([header, ...body]);
  const wb = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(wb, ws, sheetName);
  const finalName = filename.endsWith(".xlsx") ? filename : `${filename}.xlsx`;
  XLSX.writeFile(wb, finalName);
}

// 오늘 날짜를 파일명 접미사로. ex: fileNameWithDate("제품관리_설변대상") → "제품관리_설변대상_2026-04-23"
export function fileNameWithDate(base: string, delimiter = "_"): string {
  const d = new Date();
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, "0");
  const day = String(d.getDate()).padStart(2, "0");
  return `${base}${delimiter}${y}-${m}-${day}`;
}
