/**
 * Excel 내보내기 유틸리티
 * 피벗 테이블 데이터를 Excel 파일로 내보내기
 * xlsx 라이브러리 사용 (브라우저 호환)
 */

import * as XLSX from "xlsx";
import {
  PivotResult,
  PivotFieldConfig,
  PivotTotalsConfig,
} from "../types";
import { pathToKey } from "./pivotEngine";

// ==================== 타입 ====================

export interface ExportOptions {
  fileName?: string;
  sheetName?: string;
  title?: string;
  subtitle?: string;
  includeHeaders?: boolean;
  includeTotals?: boolean;
}

// ==================== 메인 함수 ====================

/**
 * 피벗 데이터를 Excel로 내보내기
 */
export async function exportPivotToExcel(
  pivotResult: PivotResult,
  fields: PivotFieldConfig[],
  totals: PivotTotalsConfig,
  options: ExportOptions = {}
): Promise<void> {
  const {
    fileName = "pivot_export",
    sheetName = "Pivot",
    title,
    includeHeaders = true,
    includeTotals = true,
  } = options;

  // 필드 분류
  const rowFields = fields
    .filter((f) => f.area === "row" && f.visible !== false)
    .sort((a, b) => (a.areaIndex || 0) - (b.areaIndex || 0));

  // 데이터 배열 생성
  const data: any[][] = [];

  // 제목 추가
  if (title) {
    data.push([title]);
    data.push([]); // 빈 행
  }

  // 헤더 행
  if (includeHeaders) {
    const headerRow: any[] = [
      rowFields.map((f) => f.caption).join(" / ") || "항목",
    ];

    // 열 헤더
    for (const col of pivotResult.flatColumns) {
      headerRow.push(col.caption || "(전체)");
    }

    // 총계 헤더
    if (totals?.showRowGrandTotals && includeTotals) {
      headerRow.push("총계");
    }

    data.push(headerRow);
  }

  // 데이터 행
  for (const row of pivotResult.flatRows) {
    const excelRow: any[] = [];

    // 행 헤더 (들여쓰기 포함)
    const indent = "  ".repeat(row.level);
    excelRow.push(indent + row.caption);

    // 데이터 셀
    for (const col of pivotResult.flatColumns) {
      const cellKey = `${pathToKey(row.path)}|||${pathToKey(col.path)}`;
      const values = pivotResult.dataMatrix.get(cellKey);

      if (values && values.length > 0) {
        excelRow.push(values[0].value);
      } else {
        excelRow.push("");
      }
    }

    // 행 총계
    if (totals?.showRowGrandTotals && includeTotals) {
      const rowTotal = pivotResult.grandTotals.row.get(pathToKey(row.path));
      if (rowTotal && rowTotal.length > 0) {
        excelRow.push(rowTotal[0].value);
      } else {
        excelRow.push("");
      }
    }

    data.push(excelRow);
  }

  // 열 총계 행
  if (totals?.showColumnGrandTotals && includeTotals) {
    const totalRow: any[] = ["총계"];

    for (const col of pivotResult.flatColumns) {
      const colTotal = pivotResult.grandTotals.column.get(pathToKey(col.path));
      if (colTotal && colTotal.length > 0) {
        totalRow.push(colTotal[0].value);
      } else {
        totalRow.push("");
      }
    }

    // 대총합
    if (totals?.showRowGrandTotals) {
      const grandTotal = pivotResult.grandTotals.grand;
      if (grandTotal && grandTotal.length > 0) {
        totalRow.push(grandTotal[0].value);
      } else {
        totalRow.push("");
      }
    }

    data.push(totalRow);
  }

  // 워크시트 생성
  const worksheet = XLSX.utils.aoa_to_sheet(data);

  // 컬럼 너비 설정
  const colWidths: XLSX.ColInfo[] = [];
  const maxCols = data.reduce((max, row) => Math.max(max, row.length), 0);
  for (let i = 0; i < maxCols; i++) {
    colWidths.push({ wch: i === 0 ? 25 : 15 });
  }
  worksheet["!cols"] = colWidths;

  // 워크북 생성
  const workbook = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);

  // 파일 다운로드
  XLSX.writeFile(workbook, `${fileName}.xlsx`);
}

/**
 * Drill Down 데이터를 Excel로 내보내기
 */
export async function exportDrillDownToExcel(
  data: any[],
  columns: { field: string; caption: string }[],
  options: ExportOptions = {}
): Promise<void> {
  const {
    fileName = "drilldown_export",
    sheetName = "Data",
    title,
  } = options;

  // 데이터 배열 생성
  const sheetData: any[][] = [];

  // 제목
  if (title) {
    sheetData.push([title]);
    sheetData.push([]); // 빈 행
  }

  // 헤더
  const headerRow = columns.map((col) => col.caption);
  sheetData.push(headerRow);

  // 데이터
  for (const row of data) {
    const dataRow = columns.map((col) => row[col.field] ?? "");
    sheetData.push(dataRow);
  }

  // 워크시트 생성
  const worksheet = XLSX.utils.aoa_to_sheet(sheetData);

  // 컬럼 너비 설정
  const colWidths: XLSX.ColInfo[] = columns.map(() => ({ wch: 15 }));
  worksheet["!cols"] = colWidths;

  // 워크북 생성
  const workbook = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);

  // 파일 다운로드
  XLSX.writeFile(workbook, `${fileName}.xlsx`);
}
