"use client";

import React, { useState, useEffect, useCallback, useRef, useMemo } from "react";
import {
  BarChart, Bar, LineChart, Line, AreaChart, Area,
  XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer,
} from "recharts";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import {
  Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter,
} from "@/components/ui/dialog";
import { ScrollToTop } from "@/components/common/ScrollToTop";
import { cn } from "@/lib/utils";
import { apiClient } from "@/lib/api/client";

// ============================================
// 공통 상수
// ============================================
const COLORS = [
  "#3b82f6", "#10b981", "#f59e0b", "#ef4444", "#8b5cf6",
  "#ec4899", "#06b6d4", "#84cc16", "#f97316", "#14b8a6",
];

function ChartTooltip({ active, payload, label }: any) {
  if (!active || !payload?.length) return null;
  return (
    <div className="rounded-lg border border-border bg-popover px-3 py-2 shadow-lg">
      <p className="mb-1.5 text-xs font-semibold text-popover-foreground">{label}</p>
      {payload.map((entry: any, i: number) => (
        <div key={i} className="flex items-center gap-2 text-xs">
          <span className="h-2.5 w-2.5 shrink-0 rounded-sm" style={{ background: entry.color }} />
          <span className="text-muted-foreground">{entry.name}:</span>
          <span className="font-medium tabular-nums text-popover-foreground">
            {typeof entry.value === "number" ? entry.value.toLocaleString() : entry.value}
          </span>
        </div>
      ))}
    </div>
  );
}

const AGG_METHODS = [
  { id: "sum", name: "합계 (SUM)" },
  { id: "avg", name: "평균 (AVG)" },
  { id: "max", name: "최대 (MAX)" },
  { id: "min", name: "최소 (MIN)" },
  { id: "count", name: "건수 (COUNT)" },
];

const CHART_TYPES = [
  { id: "bar", name: "막대" },
  { id: "line", name: "선" },
  { id: "area", name: "영역" },
];

const DATE_PRESETS = [
  { id: "today", name: "오늘" },
  { id: "week", name: "이번주" },
  { id: "month", name: "이번달" },
  { id: "quarter", name: "이번분기" },
  { id: "year", name: "올해" },
  { id: "prevMonth", name: "전월" },
  { id: "last3m", name: "최근3개월" },
  { id: "last6m", name: "최근6개월" },
];

const FILTER_OPERATORS: Record<string, { id: string; name: string }[]> = {
  select: [
    { id: "eq", name: "=" },
    { id: "neq", name: "≠" },
    { id: "in", name: "포함(IN)" },
  ],
  number: [
    { id: "eq", name: "=" },
    { id: "neq", name: "≠" },
    { id: "gt", name: ">" },
    { id: "gte", name: "≥" },
    { id: "lt", name: "<" },
    { id: "lte", name: "≤" },
  ],
};

// ============================================
// 타입 정의 (외부 export)
// ============================================
export interface ReportMetric {
  id: string;
  name: string;
  unit: string;
  color: string;
  isRate?: boolean;
}

export interface ReportGroupByOption {
  id: string;
  name: string;
}

export interface ReportThreshold {
  id: string;
  label: string;
  defaultValue: number;
  unit: string;
}

export interface ReportColumnDef {
  id: string;
  name: string;
  align?: "left" | "right";
  format?: "number" | "text" | "badge" | "date";
}

export interface FilterFieldDef {
  id: string;
  name: string;
  type: "select" | "number";
  optionKey?: string;
}

export interface ReportConfig {
  key: string;
  title: string;
  description: string;
  apiEndpoint: string;
  metrics: ReportMetric[];
  groupByOptions: ReportGroupByOption[];
  defaultGroupBy: string;
  defaultMetrics: string[];
  thresholds: ReportThreshold[];
  filterFieldDefs: FilterFieldDef[];
  drilldownColumns: ReportColumnDef[];
  rawDataColumns: ReportColumnDef[];
  enrichRow?: (row: Record<string, any>) => Record<string, any>;
  emptyMessage: string;
}

interface ConditionFilter {
  id: number;
  logic: "AND" | "OR" | "";
  field: string;
  operator: string;
  value: string;
  values: string[];
}

interface ConditionGroup {
  id: number;
  name: string;
  metrics: string[];
  aggMethod: string;
  chartType: string;
  collapsed: boolean;
  filters: ConditionFilter[];
}

interface FilterField {
  id: string;
  name: string;
  type: "select" | "number";
  options: { value: string; label: string }[];
}

interface Preset {
  name: string;
  desc: string;
  config: {
    groupBy: string;
    startDate: string;
    endDate: string;
    conditions: ConditionGroup[];
  };
  savedAt: string;
}

// ============================================
// 유틸 함수
// ============================================
function getDatePresetRange(preset: string): { start: string; end: string } {
  const today = new Date();
  let s = new Date(today);
  let e = new Date(today);

  switch (preset) {
    case "today":
      break;
    case "week":
      s.setDate(today.getDate() - today.getDay());
      e.setDate(s.getDate() + 6);
      break;
    case "month":
      s.setDate(1);
      e = new Date(today.getFullYear(), today.getMonth() + 1, 0);
      break;
    case "quarter": {
      const q = Math.floor(today.getMonth() / 3);
      s = new Date(today.getFullYear(), q * 3, 1);
      e = new Date(today.getFullYear(), q * 3 + 3, 0);
      break;
    }
    case "year":
      s = new Date(today.getFullYear(), 0, 1);
      e = new Date(today.getFullYear(), 11, 31);
      break;
    case "prevMonth":
      s = new Date(today.getFullYear(), today.getMonth() - 1, 1);
      e = new Date(today.getFullYear(), today.getMonth(), 0);
      break;
    case "last3m":
      s = new Date(today.getFullYear(), today.getMonth() - 3, today.getDate());
      break;
    case "last6m":
      s = new Date(today.getFullYear(), today.getMonth() - 6, today.getDate());
      break;
  }

  return {
    start: s.toISOString().split("T")[0],
    end: e.toISOString().split("T")[0],
  };
}

function getGroupKey(row: Record<string, any>, groupBy: string): string {
  const dateStr = row.date || "";
  switch (groupBy) {
    case "daily":
      return dateStr.substring(0, 10) || "미지정";
    case "weekly": {
      if (!dateStr) return "미지정";
      const dt = new Date(dateStr);
      const weekNum = Math.ceil(
        ((dt.getTime() - new Date(dt.getFullYear(), 0, 1).getTime()) / 86400000 +
          new Date(dt.getFullYear(), 0, 1).getDay() + 1) / 7
      );
      return `${dt.getFullYear()}-W${String(weekNum).padStart(2, "0")}`;
    }
    case "monthly":
      return dateStr.substring(0, 7) || "미지정";
    case "quarterly": {
      if (!dateStr) return "미지정";
      const m = parseInt(dateStr.substring(5, 7));
      return `${dateStr.substring(0, 4)}-Q${Math.ceil(m / 3)}`;
    }
    default:
      return row[groupBy] || "미지정";
  }
}

function aggregateValues(
  rows: Record<string, any>[],
  metricId: string,
  method: string
): number {
  if (!rows.length) return 0;
  const vals = rows.map((r) => Number(r[metricId]) || 0);
  switch (method) {
    case "sum": return vals.reduce((a, b) => a + b, 0);
    case "avg": return Math.round((vals.reduce((a, b) => a + b, 0) / vals.length) * 10) / 10;
    case "max": return Math.max(...vals);
    case "min": return Math.min(...vals);
    case "count": return rows.length;
    default: return vals.reduce((a, b) => a + b, 0);
  }
}

function evalFilter(
  rec: Record<string, any>,
  f: ConditionFilter,
  filterFields: FilterField[]
): boolean {
  const field = filterFields.find((x) => x.id === f.field);
  if (!field) return true;

  const rv = rec[f.field];

  if (field.type === "select") {
    switch (f.operator) {
      case "eq": return !f.value || rv === f.value;
      case "neq": return !f.value || rv !== f.value;
      case "in": return f.values.length === 0 || f.values.includes(rv);
    }
  } else {
    const nv = parseFloat(rv) || 0;
    const cv = parseFloat(f.value) || 0;
    switch (f.operator) {
      case "eq": return !f.value || nv === cv;
      case "neq": return !f.value || nv !== cv;
      case "gt": return !f.value || nv > cv;
      case "gte": return !f.value || nv >= cv;
      case "lt": return !f.value || nv < cv;
      case "lte": return !f.value || nv <= cv;
    }
  }
  return true;
}

function applyConditionFilters(
  data: Record<string, any>[],
  filters: ConditionFilter[],
  filterFields: FilterField[]
): Record<string, any>[] {
  if (!filters.length) return data;
  return data.filter((d) => {
    let res = evalFilter(d, filters[0], filterFields);
    for (let i = 1; i < filters.length; i++) {
      const v = evalFilter(d, filters[i], filterFields);
      res = filters[i].logic === "OR" ? res || v : res && v;
    }
    return res;
  });
}

function formatNumber(n: number): string {
  return n.toLocaleString("ko-KR");
}

function renderCellValue(row: Record<string, any>, col: ReportColumnDef): React.ReactNode {
  const val = row[col.id];
  switch (col.format) {
    case "number":
      return formatNumber(Number(val) || 0);
    case "date":
      return String(val || "").substring(0, 10);
    case "badge":
      return <Badge variant="outline">{val || "-"}</Badge>;
    default:
      return String(val ?? "");
  }
}

// ============================================
// ReportEngine 컴포넌트
// ============================================
interface ReportEngineProps {
  config: ReportConfig;
}

export default function ReportEngine({ config }: ReportEngineProps) {
  const [rawData, setRawData] = useState<Record<string, any>[]>([]);
  const [filterOptions, setFilterOptions] = useState<Record<string, { value: string; label: string }[]>>({});
  const [isLoading, setIsLoading] = useState(false);

  const [groupBy, setGroupBy] = useState(config.defaultGroupBy);
  const [startDate, setStartDate] = useState("");
  const [endDate, setEndDate] = useState("");
  const [activePreset, setActivePreset] = useState("last6m");
  const [filterOpen, setFilterOpen] = useState(true);

  const [conditions, setConditions] = useState<ConditionGroup[]>([]);
  const condIdRef = useRef(0);
  const filterIdRef = useRef(0);

  const [viewMode, setViewMode] = useState<"table" | "card">("table");
  const [drilldownLabel, setDrilldownLabel] = useState<string | null>(null);
  const [rawDataOpen, setRawDataOpen] = useState(false);

  const [presets, setPresets] = useState<Preset[]>([]);
  const [presetModalOpen, setPresetModalOpen] = useState(false);
  const [presetName, setPresetName] = useState("");
  const [presetDesc, setPresetDesc] = useState("");
  const [selectedPresetIdx, setSelectedPresetIdx] = useState("");

  const [thresholdValues, setThresholdValues] = useState<Record<string, number>>(() => {
    const defaults: Record<string, number> = {};
    config.thresholds.forEach((t) => { defaults[t.id] = t.defaultValue; });
    return defaults;
  });

  const [refreshInterval, setRefreshInterval] = useState(0);
  const refreshTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);

  const PRESET_KEY = `${config.key}_presets`;

  const filterFields: FilterField[] = useMemo(
    () =>
      config.filterFieldDefs.map((def) => ({
        id: def.id,
        name: def.name,
        type: def.type,
        options: def.type === "select" && def.optionKey
          ? filterOptions[def.optionKey] || []
          : [],
      })),
    [config.filterFieldDefs, filterOptions]
  );

  const aggLabel = (method: string) =>
    ({ sum: "합계", avg: "평균", max: "최대", min: "최소", count: "건수" }[method] || "합계");

  // ============================================
  // 초기화
  // ============================================
  useEffect(() => {
    const range = getDatePresetRange("last6m");
    setStartDate(range.start);
    setEndDate(range.end);

    condIdRef.current = 1;
    setConditions([
      {
        id: 1,
        name: "조건 1",
        metrics: [...config.defaultMetrics],
        aggMethod: "sum",
        chartType: "bar",
        collapsed: false,
        filters: [],
      },
    ]);

    loadPresets();
  }, []);

  useEffect(() => {
    if (startDate && endDate) {
      fetchData();
    }
  }, [startDate, endDate]);

  useEffect(() => {
    if (refreshTimerRef.current) clearInterval(refreshTimerRef.current);
    if (refreshInterval > 0) {
      refreshTimerRef.current = setInterval(fetchData, refreshInterval * 1000);
    }
    return () => {
      if (refreshTimerRef.current) clearInterval(refreshTimerRef.current);
    };
  }, [refreshInterval]);

  // ============================================
  // API 호출
  // ============================================
  const fetchData = useCallback(async () => {
    setIsLoading(true);
    try {
      const params = new URLSearchParams();
      if (startDate) params.set("startDate", startDate);
      if (endDate) params.set("endDate", endDate);

      const response = await apiClient.get(
        `${config.apiEndpoint}?${params.toString()}`
      );

      if (response.data?.success) {
        const { rows, filterOptions: opts } = response.data.data;
        let processedRows = rows.map((r: any) => {
          const numericRow: Record<string, any> = { ...r };
          config.metrics.forEach((m) => {
            if (numericRow[m.id] !== undefined) {
              numericRow[m.id] = Number(numericRow[m.id]) || 0;
            }
          });
          return numericRow;
        });

        if (config.enrichRow) {
          processedRows = processedRows.map(config.enrichRow);
        }

        setRawData(processedRows);
        setFilterOptions(opts || {});
      }
    } catch (err) {
      console.error("데이터 조회 실패:", err);
    } finally {
      setIsLoading(false);
    }
  }, [startDate, endDate, config.apiEndpoint, config.enrichRow, config.metrics]);

  // ============================================
  // 조건 관리
  // ============================================
  const addCondition = () => {
    condIdRef.current++;
    setConditions((prev) => [
      ...prev,
      {
        id: condIdRef.current,
        name: `조건 ${condIdRef.current}`,
        metrics: [...config.defaultMetrics],
        aggMethod: "sum",
        chartType: "bar",
        collapsed: false,
        filters: [],
      },
    ]);
  };

  const removeCondition = (id: number) => {
    if (conditions.length <= 1) return;
    setConditions((prev) => prev.filter((c) => c.id !== id));
  };

  const duplicateCondition = (id: number) => {
    const src = conditions.find((c) => c.id === id);
    if (!src) return;
    condIdRef.current++;
    setConditions((prev) => [
      ...prev,
      { ...JSON.parse(JSON.stringify(src)), id: condIdRef.current, name: src.name + " (복사)" },
    ]);
  };

  const updateCondition = (id: number, updates: Partial<ConditionGroup>) => {
    setConditions((prev) =>
      prev.map((c) => (c.id === id ? { ...c, ...updates } : c))
    );
  };

  const toggleMetric = (condId: number, metricId: string) => {
    setConditions((prev) =>
      prev.map((c) => {
        if (c.id !== condId) return c;
        const idx = c.metrics.indexOf(metricId);
        if (idx > -1) {
          if (c.metrics.length <= 1) return c;
          return { ...c, metrics: c.metrics.filter((m) => m !== metricId) };
        }
        return { ...c, metrics: [...c.metrics, metricId] };
      })
    );
  };

  const addFilter = (condId: number) => {
    filterIdRef.current++;
    const firstField = config.filterFieldDefs[0]?.id || "";
    setConditions((prev) =>
      prev.map((c) => {
        if (c.id !== condId) return c;
        return {
          ...c,
          filters: [
            ...c.filters,
            {
              id: filterIdRef.current,
              logic: c.filters.length === 0 ? "" : "AND",
              field: firstField,
              operator: "eq",
              value: "",
              values: [],
            },
          ],
        };
      })
    );
  };

  const removeFilter = (condId: number, filterId: number) => {
    setConditions((prev) =>
      prev.map((c) => {
        if (c.id !== condId) return c;
        const newFilters = c.filters.filter((f) => f.id !== filterId);
        if (newFilters.length > 0) newFilters[0].logic = "";
        return { ...c, filters: newFilters };
      })
    );
  };

  const updateFilter = (
    condId: number,
    filterId: number,
    updates: Partial<ConditionFilter>
  ) => {
    setConditions((prev) =>
      prev.map((c) => {
        if (c.id !== condId) return c;
        return {
          ...c,
          filters: c.filters.map((f) =>
            f.id === filterId ? { ...f, ...updates } : f
          ),
        };
      })
    );
  };

  // ============================================
  // 날짜 프리셋
  // ============================================
  const handleDatePreset = (preset: string) => {
    setActivePreset(preset);
    const range = getDatePresetRange(preset);
    setStartDate(range.start);
    setEndDate(range.end);
  };

  // ============================================
  // 프리셋 저장/불러오기
  // ============================================
  const loadPresets = () => {
    try {
      const stored = localStorage.getItem(PRESET_KEY);
      if (stored) setPresets(JSON.parse(stored));
    } catch {}
  };

  const savePreset = () => {
    if (!presetName.trim()) return;
    const newPresets = [
      ...presets,
      {
        name: presetName.trim(),
        desc: presetDesc.trim(),
        config: { groupBy, startDate, endDate, conditions },
        savedAt: new Date().toISOString(),
      },
    ];
    setPresets(newPresets);
    localStorage.setItem(PRESET_KEY, JSON.stringify(newPresets));
    setPresetModalOpen(false);
    setPresetName("");
    setPresetDesc("");
  };

  const loadSelectedPreset = (idx: string) => {
    setSelectedPresetIdx(idx);
    if (idx === "") return;
    const p = presets[parseInt(idx)];
    if (!p?.config) return;
    setGroupBy(p.config.groupBy);
    setStartDate(p.config.startDate);
    setEndDate(p.config.endDate);
    setConditions(p.config.conditions);
  };

  const deletePreset = () => {
    if (selectedPresetIdx === "") return;
    const newPresets = presets.filter((_, i) => i !== parseInt(selectedPresetIdx));
    setPresets(newPresets);
    localStorage.setItem(PRESET_KEY, JSON.stringify(newPresets));
    setSelectedPresetIdx("");
  };

  // ============================================
  // 데이터 분석 (클라이언트 사이드)
  // ============================================
  const analysisResult = useMemo(() => {
    if (!rawData.length) return { series: [], labels: [], chartData: [] };

    const seriesList: {
      condId: number;
      condName: string;
      condIdx: number;
      metricId: string;
      metricName: string;
      metricUnit: string;
      aggMethod: string;
      chartType: string;
      groups: Record<string, Record<string, any>[]>;
    }[] = [];

    const allLabelsSet = new Set<string>();

    conditions.forEach((cond, ci) => {
      const condData = applyConditionFilters(rawData, cond.filters, filterFields);

      const groups: Record<string, Record<string, any>[]> = {};
      condData.forEach((d) => {
        const key = getGroupKey(d, groupBy);
        if (!groups[key]) groups[key] = [];
        groups[key].push(d);
      });
      Object.keys(groups).forEach((k) => allLabelsSet.add(k));

      cond.metrics.forEach((metricId) => {
        const m = config.metrics.find((x) => x.id === metricId);
        if (!m) return;
        seriesList.push({
          condId: cond.id,
          condName: cond.name,
          condIdx: ci,
          metricId,
          metricName: m.name,
          metricUnit: m.unit,
          aggMethod: cond.aggMethod,
          chartType: cond.chartType,
          groups,
        });
      });
    });

    const isTimeBased = ["monthly", "quarterly", "weekly", "daily"].includes(groupBy);
    let labels = [...allLabelsSet];

    if (isTimeBased) {
      labels.sort((a, b) => a.localeCompare(b));
    } else if (seriesList.length > 0) {
      const first = seriesList[0];
      labels.sort((a, b) => {
        const va = aggregateValues(first.groups[a] || [], first.metricId, first.aggMethod);
        const vb = aggregateValues(first.groups[b] || [], first.metricId, first.aggMethod);
        return vb - va;
      });
    }

    const chartData = labels.map((label) => {
      const point: Record<string, any> = { name: label };
      seriesList.forEach((s) => {
        const key = `${s.condName}_${s.metricName}`;
        point[key] = aggregateValues(s.groups[label] || [], s.metricId, s.aggMethod);
      });
      return point;
    });

    return { series: seriesList, labels, chartData };
  }, [rawData, conditions, groupBy, filterFields, config.metrics]);

  // ============================================
  // 렌더링
  // ============================================
  return (
    <div className="flex h-full flex-col overflow-auto bg-background">
      <div className="space-y-4 p-4 sm:p-6">
        {/* 헤더 */}
        <div className="flex flex-col gap-3 border-b pb-4 sm:flex-row sm:items-center sm:justify-between">
          <div>
            <h1 className="text-2xl font-bold tracking-tight sm:text-3xl">
              {config.title}
            </h1>
            <p className="text-sm text-muted-foreground">
              {config.description} | 원본 {rawData.length}건
            </p>
          </div>
          <div className="flex flex-wrap items-center gap-2">
            <select
              value={refreshInterval}
              onChange={(e) => setRefreshInterval(Number(e.target.value))}
              className={cn(
                "h-8 rounded-md border px-2 text-xs",
                refreshInterval > 0 && "border-primary bg-primary/5"
              )}
            >
              <option value={0}>자동갱신 OFF</option>
              <option value={30}>30초</option>
              <option value={60}>1분</option>
              <option value={300}>5분</option>
            </select>
            <Button variant="outline" size="sm" onClick={() => window.print()}>
              인쇄
            </Button>
          </div>
        </div>

        {/* 프리셋 바 */}
        <div className="flex flex-wrap items-center gap-2 rounded-md border bg-muted/30 p-3">
          <span className="text-xs font-medium text-muted-foreground">저장된 조건</span>
          <select
            value={selectedPresetIdx}
            onChange={(e) => loadSelectedPreset(e.target.value)}
            className="h-8 min-w-[180px] rounded-md border px-2 text-xs"
          >
            <option value="">조건을 선택하세요</option>
            {presets.map((p, i) => (
              <option key={i} value={i}>{p.name}</option>
            ))}
          </select>
          <Button size="sm" variant="default" className="h-8 text-xs" onClick={() => setPresetModalOpen(true)}>
            조건 저장
          </Button>
          <Button size="sm" variant="outline" className="h-8 text-xs" onClick={deletePreset}>
            삭제
          </Button>
        </div>

        {/* 분석 조건 설정 */}
        <div className="rounded-md border">
          <button
            className="flex w-full items-center justify-between p-3 text-left hover:bg-muted/50"
            onClick={() => setFilterOpen(!filterOpen)}
          >
            <span className="text-sm font-semibold">분석 조건 설정</span>
            <span className={cn("text-xs transition-transform", !filterOpen && "-rotate-90")}>
              ▼
            </span>
          </button>

          {filterOpen && (
            <div className="space-y-4 border-t p-4">
              {/* 기준축 + 기간 */}
              <div className="flex flex-wrap gap-4">
                <div className="space-y-1">
                  <Label className="text-xs">분석 기준 (X축)</Label>
                  <select
                    value={groupBy}
                    onChange={(e) => setGroupBy(e.target.value)}
                    className="h-9 w-[140px] rounded-md border px-2 text-sm"
                  >
                    {config.groupByOptions.map((o) => (
                      <option key={o.id} value={o.id}>{o.name}</option>
                    ))}
                  </select>
                </div>
                <div className="space-y-1">
                  <Label className="text-xs">기간</Label>
                  <div className="flex items-center gap-2">
                    <Input
                      type="date"
                      value={startDate}
                      onChange={(e) => setStartDate(e.target.value)}
                      className="h-9 w-[150px] text-sm"
                    />
                    <span className="text-muted-foreground">~</span>
                    <Input
                      type="date"
                      value={endDate}
                      onChange={(e) => setEndDate(e.target.value)}
                      className="h-9 w-[150px] text-sm"
                    />
                  </div>
                </div>
              </div>

              {/* 날짜 프리셋 */}
              <div className="flex flex-wrap gap-1.5">
                {DATE_PRESETS.map((p) => (
                  <button
                    key={p.id}
                    onClick={() => handleDatePreset(p.id)}
                    className={cn(
                      "rounded-full border px-3 py-1 text-xs transition-colors",
                      activePreset === p.id
                        ? "border-primary bg-primary text-primary-foreground"
                        : "hover:bg-muted"
                    )}
                  >
                    {p.name}
                  </button>
                ))}
              </div>

              {/* 다중 분석 조건 */}
              <div className="space-y-3">
                <div className="flex items-center justify-between">
                  <span className="text-sm font-medium">분석 조건</span>
                  <Button size="sm" variant="outline" className="h-7 text-xs" onClick={addCondition}>
                    + 조건 추가
                  </Button>
                </div>

                {conditions.map((cond, ci) => {
                  const color = COLORS[ci % COLORS.length];
                  return (
                    <div
                      key={cond.id}
                      className="rounded-md border"
                      style={{ borderLeftColor: color, borderLeftWidth: 3 }}
                    >
                      <div
                        className="flex cursor-pointer items-center justify-between p-3 hover:bg-muted/30"
                        onClick={() => updateCondition(cond.id, { collapsed: !cond.collapsed })}
                      >
                        <div className="flex items-center gap-2">
                          <div className="h-3 w-3 rounded" style={{ background: color }} />
                          <input
                            value={cond.name}
                            onClick={(e) => e.stopPropagation()}
                            onChange={(e) => updateCondition(cond.id, { name: e.target.value })}
                            className="w-[100px] border-b border-transparent bg-transparent text-sm font-medium focus:border-primary focus:outline-none"
                          />
                          <span className="text-xs text-muted-foreground">
                            {cond.metrics.map((id) => config.metrics.find((m) => m.id === id)?.name).join("+")}
                            {" "}{aggLabel(cond.aggMethod)}
                            {" "}{CHART_TYPES.find((t) => t.id === cond.chartType)?.name}
                            {cond.filters.length > 0 && ` | 필터 ${cond.filters.length}개`}
                          </span>
                        </div>
                        <div className="flex items-center gap-1">
                          <button
                            className="rounded p-1 text-xs hover:bg-muted"
                            onClick={(e) => { e.stopPropagation(); duplicateCondition(cond.id); }}
                          >
                            복제
                          </button>
                          <button
                            className="rounded p-1 text-xs text-destructive hover:bg-destructive/10"
                            onClick={(e) => { e.stopPropagation(); removeCondition(cond.id); }}
                          >
                            X
                          </button>
                          <span className={cn("ml-1 text-xs transition-transform", cond.collapsed && "-rotate-90")}>
                            ▼
                          </span>
                        </div>
                      </div>

                      {!cond.collapsed && (
                        <div className="space-y-3 border-t p-3">
                          <div className="space-y-1">
                            <span className="text-xs text-muted-foreground">데이터</span>
                            <div className="flex flex-wrap gap-1.5">
                              {config.metrics.map((m) => {
                                const active = cond.metrics.includes(m.id);
                                return (
                                  <button
                                    key={m.id}
                                    onClick={() => toggleMetric(cond.id, m.id)}
                                    className={cn(
                                      "flex items-center gap-1.5 rounded-full border px-3 py-1 text-xs transition-colors",
                                      active
                                        ? "border-primary bg-primary/10 font-medium"
                                        : "hover:bg-muted"
                                    )}
                                  >
                                    {active && <span className="text-primary">✓</span>}
                                    <span
                                      className="inline-block h-2 w-2 rounded-full"
                                      style={{ background: m.color }}
                                    />
                                    {m.name}
                                  </button>
                                );
                              })}
                            </div>
                          </div>

                          <div className="flex flex-wrap items-center gap-3">
                            <div className="space-y-1">
                              <span className="text-xs text-muted-foreground">집계</span>
                              <select
                                value={cond.aggMethod}
                                onChange={(e) =>
                                  updateCondition(cond.id, { aggMethod: e.target.value })
                                }
                                className="h-8 rounded-md border px-2 text-xs"
                              >
                                {AGG_METHODS.map((a) => (
                                  <option key={a.id} value={a.id}>{a.name}</option>
                                ))}
                              </select>
                            </div>
                            <div className="space-y-1">
                              <span className="text-xs text-muted-foreground">차트</span>
                              <div className="flex gap-1">
                                {CHART_TYPES.map((ct) => (
                                  <button
                                    key={ct.id}
                                    onClick={() => updateCondition(cond.id, { chartType: ct.id })}
                                    className={cn(
                                      "rounded border px-2.5 py-1 text-xs",
                                      cond.chartType === ct.id
                                        ? "border-primary bg-primary text-primary-foreground"
                                        : "hover:bg-muted"
                                    )}
                                  >
                                    {ct.name}
                                  </button>
                                ))}
                              </div>
                            </div>
                          </div>

                          {/* 필터 */}
                          <div className="space-y-2">
                            <span className="text-xs text-muted-foreground">필터</span>
                            {cond.filters.length === 0 && (
                              <p className="text-xs text-muted-foreground/70">전체 데이터 (필터 없음)</p>
                            )}
                            {cond.filters.map((f, fi) => {
                              const field = filterFields.find((x) => x.id === f.field);
                              const ops = FILTER_OPERATORS[field?.type || "select"];
                              return (
                                <div key={f.id} className="flex flex-wrap items-center gap-1.5">
                                  {fi === 0 ? (
                                    <span className="w-[50px] text-center text-[11px] text-muted-foreground">WHERE</span>
                                  ) : (
                                    <select
                                      value={f.logic}
                                      onChange={(e) =>
                                        updateFilter(cond.id, f.id, {
                                          logic: e.target.value as "AND" | "OR",
                                        })
                                      }
                                      className="h-7 w-[50px] rounded border text-[11px]"
                                    >
                                      <option value="AND">AND</option>
                                      <option value="OR">OR</option>
                                    </select>
                                  )}
                                  <select
                                    value={f.field}
                                    onChange={(e) =>
                                      updateFilter(cond.id, f.id, {
                                        field: e.target.value,
                                        operator: "eq",
                                        value: "",
                                        values: [],
                                      })
                                    }
                                    className="h-7 rounded border px-1.5 text-[11px]"
                                  >
                                    {filterFields.map((ff) => (
                                      <option key={ff.id} value={ff.id}>{ff.name}</option>
                                    ))}
                                  </select>
                                  <select
                                    value={f.operator}
                                    onChange={(e) =>
                                      updateFilter(cond.id, f.id, { operator: e.target.value })
                                    }
                                    className="h-7 rounded border px-1.5 text-[11px]"
                                  >
                                    {ops.map((o) => (
                                      <option key={o.id} value={o.id}>{o.name}</option>
                                    ))}
                                  </select>
                                  {field?.type === "select" ? (
                                    <select
                                      value={f.value}
                                      onChange={(e) =>
                                        updateFilter(cond.id, f.id, { value: e.target.value })
                                      }
                                      className="h-7 min-w-[120px] rounded border px-1.5 text-[11px]"
                                    >
                                      <option value="">선택...</option>
                                      {field.options.map((o) => (
                                        <option key={o.value} value={o.label}>{o.label}</option>
                                      ))}
                                    </select>
                                  ) : (
                                    <input
                                      type="number"
                                      value={f.value}
                                      onChange={(e) =>
                                        updateFilter(cond.id, f.id, { value: e.target.value })
                                      }
                                      className="h-7 w-[100px] rounded border px-2 text-[11px]"
                                    />
                                  )}
                                  <button
                                    onClick={() => removeFilter(cond.id, f.id)}
                                    className="rounded p-1 text-xs text-destructive hover:bg-destructive/10"
                                  >
                                    X
                                  </button>
                                </div>
                              );
                            })}
                            <button
                              onClick={() => addFilter(cond.id)}
                              className="text-xs text-primary hover:underline"
                            >
                              + 필터 추가
                            </button>
                          </div>
                        </div>
                      )}
                    </div>
                  );
                })}
              </div>

              {/* 임계값 */}
              {config.thresholds.length > 0 && (
                <div className="flex flex-wrap items-center gap-4 rounded-md border bg-muted/20 p-3">
                  <span className="text-xs font-medium">임계값 설정</span>
                  {config.thresholds.map((t, ti) => (
                    <div key={t.id} className="flex items-center gap-2">
                      <span
                        className="inline-block h-2.5 w-2.5 rounded-full"
                        style={{ background: ti === 0 ? "#ef4444" : "#10b981" }}
                      />
                      <span className="text-xs">{t.label}</span>
                      <Input
                        type="number"
                        value={thresholdValues[t.id] ?? t.defaultValue}
                        onChange={(e) =>
                          setThresholdValues((prev) => ({
                            ...prev,
                            [t.id]: Number(e.target.value),
                          }))
                        }
                        className="h-7 w-[60px] text-xs"
                      />
                      <span className="text-xs">{t.unit}</span>
                    </div>
                  ))}
                </div>
              )}

              {/* 액션 */}
              <div className="flex justify-end gap-2">
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => {
                    condIdRef.current = 1;
                    setConditions([
                      {
                        id: 1,
                        name: "조건 1",
                        metrics: [...config.defaultMetrics],
                        aggMethod: "sum",
                        chartType: "bar",
                        collapsed: false,
                        filters: [],
                      },
                    ]);
                    setGroupBy(config.defaultGroupBy);
                    handleDatePreset("last6m");
                  }}
                >
                  전체 초기화
                </Button>
                <Button size="sm" onClick={fetchData} disabled={isLoading}>
                  {isLoading ? "분석 중..." : "분석 실행"}
                </Button>
              </div>
            </div>
          )}
        </div>

        {/* 적용된 조건 태그 */}
        {analysisResult.series.length > 0 && (
          <div className="flex flex-wrap gap-1.5">
            <Badge variant="secondary">
              {config.groupByOptions.find((o) => o.id === groupBy)?.name}
            </Badge>
            {(startDate || endDate) && (
              <Badge variant="secondary">
                {startDate || "~"} ~ {endDate || "~"}
              </Badge>
            )}
            {conditions.map((cond, ci) => (
              <Badge
                key={cond.id}
                variant="outline"
                style={{ borderColor: COLORS[ci % COLORS.length] + "80" }}
              >
                <span
                  className="mr-1 inline-block h-2 w-2 rounded"
                  style={{ background: COLORS[ci % COLORS.length] }}
                />
                {cond.name}: {cond.metrics.map((id) => config.metrics.find((m) => m.id === id)?.name).join("+")}
                {" "}({aggLabel(cond.aggMethod)})
              </Badge>
            ))}
          </div>
        )}

        {/* KPI 카드 */}
        {analysisResult.series.length > 0 && (
          <div className="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-5">
            {conditions.flatMap((cond, ci) =>
              cond.metrics.map((metricId) => {
                const m = config.metrics.find((x) => x.id === metricId);
                if (!m) return null;
                const condData = applyConditionFilters(rawData, cond.filters, filterFields);
                const val = aggregateValues(condData, metricId, cond.aggMethod);
                const color = COLORS[ci % COLORS.length];
                return (
                  <div
                    key={`${cond.id}-${metricId}`}
                    className="rounded-lg border p-4"
                    style={{ borderTopColor: color, borderTopWidth: 3 }}
                  >
                    <p className="truncate text-xs text-muted-foreground">
                      {cond.name} · {m.name} ({aggLabel(cond.aggMethod)})
                    </p>
                    <p className="mt-1 text-xl font-bold tabular-nums">
                      {formatNumber(val)}
                      <span className="ml-1 text-xs font-normal text-muted-foreground">
                        {cond.aggMethod === "count" ? "건" : m.unit}
                      </span>
                    </p>
                  </div>
                );
              })
            )}
          </div>
        )}

        {/* 차트 */}
        {analysisResult.chartData.length > 0 && (
          <div className="rounded-md border p-4">
            <h3 className="mb-4 text-sm font-semibold">분석 차트</h3>
            <div style={{ width: "100%", height: 400 }}>
              <ResponsiveContainer>
                {(() => {
                  const firstChartType = conditions[0]?.chartType || "bar";
                  const dataKeys = analysisResult.series.map(
                    (s) => `${s.condName}_${s.metricName}`
                  );

                  if (firstChartType === "line") {
                    return (
                      <LineChart data={analysisResult.chartData}>
                        <CartesianGrid strokeDasharray="3 3" className="stroke-border" />
                        <XAxis dataKey="name" tick={{ fontSize: 12 }} className="fill-muted-foreground" />
                        <YAxis tick={{ fontSize: 12 }} className="fill-muted-foreground" tickFormatter={(v) => v.toLocaleString()} />
                        <Tooltip content={<ChartTooltip />} />
                        <Legend wrapperStyle={{ fontSize: 12 }} />
                        {dataKeys.map((key, i) => (
                          <Line
                            key={key}
                            type="monotone"
                            dataKey={key}
                            stroke={COLORS[i % COLORS.length]}
                            strokeWidth={2}
                            dot={{ r: 4 }}
                          />
                        ))}
                      </LineChart>
                    );
                  }

                  if (firstChartType === "area") {
                    return (
                      <AreaChart data={analysisResult.chartData}>
                        <CartesianGrid strokeDasharray="3 3" className="stroke-border" />
                        <XAxis dataKey="name" tick={{ fontSize: 12 }} className="fill-muted-foreground" />
                        <YAxis tick={{ fontSize: 12 }} className="fill-muted-foreground" tickFormatter={(v) => v.toLocaleString()} />
                        <Tooltip content={<ChartTooltip />} />
                        <Legend wrapperStyle={{ fontSize: 12 }} />
                        {dataKeys.map((key, i) => (
                          <Area
                            key={key}
                            type="monotone"
                            dataKey={key}
                            stroke={COLORS[i % COLORS.length]}
                            fill={COLORS[i % COLORS.length]}
                            fillOpacity={0.3}
                          />
                        ))}
                      </AreaChart>
                    );
                  }

                  return (
                    <BarChart data={analysisResult.chartData}>
                      <CartesianGrid strokeDasharray="3 3" className="stroke-border" />
                      <XAxis dataKey="name" tick={{ fontSize: 12 }} className="fill-muted-foreground" />
                      <YAxis tick={{ fontSize: 12 }} className="fill-muted-foreground" tickFormatter={(v) => v.toLocaleString()} />
                      <Tooltip content={<ChartTooltip />} cursor={{ fill: "hsl(var(--muted))", opacity: 0.3 }} />
                      <Legend wrapperStyle={{ fontSize: 12 }} />
                      {dataKeys.map((key, i) => (
                        <Bar
                          key={key}
                          dataKey={key}
                          fill={COLORS[i % COLORS.length]}
                          radius={[4, 4, 0, 0]}
                        />
                      ))}
                    </BarChart>
                  );
                })()}
              </ResponsiveContainer>
            </div>
          </div>
        )}

        {/* 집계 데이터 */}
        {analysisResult.series.length > 0 && (
          <div className="rounded-md border">
            <div className="flex items-center justify-between border-b p-3">
              <h3 className="text-sm font-semibold">집계 데이터</h3>
              <div className="flex rounded-md border">
                <button
                  onClick={() => setViewMode("table")}
                  className={cn(
                    "px-3 py-1 text-xs",
                    viewMode === "table" && "bg-primary text-primary-foreground"
                  )}
                >
                  테이블
                </button>
                <button
                  onClick={() => setViewMode("card")}
                  className={cn(
                    "px-3 py-1 text-xs",
                    viewMode === "card" && "bg-primary text-primary-foreground"
                  )}
                >
                  카드
                </button>
              </div>
            </div>

            <div className="p-3">
              {viewMode === "table" ? (
                <div className="overflow-x-auto">
                  <table className="w-full text-sm">
                    <thead>
                      <tr className="border-b">
                        <th className="p-2 text-left text-xs font-medium text-muted-foreground">
                          {config.groupByOptions.find((o) => o.id === groupBy)?.name}
                        </th>
                        {analysisResult.series.map((s, si) => (
                          <th
                            key={si}
                            className="p-2 text-right text-xs font-medium"
                            style={{ borderBottomColor: COLORS[si % COLORS.length], borderBottomWidth: 2 }}
                          >
                            {s.condName}
                            <br />
                            <span className="font-normal text-muted-foreground">
                              {s.metricName}({aggLabel(s.aggMethod)})
                            </span>
                          </th>
                        ))}
                      </tr>
                    </thead>
                    <tbody>
                      {analysisResult.labels.map((label) => (
                        <tr
                          key={label}
                          className="cursor-pointer border-b transition-colors hover:bg-muted/50"
                          onClick={() => setDrilldownLabel(label)}
                        >
                          <td className="p-2 font-medium">{label}</td>
                          {analysisResult.series.map((s, si) => (
                            <td key={si} className="p-2 text-right tabular-nums">
                              {formatNumber(
                                aggregateValues(s.groups[label] || [], s.metricId, s.aggMethod)
                              )}
                            </td>
                          ))}
                        </tr>
                      ))}
                      <tr className="border-t-2 bg-muted/30 font-bold">
                        <td className="p-2">전체</td>
                        {analysisResult.series.map((s, si) => {
                          const allRows = analysisResult.labels.flatMap(
                            (lb) => s.groups[lb] || []
                          );
                          return (
                            <td key={si} className="p-2 text-right tabular-nums">
                              {formatNumber(aggregateValues(allRows, s.metricId, s.aggMethod))}
                            </td>
                          );
                        })}
                      </tr>
                    </tbody>
                  </table>
                </div>
              ) : (
                <div className="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3">
                  {analysisResult.labels.map((label) => {
                    const firstS = analysisResult.series[0];
                    const val = firstS
                      ? aggregateValues(firstS.groups[label] || [], firstS.metricId, firstS.aggMethod)
                      : 0;
                    return (
                      <div
                        key={label}
                        className="cursor-pointer rounded-lg border p-4 transition-shadow hover:shadow-md"
                        onClick={() => setDrilldownLabel(label)}
                      >
                        <p className="text-sm font-medium">{label}</p>
                        <p className="mt-1 text-xl font-bold tabular-nums">
                          {formatNumber(val)}
                          <span className="ml-1 text-xs font-normal text-muted-foreground">
                            {firstS?.metricUnit}
                          </span>
                        </p>
                        {analysisResult.series.length > 1 && (
                          <p className="mt-1 truncate text-xs text-muted-foreground">
                            {analysisResult.series.slice(1).map((s) => {
                              const v = aggregateValues(s.groups[label] || [], s.metricId, s.aggMethod);
                              return `${s.condName}-${s.metricName}: ${formatNumber(v)}`;
                            }).join(" | ")}
                          </p>
                        )}
                      </div>
                    );
                  })}
                </div>
              )}
            </div>
          </div>
        )}

        {/* 드릴다운 */}
        {drilldownLabel && (
          <div className="rounded-md border border-primary/30 bg-primary/5">
            <div className="flex items-center justify-between border-b p-3">
              <h3 className="text-sm font-semibold">{drilldownLabel} 상세</h3>
              <button
                onClick={() => setDrilldownLabel(null)}
                className="rounded p-1 text-sm hover:bg-muted"
              >
                X
              </button>
            </div>
            <div className="overflow-x-auto p-3">
              <table className="w-full text-sm">
                <thead>
                  <tr className="border-b">
                    {config.drilldownColumns.map((col) => (
                      <th
                        key={col.id}
                        className={cn("p-2 text-xs", col.align === "right" ? "text-right" : "text-left")}
                      >
                        {col.name}
                      </th>
                    ))}
                  </tr>
                </thead>
                <tbody>
                  {rawData
                    .filter((d) => getGroupKey(d, groupBy) === drilldownLabel)
                    .map((r, i) => (
                      <tr key={i} className="border-b">
                        {config.drilldownColumns.map((col) => (
                          <td
                            key={col.id}
                            className={cn(
                              "p-2 text-xs",
                              col.align === "right" ? "text-right tabular-nums" : ""
                            )}
                          >
                            {renderCellValue(r, col)}
                          </td>
                        ))}
                      </tr>
                    ))}
                </tbody>
              </table>
            </div>
          </div>
        )}

        {/* 원본 데이터 */}
        <div className="rounded-md border">
          <button
            className="flex w-full items-center justify-between p-3 text-left hover:bg-muted/50"
            onClick={() => setRawDataOpen(!rawDataOpen)}
          >
            <span className="text-sm font-semibold">백 데이터 (원본)</span>
            <span className={cn("text-xs transition-transform", !rawDataOpen && "-rotate-90")}>
              ▼
            </span>
          </button>
          {rawDataOpen && (
            <div className="overflow-x-auto border-t p-3">
              <table className="w-full text-sm">
                <thead>
                  <tr className="border-b">
                    {config.rawDataColumns.map((col) => (
                      <th
                        key={col.id}
                        className={cn("p-2 text-xs", col.align === "right" ? "text-right" : "text-left")}
                      >
                        {col.name}
                      </th>
                    ))}
                  </tr>
                </thead>
                <tbody>
                  {rawData.slice(0, 100).map((r, i) => (
                    <tr key={i} className="border-b">
                      {config.rawDataColumns.map((col) => (
                        <td
                          key={col.id}
                          className={cn(
                            "p-2 text-xs",
                            col.align === "right" ? "text-right tabular-nums" : ""
                          )}
                        >
                          {renderCellValue(r, col)}
                        </td>
                      ))}
                    </tr>
                  ))}
                </tbody>
              </table>
              {rawData.length > 100 && (
                <p className="mt-2 text-center text-xs text-muted-foreground">
                  상위 100건만 표시 (전체 {rawData.length}건)
                </p>
              )}
            </div>
          )}
        </div>

        {/* 데이터 없음 */}
        {!isLoading && rawData.length === 0 && (
          <div className="flex flex-col items-center justify-center py-16 text-center">
            <div className="mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-muted">
              <svg className="h-8 w-8 text-muted-foreground" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5}
                  d="M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
                />
              </svg>
            </div>
            <h3 className="text-lg font-semibold">{config.emptyMessage}</h3>
            <p className="mt-1 text-sm text-muted-foreground">
              기간을 변경하거나 데이터를 확인해주세요
            </p>
          </div>
        )}
      </div>

      {/* 프리셋 저장 모달 */}
      <Dialog open={presetModalOpen} onOpenChange={setPresetModalOpen}>
        <DialogContent className="max-w-[95vw] sm:max-w-[500px]">
          <DialogHeader>
            <DialogTitle className="text-base sm:text-lg">조건 저장</DialogTitle>
          </DialogHeader>
          <div className="space-y-3">
            <div>
              <Label className="text-xs sm:text-sm">
                조건명 <span className="text-destructive">*</span>
              </Label>
              <Input
                value={presetName}
                onChange={(e) => setPresetName(e.target.value)}
                placeholder="예: 월별 추이 분석"
                className="h-8 text-xs sm:h-10 sm:text-sm"
              />
            </div>
            <div>
              <Label className="text-xs sm:text-sm">설명</Label>
              <Input
                value={presetDesc}
                onChange={(e) => setPresetDesc(e.target.value)}
                placeholder="조건 설명 (선택사항)"
                className="h-8 text-xs sm:h-10 sm:text-sm"
              />
            </div>
          </div>
          <DialogFooter className="gap-2 sm:gap-0">
            <Button
              variant="outline"
              onClick={() => setPresetModalOpen(false)}
              className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
            >
              취소
            </Button>
            <Button
              onClick={savePreset}
              className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
            >
              저장
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <ScrollToTop />
    </div>
  );
}
