"use client";

/**
 * InvChartConfigPanel — canonical 차트 컴포넌트 (id: chart) cp 톤 설정 패널 (Phase G.3)
 *
 * 흐름:
 *   ① 기본 — 제목 + 차트 종류 (CPVisualGrid 4종)
 *   ② 데이터 소스 — 테이블 / groupBy / 집계 / valueColumn
 *   ③ 필터 — OptionFilter 빌더 (stats 와 같은 패턴 재사용)
 *   ④ 표시 옵션 — 최대 그룹 / 정렬 방향 / 빈 그룹 / 축 / 범례 / 색
 *
 * Reference: notes/gbpark/2026-04-28-cp-panel-standard.md
 */

import React from "react";
import { Plus, BarChart3, BarChart2, PieChart as PieIcon, LineChart as LineIcon } from "lucide-react";
import {
  CPSection,
  CPRow,
  CPText,
  CPSelect,
  CPSegment,
  CPNumber,
  CPColor,
  CPVisualGrid,
  CPSwitch,
  Hint,
} from "@/components/v2/config-panels/_shared/cp";
import { useDbTables } from "../common/useDbTables";
import { OptionFilterRow } from "../_shared/FilterRow";
import { ColumnPicker } from "../_shared/ColumnPicker";
import type { OptionFilter } from "../input/use-option-loader";
import type { ChartConfig, ChartType, ChartDataSource } from "./types";
import type { StatsAggregation } from "../stats/types";

const CHART_TYPES: Array<{ value: ChartType; label: string; preview: React.ReactNode; desc: string }> = [
  { value: "bar", label: "막대", preview: <BarChart3 size={18} />, desc: "세로 막대 그래프" },
  { value: "horizontalBar", label: "가로 막대", preview: <BarChart2 size={18} style={{ transform: "rotate(90deg)" }} />, desc: "가로 막대 그래프" },
  { value: "line", label: "선", preview: <LineIcon size={18} />, desc: "추세선" },
  { value: "donut", label: "도넛", preview: <PieIcon size={18} />, desc: "도넛형 비율" },
];

const AGGREGATION_OPTS: Array<{ value: StatsAggregation; label: string }> = [
  { value: "count", label: "건수" },
  { value: "distinctCount", label: "고유 건수" },
  { value: "sum", label: "합계" },
  { value: "avg", label: "평균" },
  { value: "min", label: "최소" },
  { value: "max", label: "최대" },
];

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

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

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

  const aggregation: StatsAggregation = ds.aggregation ?? "count";
  const needsValueColumn = aggregation !== "count";

  const filters = ds.filters ?? [];
  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 { 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>
        <div style={{ marginTop: 8 }}>
          <CPRow label="차트 종류" />
          <CPVisualGrid
            cols={4}
            cardHeight={56}
            value={current.chartType || "bar"}
            onChange={(v) => patch({ chartType: v as ChartType })}
            options={CHART_TYPES}
          />
        </div>
      </CPSection>

      {/* ── ② 데이터 소스 ─────────────────────────── */}
      <CPSection title="② 데이터 소스" desc="GROUP BY 컬럼별 집계 결과를 차트로 표시">
        <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="이 컬럼 값별로 묶어 집계">
          <ColumnPicker
            tableName={ds.tableName}
            value={ds.groupBy}
            onChange={(v) => patchDataSource({ groupBy: v || undefined })}
            placeholder="그룹 컬럼 선택…"
          />
        </CPRow>
        <CPRow label="집계">
          <CPSelect
            value={aggregation}
            onChange={(v) => patchDataSource({ aggregation: (v as StatsAggregation) || "count" })}
          >
            {AGGREGATION_OPTS.map((o) => (
              <option key={o.value} value={o.value}>
                {o.label}
              </option>
            ))}
          </CPSelect>
        </CPRow>
        {(needsValueColumn || ds.valueColumn) && (
          <CPRow label="값 컬럼" help={needsValueColumn ? "필수" : "(count 는 비워도 됨)"}>
            <ColumnPicker
              tableName={ds.tableName}
              value={ds.valueColumn}
              onChange={(v) => patchDataSource({ valueColumn: v || undefined })}
              placeholder="값 컬럼 선택…"
            />
          </CPRow>
        )}
      </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>필터 없음 — 테이블 전체 그룹별 집계</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>

      {/* ── ④ 표시 옵션 ─────────────────────────── */}
      <CPSection title="④ 표시 옵션">
        <CPRow label="최대 그룹 수" help="1 ~ 500. 기본 12">
          <CPNumber
            value={ds.limit ?? 12}
            onChange={(v) => patchDataSource({ limit: v ?? 12 })}
            min={1}
            max={500}
          />
        </CPRow>
        <CPRow label="정렬">
          <CPSegment
            value={ds.orderDir ?? "desc"}
            onChange={(v) => patchDataSource({ orderDir: v as "asc" | "desc" })}
            options={[
              { value: "desc", label: "값 큰 순" },
              { value: "asc", label: "값 작은 순" },
            ]}
          />
        </CPRow>
        <CPRow label="빈 그룹 포함">
          <CPSwitch
            value={!!current.includeEmptyGroup}
            onChange={(v) => patch({ includeEmptyGroup: v })}
          />
        </CPRow>
        <CPRow label="축 표시">
          <CPSwitch
            value={current.showAxis ?? true}
            onChange={(v) => patch({ showAxis: v })}
          />
        </CPRow>
        {(current.chartType ?? "bar") === "donut" && (
          <CPRow label="범례 표시">
            <CPSwitch
              value={current.showLegend ?? true}
              onChange={(v) => patch({ showLegend: v })}
            />
          </CPRow>
        )}
        {(current.chartType ?? "bar") !== "donut" && (
          <CPRow label="막대/선 색">
            <CPColor
              value={current.barColor || "#6c5ce7"}
              onChange={(v) => patch({ barColor: v || undefined })}
            />
          </CPRow>
        )}
      </CPSection>
    </div>
  );
};

InvChartConfigPanel.displayName = "InvChartConfigPanel";

export default InvChartConfigPanel;
