"use client";

import React from "react";
import type { ComponentRendererProps } from "@/types/component";
import { filterDOMProps } from "@/lib/utils/domPropsFilter";
import { useTableRows } from "../_shared/use-table-rows";
import type {
  GroupedTableColumn,
  GroupedTableConfig,
  GroupedTableDataSource,
} from "./types";

/**
 * GroupedTable — canonical 그룹 테이블 컴포넌트 (Phase G.3.1)
 *
 * 백엔드 `/select-rows` 응답을 클라이언트 측에서 `groupBy` 키로 묶고, 그룹 헤더 +
 * 안쪽 row 들로 두 단계 표 렌더. 운영 모드 / dataSource 완성 / fetch 성공 시
 * 실제 row 사용. 디자인 모드 / 미완성: 정적 preview.
 */

const cellToText = (v: unknown): string => {
  if (v === null || v === undefined || v === "") return "—";
  if (typeof v === "number") return v.toLocaleString();
  if (typeof v === "boolean") return v ? "✓" : "✗";
  if (v instanceof Date) return v.toLocaleString();
  return String(v);
};

export interface GroupedTableComponentProps extends ComponentRendererProps {
  config?: GroupedTableConfig;
}

export const GroupedTableComponent: React.FC<GroupedTableComponentProps> = ({
  component,
  isDesignMode = false,
  isSelected = false,
  onClick,
  onDragStart,
  onDragEnd,
  config,
  className,
  style,
  ...props
}) => {
  const p = props as any;
  const fromProps: Partial<GroupedTableConfig> = {};
  if (typeof p.title === "string") fromProps.title = p.title;
  if (p.dataSource && typeof p.dataSource === "object") fromProps.dataSource = p.dataSource;
  if (typeof p.groupBy === "string") fromProps.groupBy = p.groupBy;
  if (Array.isArray(p.columns)) fromProps.columns = p.columns;
  if (typeof p.sortGroups === "string") fromProps.sortGroups = p.sortGroups;
  if (typeof p.emptyText === "string") fromProps.emptyText = p.emptyText;

  const componentConfig = {
    ...config,
    ...((component as any).config ?? {}),
    ...((component as any).componentConfig ?? {}),
    ...fromProps,
  } as GroupedTableConfig;

  const title = componentConfig.title;
  const groupBy = componentConfig.groupBy;
  const columns: GroupedTableColumn[] = componentConfig.columns ?? [];
  const sortGroups = componentConfig.sortGroups ?? "none";
  const emptyText = componentConfig.emptyText ?? "데이터 없음";
  const previewGroupBy = groupBy ?? "group";
  const previewFirstColumn = columns[0]?.column ?? "name";
  const previewSecondColumn = columns[1]?.column ?? "value";

  const userContext = React.useMemo(
    () => ({
      companyCode: (p.companyCode as string) || undefined,
      userId: (p.userId as string) || undefined,
      deptCode: (p.deptCode as string) || undefined,
      userName: (p.userName as string) || undefined,
    }),
    [p.companyCode, p.userId, p.deptCode, p.userName],
  );

  const previewBuilder = React.useCallback(
    (i: number) => ({
      __preview: true,
      [previewGroupBy]: `그룹 ${Math.floor(i / 2) + 1}`,
      [previewFirstColumn]: `샘플 ${i + 1}`,
      [previewSecondColumn]: (i + 1) * 5,
    }),
    [previewFirstColumn, previewGroupBy, previewSecondColumn],
  );

  const { rows, loading, error, isPreview } = useTableRows(componentConfig.dataSource, {
    isDesignMode,
    formData: (p.formData as Record<string, unknown>) || undefined,
    userContext,
    refreshKey: (p.refreshKey as number | string | undefined) || undefined,
    previewCount: 6,
    previewBuilder,
  });

  // 클라이언트 측 group-by
  const grouped = React.useMemo(() => {
    if (!groupBy) {
      return [{ key: "__all", values: rows }];
    }
    const map = new Map<string, Record<string, any>[]>();
    const order: string[] = [];
    for (const row of rows) {
      const raw = row[groupBy];
      const key = raw === null || raw === undefined || raw === "" ? "—" : String(raw);
      if (!map.has(key)) {
        map.set(key, []);
        order.push(key);
      }
      map.get(key)!.push(row);
    }
    let keys = order;
    if (sortGroups === "asc") keys = [...order].sort((a, b) => a.localeCompare(b, "ko"));
    else if (sortGroups === "desc") keys = [...order].sort((a, b) => b.localeCompare(a, "ko"));
    return keys.map((k) => ({ key: k, values: map.get(k)! }));
  }, [rows, groupBy, sortGroups]);

  // 표시할 컬럼들 — 비어있으면 row 첫 항목의 모든 키 사용 (groupBy 자체는 제외)
  const effectiveColumns: GroupedTableColumn[] = React.useMemo(() => {
    if (columns.length > 0) return columns;
    const sample = rows[0] ?? {};
    return Object.keys(sample)
      .filter((k) => k !== groupBy && !k.startsWith("__"))
      .map((k) => ({ column: k }));
  }, [columns, rows, groupBy]);

  const containerStyle: React.CSSProperties = {
    width: "100%",
    height: "100%",
    display: "flex",
    flexDirection: "column",
    boxSizing: "border-box",
    background: "hsl(var(--card))",
    border: "1px solid hsl(var(--border))",
    borderRadius: 8,
    padding: 12,
    minHeight: 180,
    ...((component as any).style ?? {}),
    ...style,
  };
  if (isDesignMode && isSelected) {
    containerStyle.outline = "2px solid hsl(var(--primary))";
    containerStyle.outlineOffset = "2px";
  }

  const handleClick = (e: React.MouseEvent) => {
    e.stopPropagation();
    onClick?.();
  };

  /* eslint-disable @typescript-eslint/no-unused-vars */
  const {
    selectedScreen: _1, onZoneComponentDrop: _2, onZoneClick: _3,
    componentConfig: _4, component: _5, isSelected: _6,
    onClick: _7, onDragStart: _8, onDragEnd: _9,
    size: _10, position: _11, style: _12,
    screenId: _13, tableName: _14, onRefresh: _15, onClose: _16,
    web_type: _17, autoGeneration: _18, isInteractive: _19,
    formData: _20, onFormDataChange: _21,
    menuId: _22, menuObjid: _23, onSave: _24,
    userId: _25, userName: _26, companyCode: _27, deptCode: _27b,
    isInModal: _28, readonly: _29, originalData: _30,
    selectedRows: _36, selectedRowsData: _37, onSelectedRowsChange: _38,
    sortBy: _39, sortOrder: _40, tableDisplayData: _41,
    flowSelectedData: _42, flowSelectedStepId: _43, onFlowSelectedDataChange: _44,
    onConfigChange: _45, refreshKey: _46, flowRefreshKey: _47, onFlowRefresh: _48,
    isPreview: _49, groupedData: _50,
    title: _51, dataSource: _52, groupBy: _53,
    columns: _54, sortGroups: _55, emptyText: _56,
    disabled: _57, required: _58,
    ...domProps
  } = props as any;
  /* eslint-enable @typescript-eslint/no-unused-vars */

  return (
    <div
      style={containerStyle}
      className={className}
      onClick={handleClick}
      onDragStart={onDragStart}
      onDragEnd={onDragEnd}
      {...filterDOMProps(domProps)}
    >
      {(title || isPreview || loading) && (
        <div
          style={{
            display: "flex",
            alignItems: "center",
            justifyContent: "space-between",
            fontSize: 12,
            fontWeight: 700,
            color: "hsl(var(--foreground))",
            marginBottom: 6,
            flexShrink: 0,
          }}
        >
          <span>{title || (isPreview ? "그룹 테이블 (미리보기)" : "")}</span>
          {loading && (
            <span style={{ fontSize: 10, color: "hsl(var(--muted-foreground))", fontWeight: 500 }}>
              로딩…
            </span>
          )}
        </div>
      )}
      <div style={{ flex: 1, minHeight: 0, overflow: "auto" }}>
        {error ? (
          <div
            style={{
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              minHeight: 80,
              fontSize: 12,
              color: "hsl(var(--muted-foreground))",
            }}
          >
            데이터 로드 실패: {error}
          </div>
        ) : rows.length === 0 || effectiveColumns.length === 0 ? (
          <div
            style={{
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              minHeight: 80,
              fontSize: 12,
              color: "hsl(var(--muted-foreground))",
            }}
          >
            {emptyText}
          </div>
        ) : (
          <table
            style={{
              width: "100%",
              borderCollapse: "collapse",
              fontSize: 11.5,
              fontFamily: "var(--v5-font-sans)",
            }}
          >
            <thead>
              <tr style={{ background: "hsl(var(--muted))" }}>
                {effectiveColumns.map((c, i) => (
                  <th
                    key={i}
                    style={{
                      padding: "6px 8px",
                      fontSize: 10.5,
                      fontWeight: 700,
                      textAlign: c.align ?? "left",
                      color: "hsl(var(--muted-foreground))",
                      borderBottom: "1px solid hsl(var(--border))",
                      width: c.width,
                    }}
                  >
                    {c.label ?? c.column}
                  </th>
                ))}
              </tr>
            </thead>
            <tbody>
              {grouped.map((g, gi) => (
                <React.Fragment key={gi}>
                  {groupBy && (
                    <tr style={{ background: "hsl(var(--accent))" }}>
                      <td
                        colSpan={effectiveColumns.length}
                        style={{
                          padding: "5px 8px",
                          fontSize: 11,
                          fontWeight: 700,
                          color: "var(--v5-primary, hsl(var(--primary)))",
                          borderBottom: "1px solid hsl(var(--border))",
                        }}
                      >
                        {g.key}
                        <span
                          style={{
                            marginLeft: 8,
                            fontSize: 10,
                            fontWeight: 500,
                            color: "hsl(var(--muted-foreground))",
                          }}
                        >
                          ({g.values.length}건)
                        </span>
                      </td>
                    </tr>
                  )}
                  {g.values.map((row, ri) => (
                    <tr
                      key={ri}
                      style={{
                        borderBottom: "1px solid hsl(var(--border))",
                      }}
                    >
                      {effectiveColumns.map((c, ci) => (
                        <td
                          key={ci}
                          style={{
                            padding: "5px 8px",
                            textAlign: c.align ?? "left",
                            color: "hsl(var(--foreground))",
                            whiteSpace: "nowrap",
                            overflow: "hidden",
                            textOverflow: "ellipsis",
                          }}
                        >
                          {cellToText(row[c.column])}
                        </td>
                      ))}
                    </tr>
                  ))}
                </React.Fragment>
              ))}
            </tbody>
          </table>
        )}
      </div>
    </div>
  );
};

export const GroupedTableWrapper: React.FC<GroupedTableComponentProps> = (props) => {
  return <GroupedTableComponent {...props} />;
};
