"use client";

import type { TableRendererProps } from "./types";
import type { ComponentConfig, GridCell } from "@/types/report";

type TableColumn = NonNullable<ComponentConfig["tableColumns"]>[number];

// ─── 헬퍼 함수 ────────────────────────────────────────────────────────────────

function applyNumberFormat(value: string, format?: string, suffix?: string): string {
  if (!format || format === "none") return value;
  const num = parseFloat(value.replace(/,/g, ""));
  if (isNaN(num)) return value;
  const formatted = num.toLocaleString("ko-KR");
  return format === "currency" ? `${formatted}${suffix ?? "원"}` : formatted;
}

function getCellValue(col: TableColumn, row: Record<string, unknown>): string {
  const raw = String(row[col.field] ?? "");
  return applyNumberFormat(raw, col.numberFormat, col.currencySuffix);
}

function calcSummary(col: TableColumn, rows: Record<string, unknown>[]): string {
  if (!col.summaryType || col.summaryType === "NONE") return "";

  if (col.summaryType === "COUNT") {
    return applyNumberFormat(String(rows.length), col.numberFormat, col.currencySuffix);
  }

  const values = rows
    .map((row) => {
      const raw = String(row[col.field] ?? "");
      return parseFloat(raw.replace(/,/g, ""));
    })
    .filter((v) => !isNaN(v));

  if (values.length === 0) return "";

  const sum = values.reduce((a, b) => a + b, 0);
  const result = col.summaryType === "AVG" ? sum / values.length : sum;

  return applyNumberFormat(
    parseFloat(result.toFixed(4)).toString(),
    col.numberFormat,
    col.currencySuffix,
  );
}

// ─── 그리드 셀 값 계산 ──────────────────────────────────────────────────────

function getGridCellValue(
  cell: GridCell,
  row?: Record<string, unknown>,
): string {
  if (cell.cellType === "static") return cell.value ?? "";

  if (cell.cellType === "field" && cell.field && row) {
    const raw = String(row[cell.field] ?? "");
    return applyNumberFormat(raw, cell.numberFormat, cell.currencySuffix);
  }

  return cell.value ?? "";
}

// ─── 그리드 테이블 렌더러 ────────────────────────────────────────────────────

function GridTableRenderer({ component, getQueryResult }: TableRendererProps) {
  const cells = component.gridCells ?? [];
  const rowCount = component.gridRowCount ?? 0;
  const colCount = component.gridColCount ?? 0;
  const colWidths = component.gridColWidths ?? [];
  const rowHeights = component.gridRowHeights ?? [];
  const headerRows = component.gridHeaderRows ?? 1;
  const headerCols = component.gridHeaderCols ?? 1;

  if (cells.length === 0 || rowCount === 0 || colCount === 0) {
    return (
      <div className="flex h-full w-full items-center justify-center border-2 border-dashed border-gray-300 bg-gray-50 text-xs text-gray-400">
        격자 양식을 구성하세요
      </div>
    );
  }

  const resultKey = component.visualQuery?.tableName
    ? `visual_${component.id}`
    : component.queryId;
  const queryResult = resultKey ? getQueryResult(resultKey) : null;
  const dataRow = queryResult?.rows?.[0] as Record<string, unknown> | undefined;

  const totalConfigWidth = colWidths.reduce((a, b) => a + b, 0) || 1;
  const totalConfigHeight = rowHeights.reduce((a, b) => a + b, 0) || 1;

  const hdrBg = component.headerBackgroundColor || "#f3f4f6";
  const hdrColor = component.headerTextColor || "#111827";

  const findCell = (row: number, col: number) =>
    cells.find((c) => c.row === row && c.col === col);

  const tableRows: React.ReactNode[] = [];

  for (let r = 0; r < rowCount; r++) {
    const tds: React.ReactNode[] = [];
    const rowHPct = ((rowHeights[r] ?? 32) / totalConfigHeight) * 100;

    for (let c = 0; c < colCount; c++) {
      const cell = findCell(r, c);
      if (!cell || cell.merged) continue;

      const rSpan = cell.rowSpan ?? 1;
      const cSpan = cell.colSpan ?? 1;
      const borderW =
        cell.borderStyle === "medium" ? 2 : cell.borderStyle === "thick" ? 3 : cell.borderStyle === "none" ? 0 : 1;

      const isHeader = r < headerRows || c < headerCols;
      const cellBg = cell.backgroundColor || (isHeader ? hdrBg : "white");
      const cellColor = cell.textColor || (isHeader ? hdrColor : "#111827");

      const displayValue = getGridCellValue(cell, dataRow);

      tds.push(
        <td
          key={cell.id}
          rowSpan={rSpan > 1 ? rSpan : undefined}
          colSpan={cSpan > 1 ? cSpan : undefined}
          style={{
            backgroundColor: cellBg,
            border: `${borderW}px solid #d1d5db`,
            padding: "2px 4px",
            fontSize: cell.fontSize ?? 12,
            fontWeight: cell.fontWeight === "bold" ? 700 : (isHeader ? 600 : 400),
            color: cellColor,
            textAlign: cell.align || "center",
            verticalAlign: cell.verticalAlign || "middle",
            overflow: "hidden",
            whiteSpace: "pre-line",
            wordBreak: "break-word",
          }}
        >
          {displayValue}
        </td>,
      );
    }

    tableRows.push(
      <tr key={`grid-row-${r}`} style={{ height: `${rowHPct.toFixed(2)}%` }}>
        {tds}
      </tr>,
    );
  }

  return (
    <div className="h-full w-full overflow-hidden">
      <table
        className="border-collapse"
        style={{ width: "100%", height: "100%", tableLayout: "fixed" }}
      >
        <colgroup>
          {colWidths.map((w, i) => {
            const pct = (w / totalConfigWidth) * 100;
            return <col key={i} style={{ width: `${pct.toFixed(2)}%` }} />;
          })}
        </colgroup>
        <tbody>{tableRows}</tbody>
      </table>
    </div>
  );
}

// ─── 기존 테이블 렌더러 ─────────────────────────────────────────────────────

function ClassicTableRenderer({ component, getQueryResult }: TableRendererProps) {
  const resultKey = component.visualQuery?.tableName
    ? `visual_${component.id}`
    : component.queryId;

  const queryResult = resultKey ? getQueryResult(resultKey) : null;
  const hasData = queryResult && queryResult.rows.length > 0;
  const hasColumns = component.tableColumns && component.tableColumns.length > 0;

  if (!hasData && !hasColumns) {
    return (
      <div className="flex h-full w-full items-center justify-center border-2 border-dashed border-gray-300 bg-gray-50 text-xs text-gray-400">
        테이블을 구성하세요
      </div>
    );
  }

  const allColumns = hasColumns
    ? component.tableColumns!
    : queryResult!.fields.map((field) => ({
        field,
        header: field,
        width: undefined as number | undefined,
        align: "left" as const,
        visible: true,
      }));

  const visibleColumns = allColumns.filter((col) => col.visible !== false);
  const dataRows = hasData ? queryResult!.rows : [];
  const previewRowCount = component.tableRowCount ?? 3;

  const hasSummaryRow =
    component.showFooter &&
    visibleColumns.some((col) => col.summaryType && col.summaryType !== "NONE");

  const borderClass = component.showBorder !== false ? "border border-gray-300" : "";
  const rowH = component.rowHeight ?? 28;

  // 열 너비: 설정된 비율을 유지하면서 컴포넌트 전체 너비에 맞게 스케일
  const totalConfigWidth = visibleColumns.reduce((s, c) => s + (c.width || 120), 0);

  return (
    <div className="h-full w-full overflow-hidden">
      <table className="w-full border-collapse text-xs" style={{ tableLayout: "fixed" }}>
        <colgroup>
          {visibleColumns.map((col, idx) => {
            const ratio = (col.width || 120) / totalConfigWidth;
            return <col key={idx} style={{ width: `${(ratio * 100).toFixed(2)}%` }} />;
          })}
        </colgroup>
        <thead>
          <tr
            style={{
              backgroundColor: component.headerBackgroundColor || "#f3f4f6",
              color: component.headerTextColor || "#111827",
            }}
          >
            {visibleColumns.map((col, idx) => (
              <th
                key={`h_${col.field || col.header}_${idx}`}
                className={borderClass}
                style={{
                  padding: "4px 6px",
                  textAlign: col.align || "left",
                  fontWeight: "600",
                  overflow: "hidden",
                  textOverflow: "ellipsis",
                  whiteSpace: "nowrap",
                }}
              >
                {col.header}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {dataRows.length > 0
            ? dataRows.map((row, rowIdx) => (
                <tr key={rowIdx}>
                  {visibleColumns.map((col, colIdx) => (
                    <td
                      key={`r${rowIdx}_c${col.field || col.header}_${colIdx}`}
                      className={borderClass}
                      style={{
                        padding: "4px 6px",
                        textAlign: col.align || "left",
                        height: `${rowH}px`,
                        overflow: "hidden",
                        textOverflow: "ellipsis",
                        whiteSpace: "nowrap",
                      }}
                    >
                      {getCellValue(col, row)}
                    </td>
                  ))}
                </tr>
              ))
            : Array.from({ length: previewRowCount }).map((_, rowIdx) => (
                <tr key={`empty-${rowIdx}`}>
                  {visibleColumns.map((col, colIdx) => (
                    <td
                      key={`e${rowIdx}_${colIdx}`}
                      className={borderClass}
                      style={{
                        padding: "4px 6px",
                        textAlign: col.align || "left",
                        height: `${rowH}px`,
                        color: "#d1d5db",
                      }}
                    >
                      {col.field ? `{${col.field}}` : "—"}
                    </td>
                  ))}
                </tr>
              ))}
        </tbody>

        {hasSummaryRow && dataRows.length > 0 && (
          <tfoot>
            <tr
              style={{
                backgroundColor: "#f3f4f6",
                fontWeight: 600,
                borderTop: "2px solid #d1d5db",
              }}
            >
              {visibleColumns.map((col, idx) => (
                <td
                  key={`f_${col.field || col.header}_${idx}`}
                  className={borderClass}
                  style={{ padding: "4px 6px", textAlign: col.align || "right" }}
                >
                  {calcSummary(col, dataRows)}
                </td>
              ))}
            </tr>
          </tfoot>
        )}
      </table>
    </div>
  );
}

// ─── 메인 export ─────────────────────────────────────────────────────────────

export function TableRenderer(props: TableRendererProps) {
  if (props.component.gridMode) {
    return <GridTableRenderer {...props} />;
  }
  return <ClassicTableRenderer {...props} />;
}
