"use client";

/**
 * InvCardListConfigPanel — canonical card-list 설정 패널 (Phase G.3.1, cp 톤)
 *
 * 흐름:
 *   ① 기본 — 제목 + 레이아웃 (list / grid)
 *   ② 데이터 소스 — 테이블 + 정렬 컬럼 + limit
 *   ③ 필드 매핑 — title / subtitles / metrics
 *   ④ 필터 — OptionFilter 빌더
 */

import React from "react";
import { Plus, Trash2 } from "lucide-react";
import {
  CPSection,
  CPRow,
  CPText,
  CPSelect,
  CPSegment,
  CPNumber,
  CPSwitch,
  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 {
  CardListConfig,
  CardListDataSource,
  CardListLayout,
  CardListMetric,
} from "./types";

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

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

  const ds = current.dataSource ?? {};
  const patchDataSource = (p: Partial<CardListDataSource>) => {
    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 subtitles = current.subtitleFields ?? [];
  const metrics: CardListMetric[] = current.metricFields ?? [];

  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) =>
    patchDataSource({ filters: filters.filter((_, i) => i !== idx).length === 0 ? undefined : filters.filter((_, i) => i !== idx) });

  const updateSubtitle = (idx: number, v: string) => {
    const next = subtitles.map((it, i) => (i === idx ? v : it));
    patch({ subtitleFields: next });
  };
  const addSubtitle = () => patch({ subtitleFields: [...subtitles, ""] });
  const removeSubtitle = (idx: number) =>
    patch({
      subtitleFields: subtitles.filter((_, i) => i !== idx).length === 0
        ? undefined
        : subtitles.filter((_, i) => i !== idx),
    });

  const updateMetric = (idx: number, m: Partial<CardListMetric>) => {
    const next = metrics.map((it, i) => (i === idx ? { ...it, ...m } : it));
    patch({ metricFields: next });
  };
  const addMetric = () => patch({ metricFields: [...metrics, { column: "" }] });
  const removeMetric = (idx: number) => {
    const next = metrics.filter((_, i) => i !== idx);
    patch({ metricFields: next.length === 0 ? undefined : next });
  };

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

  const { options: tableOptions } = useDbTables();

  return (
    <div style={{ fontFamily: "var(--v5-font-sans)", color: "var(--cp-text)", padding: "0 12px" }}>
      {/* ── ① 기본 ─────────────────────────── */}
      <CPSection title="① 기본">
        <CPRow label="제목" help="비우면 제목 영역 숨김">
          <CPText
            value={current.title || ""}
            onChange={(v) => patch({ title: v || undefined })}
            placeholder="부서별 카드"
          />
        </CPRow>
        <CPRow label="레이아웃">
          <CPSegment
            value={current.layout || "list"}
            onChange={(v) => patch({ layout: v as CardListLayout })}
            options={[
              { value: "list", label: "리스트" },
              { value: "grid", label: "그리드" },
            ]}
          />
        </CPRow>
        {(current.layout ?? "list") === "grid" && (
          <CPRow label="그리드 컬럼" help="비우면 auto-fit. 1 ~ 6 권장">
            <CPNumber
              value={current.columns ?? undefined}
              onChange={(v) => patch({ columns: v ?? undefined })}
              min={1}
              max={8}
              placeholder="auto"
            />
          </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="created_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. 기본 50">
          <CPNumber
            value={ds.limit ?? 50}
            onChange={(v) => patchDataSource({ limit: v ?? 50 })}
            min={1}
            max={500}
          />
        </CPRow>
      </CPSection>

      {/* ── ③ 필드 매핑 ─────────────────────────── */}
      <CPSection title="③ 필드 매핑" desc="카드 한 장에 보일 컬럼들">
        <CPRow label="제목 컬럼">
          <CPText
            value={current.titleField || ""}
            onChange={(v) => patch({ titleField: v || undefined })}
            placeholder="dept_name"
          />
        </CPRow>

        <div
          style={{
            display: "flex",
            alignItems: "center",
            justifyContent: "space-between",
            marginTop: 6,
          }}
        >
          <span style={{ fontSize: 10.5, color: "var(--cp-text-sec)", fontWeight: 700 }}>
            부제 컬럼 {subtitles.length > 0 && `(${subtitles.length})`}
          </span>
          <button
            type="button"
            onClick={addSubtitle}
            style={{
              padding: "2px 6px",
              fontSize: 10,
              background: "var(--cp-bg-subtle)",
              border: "1px solid var(--cp-border)",
              borderRadius: 3,
              cursor: "pointer",
              color: "var(--cp-text)",
              display: "inline-flex",
              alignItems: "center",
              gap: 3,
            }}
          >
            <Plus size={9} /> 추가
          </button>
        </div>
        {subtitles.length === 0 ? (
          <Hint>부제 없음</Hint>
        ) : (
          <div style={{ display: "flex", flexDirection: "column", gap: 4, marginTop: 4 }}>
            {subtitles.map((col, idx) => (
              <SubtitleRow
                key={idx}
                value={col}
                onChange={(v) => updateSubtitle(idx, v)}
                onRemove={() => removeSubtitle(idx)}
              />
            ))}
          </div>
        )}

        <div
          style={{
            display: "flex",
            alignItems: "center",
            justifyContent: "space-between",
            marginTop: 10,
          }}
        >
          <span style={{ fontSize: 10.5, color: "var(--cp-text-sec)", fontWeight: 700 }}>
            metric 칩 {metrics.length > 0 && `(${metrics.length})`}
          </span>
          <button
            type="button"
            onClick={addMetric}
            style={{
              padding: "2px 6px",
              fontSize: 10,
              background: "var(--cp-bg-subtle)",
              border: "1px solid var(--cp-border)",
              borderRadius: 3,
              cursor: "pointer",
              color: "var(--cp-text)",
              display: "inline-flex",
              alignItems: "center",
              gap: 3,
            }}
          >
            <Plus size={9} /> 추가
          </button>
        </div>
        {metrics.length === 0 ? (
          <Hint>metric 칩 없음 — 카드 우측/하단 숫자 강조 영역 빈 상태</Hint>
        ) : (
          <div style={{ display: "flex", flexDirection: "column", gap: 4, marginTop: 4 }}>
            {metrics.map((m, idx) => (
              <MetricRow
                key={idx}
                metric={m}
                onChange={(p) => updateMetric(idx, p)}
                onRemove={() => removeMetric(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>
  );
};

InvCardListConfigPanel.displayName = "InvCardListConfigPanel";

function SubtitleRow({
  value,
  onChange,
  onRemove,
}: {
  value: string;
  onChange: (v: string) => void;
  onRemove: () => void;
}) {
  return (
    <div style={{ display: "grid", gridTemplateColumns: "1fr 18px", gap: 4, alignItems: "center" }}>
      <input
        type="text"
        value={value}
        onChange={(e) => onChange(e.target.value)}
        placeholder="컬럼명"
        style={{
          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,
        }}
      />
      <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 MetricRow({
  metric,
  onChange,
  onRemove,
}: {
  metric: CardListMetric;
  onChange: (p: Partial<CardListMetric>) => void;
  onRemove: () => void;
}) {
  return (
    <div
      style={{
        display: "grid",
        gridTemplateColumns: "1fr 1fr 60px 18px",
        gap: 4,
        alignItems: "center",
      }}
    >
      <input
        type="text"
        value={metric.column}
        onChange={(e) => onChange({ column: e.target.value })}
        placeholder="컬럼명"
        style={inputBase()}
      />
      <input
        type="text"
        value={metric.label || ""}
        onChange={(e) => onChange({ label: e.target.value || undefined })}
        placeholder="라벨"
        style={inputBase()}
      />
      <span style={{ display: "inline-flex", alignItems: "center", gap: 3 }}>
        <CPSwitch value={!!metric.emphasis} onChange={(v) => onChange({ emphasis: v })} />
        <span style={{ fontSize: 9, color: "var(--cp-text-muted)" }}>강조</span>
      </span>
      <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="metric 삭제"
      >
        <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 InvCardListConfigPanel;
