"use client";

/**
 * InvGroupedTableConfigPanel — canonical grouped-table 설정 패널 (Phase G.3.1)
 *
 *   ① 기본 — 제목 + 빈 결과 문구
 *   ② 데이터 소스 — 테이블 / 정렬 / limit
 *   ③ 그룹 — groupBy 컬럼 + 그룹 정렬
 *   ④ 컬럼 — 표시할 컬럼 목록 (label / width / align)
 *   ⑤ 필터 — OptionFilter 빌더
 */

import React from "react";
import { Plus, Trash2 } from "lucide-react";
import {
  CPSection,
  CPRow,
  CPText,
  CPSelect,
  CPSegment,
  CPNumber,
  Hint,
} from "@/components/v2/config-panels/_shared/cp";
import { useDbTables } from "../common/useDbTables";
import { OptionFilterRow } from "../_shared/FilterRow";
import type { OptionFilter } from "../input/use-option-loader";
import type {
  GroupedTableConfig,
  GroupedTableColumn,
  GroupedTableDataSource,
} from "./types";

export interface InvGroupedTableConfigPanelProps {
  config?: GroupedTableConfig;
  onChange?: (config: GroupedTableConfig) => void;
  selectedComponent?: { id: string; config?: GroupedTableConfig; [k: string]: any };
}

export const InvGroupedTableConfigPanel: React.FC<InvGroupedTableConfigPanelProps> = ({
  config,
  onChange,
  selectedComponent,
}) => {
  const current: GroupedTableConfig =
    (config as GroupedTableConfig) || (selectedComponent?.config as GroupedTableConfig) || {};
  const patch = (p: Partial<GroupedTableConfig>) => onChange?.({ ...current, ...p });

  const ds = current.dataSource ?? {};
  const patchDataSource = (p: Partial<GroupedTableDataSource>) => {
    const next = { ...ds, ...p };
    if (
      !next.tableName &&
      (!next.filters || next.filters.length === 0) &&
      (!next.orderBy || next.orderBy.length === 0)
    ) {
      patch({ dataSource: undefined });
    } else {
      patch({ dataSource: next });
    }
  };

  const filters = ds.filters ?? [];
  const columns: GroupedTableColumn[] = current.columns ?? [];

  const orderByCol = ds.orderBy?.[0]?.column || "";
  const orderByDir = ds.orderBy?.[0]?.direction || "desc";

  const updateFilter = (idx: number, f: Partial<OptionFilter>) => {
    const next = filters.map((it, i) => (i === idx ? { ...it, ...f } : it));
    patchDataSource({ filters: next });
  };
  const addFilter = () =>
    patchDataSource({
      filters: [
        ...filters,
        { column: "", operator: "=", value_type: "static", value: "" } as OptionFilter,
      ],
    });
  const removeFilter = (idx: number) => {
    const next = filters.filter((_, i) => i !== idx);
    patchDataSource({ filters: next.length === 0 ? undefined : next });
  };

  const updateColumn = (idx: number, c: Partial<GroupedTableColumn>) => {
    const next = columns.map((it, i) => (i === idx ? { ...it, ...c } : it));
    patch({ columns: next });
  };
  const addColumn = () => patch({ columns: [...columns, { column: "" }] });
  const removeColumn = (idx: number) => {
    const next = columns.filter((_, i) => i !== idx);
    patch({ columns: next.length === 0 ? undefined : next });
  };

  const { options: tableOptions } = useDbTables();

  return (
    <div style={{ fontFamily: "var(--v5-font-sans)", color: "var(--cp-text)", padding: "0 12px" }}>
      {/* ── ① 기본 ─────────────────────────── */}
      <CPSection title="① 기본">
        <CPRow label="제목">
          <CPText
            value={current.title || ""}
            onChange={(v) => patch({ title: v || undefined })}
            placeholder="날짜별 근태"
          />
        </CPRow>
        <CPRow label="빈 결과 문구">
          <CPText
            value={current.emptyText || ""}
            onChange={(v) => patch({ emptyText: v || undefined })}
            placeholder="데이터 없음"
          />
        </CPRow>
      </CPSection>

      {/* ── ② 데이터 소스 ─────────────────────────── */}
      <CPSection title="② 데이터 소스">
        <CPRow label="테이블">
          <CPSelect
            value={ds.tableName || ""}
            onChange={(v) => patchDataSource({ tableName: v || undefined })}
          >
            <option value="">선택...</option>
            {tableOptions.map((t) => (
              <option key={t.value} value={t.value}>
                {t.label}
              </option>
            ))}
          </CPSelect>
        </CPRow>
        <CPRow label="정렬 컬럼" help="비우면 created_date desc 또는 PK 순">
          <CPText
            value={orderByCol}
            onChange={(v) =>
              patchDataSource({
                orderBy: v
                  ? [{ column: v, direction: orderByDir as "asc" | "desc" }]
                  : undefined,
              })
            }
            placeholder="attendance_date"
          />
        </CPRow>
        {orderByCol && (
          <CPRow label="정렬 방향">
            <CPSegment
              value={orderByDir}
              onChange={(v) =>
                patchDataSource({
                  orderBy: [{ column: orderByCol, direction: v as "asc" | "desc" }],
                })
              }
              options={[
                { value: "desc", label: "내림차순" },
                { value: "asc", label: "오름차순" },
              ]}
            />
          </CPRow>
        )}
        <CPRow label="최대 행 수" help="1 ~ 500. 기본 100">
          <CPNumber
            value={ds.limit ?? 100}
            onChange={(v) => patchDataSource({ limit: v ?? 100 })}
            min={1}
            max={500}
          />
        </CPRow>
      </CPSection>

      {/* ── ③ 그룹 ─────────────────────────── */}
      <CPSection title="③ 그룹">
        <CPRow label="그룹 컬럼" help="이 컬럼 값별로 row 묶음">
          <CPText
            value={current.groupBy || ""}
            onChange={(v) => patch({ groupBy: v || undefined })}
            placeholder="attendance_date, dept_code, ..."
          />
        </CPRow>
        <CPRow label="그룹 정렬">
          <CPSegment
            value={current.sortGroups ?? "none"}
            onChange={(v) => patch({ sortGroups: v as "none" | "asc" | "desc" })}
            options={[
              { value: "none", label: "원본 순" },
              { value: "asc", label: "오름차순" },
              { value: "desc", label: "내림차순" },
            ]}
          />
        </CPRow>
      </CPSection>

      {/* ── ④ 컬럼 ─────────────────────────── */}
      <CPSection title={`④ 컬럼 ${columns.length > 0 ? `(${columns.length})` : "(자동)"}`}>
        <div style={{ display: "flex", justifyContent: "flex-end", marginBottom: 5 }}>
          <button
            type="button"
            onClick={addColumn}
            style={{
              padding: "3px 8px",
              fontSize: 10.5,
              background: "var(--cp-bg-subtle)",
              border: "1px solid var(--cp-border)",
              borderRadius: 4,
              cursor: "pointer",
              color: "var(--cp-text)",
              display: "inline-flex",
              alignItems: "center",
              gap: 3,
            }}
          >
            <Plus size={10} /> 추가
          </button>
        </div>
        {columns.length === 0 ? (
          <Hint>컬럼 미지정 — row 의 모든 컬럼 자동 표시</Hint>
        ) : (
          <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
            {columns.map((c, idx) => (
              <ColumnRow
                key={idx}
                column={c}
                onChange={(p) => updateColumn(idx, p)}
                onRemove={() => removeColumn(idx)}
              />
            ))}
          </div>
        )}
      </CPSection>

      {/* ── ⑤ 필터 ─────────────────────────── */}
      <CPSection title={`⑤ 필터 ${filters.length > 0 ? `(${filters.length})` : ""}`}>
        <div style={{ display: "flex", justifyContent: "flex-end", marginBottom: 5 }}>
          <button
            type="button"
            onClick={addFilter}
            style={{
              padding: "3px 8px",
              fontSize: 10.5,
              background: "var(--cp-bg-subtle)",
              border: "1px solid var(--cp-border)",
              borderRadius: 4,
              cursor: "pointer",
              color: "var(--cp-text)",
              display: "inline-flex",
              alignItems: "center",
              gap: 3,
            }}
          >
            <Plus size={10} /> 추가
          </button>
        </div>
        {filters.length === 0 ? (
          <Hint>필터 없음 — 테이블 전체 row</Hint>
        ) : (
          <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
            {filters.map((f, idx) => (
              <OptionFilterRow
                key={idx}
                filter={f}
                onChange={(p) => updateFilter(idx, p)}
                onRemove={() => removeFilter(idx)}
                tableName={ds.tableName}
              />
            ))}
          </div>
        )}
      </CPSection>
    </div>
  );
};

InvGroupedTableConfigPanel.displayName = "InvGroupedTableConfigPanel";

function ColumnRow({
  column,
  onChange,
  onRemove,
}: {
  column: GroupedTableColumn;
  onChange: (p: Partial<GroupedTableColumn>) => void;
  onRemove: () => void;
}) {
  return (
    <div
      style={{
        display: "grid",
        gridTemplateColumns: "1.2fr 1fr 60px 70px 18px",
        gap: 4,
        alignItems: "center",
      }}
    >
      <input
        type="text"
        value={column.column}
        onChange={(e) => onChange({ column: e.target.value })}
        placeholder="컬럼명"
        style={inputBase()}
      />
      <input
        type="text"
        value={column.label || ""}
        onChange={(e) => onChange({ label: e.target.value || undefined })}
        placeholder="라벨"
        style={inputBase()}
      />
      <input
        type="text"
        value={column.width || ""}
        onChange={(e) => onChange({ width: e.target.value || undefined })}
        placeholder="auto"
        style={inputBase()}
      />
      <select
        value={column.align || "left"}
        onChange={(e) =>
          onChange({ align: e.target.value as GroupedTableColumn["align"] })
        }
        style={{ ...inputBase(), height: 22 }}
      >
        <option value="left">왼쪽</option>
        <option value="center">가운데</option>
        <option value="right">오른쪽</option>
      </select>
      <button
        type="button"
        onClick={onRemove}
        style={{
          width: 18,
          height: 18,
          padding: 0,
          border: "none",
          background: "transparent",
          cursor: "pointer",
          color: "var(--cp-text-muted)",
          display: "inline-flex",
          alignItems: "center",
          justifyContent: "center",
        }}
        aria-label="컬럼 삭제"
      >
        <Trash2 size={11} />
      </button>
    </div>
  );
}

function inputBase(): React.CSSProperties {
  return {
    height: 22,
    padding: "0 6px",
    fontSize: 11,
    fontFamily: "var(--v5-font-sans)",
    background: "var(--cp-surface)",
    border: "1px solid var(--cp-border)",
    borderRadius: 3,
    color: "var(--cp-text)",
    outline: "none",
    minWidth: 0,
  };
}

export default InvGroupedTableConfigPanel;
