"use client";

import React, { useState, useCallback, useEffect } from "react";
import { ChartConfig, QueryResult } from "./types";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { Checkbox } from "@/components/ui/checkbox";
import { Separator } from "@/components/ui/separator";
import { AlertCircle } from "lucide-react";
import { DateFilterPanel } from "./DateFilterPanel";
import { extractTableNameFromQuery } from "./utils/queryHelpers";
import { dashboardApi } from "@/lib/api/dashboard";

interface ChartConfigPanelProps {
  config?: ChartConfig;
  queryResult?: QueryResult;
  onConfigChange: (config: ChartConfig) => void;
  chartType?: string;
  dataSourceType?: "database" | "api"; // 데이터 소스 타입
  query?: string; // SQL 쿼리 (테이블명 추출용)
}

/**
 * 차트 설정 패널 컴포넌트
 * - 데이터 필드 매핑 설정
 * - 차트 스타일 설정
 * - 실시간 미리보기
 */
export function ChartConfigPanel({
  config,
  queryResult,
  onConfigChange,
  chartType,
  dataSourceType,
  query,
}: ChartConfigPanelProps) {
  const [currentConfig, setCurrentConfig] = useState<ChartConfig>(config || {});
  const [dateColumns, setDateColumns] = useState<string[]>([]);

  // 원형/도넛 차트 또는 REST API는 Y축이 필수가 아님
  const isPieChart = chartType === "pie" || chartType === "donut";
  const isApiSource = dataSourceType === "api";

  // 설정 업데이트
  const updateConfig = useCallback(
    (updates: Partial<ChartConfig>) => {
      const newConfig = { ...currentConfig, ...updates };
      setCurrentConfig(newConfig);
      onConfigChange(newConfig);
    },
    [currentConfig, onConfigChange],
  );

  // 사용 가능한 컬럼 목록 및 타입 정보
  const availableColumns = queryResult?.columns || [];
  const columnTypes = queryResult?.columnTypes || {};
  const sampleData = queryResult?.rows?.[0] || {};

  // 차트에 사용 가능한 컬럼 필터링
  const simpleColumns = availableColumns.filter((col) => {
    const type = columnTypes[col];
    // number, string, boolean만 허용 (object, array는 제외)
    return !type || type === "number" || type === "string" || type === "boolean";
  });

  // 숫자 타입 컬럼만 필터링 (Y축용)
  const numericColumns = availableColumns.filter((col) => columnTypes[col] === "number");

  // 복잡한 타입의 컬럼 (경고 표시용)
  const complexColumns = availableColumns.filter((col) => {
    const type = columnTypes[col];
    return type === "object" || type === "array";
  });

  // 테이블 스키마에서 실제 날짜 컬럼 가져오기
  useEffect(() => {
    if (!query || !queryResult || dataSourceType === "api") {
      // API 소스는 스키마 조회 불가
      setDateColumns([]);
      return;
    }

    const tableName = extractTableNameFromQuery(query);

    if (!tableName) {
      setDateColumns([]);
      return;
    }
    dashboardApi
      .getTableSchema(tableName)
      .then((schema) => {
        // 원본 테이블의 모든 날짜 컬럼을 표시
        // (SELECT에 없어도 WHERE 절에 사용 가능)
        setDateColumns(schema.dateColumns);
      })
      .catch(() => {
        // 실패 시 빈 배열 (날짜 필터 비활성화)
        setDateColumns([]);
      });
  }, [query, queryResult, dataSourceType]);

  return (
    <div className="space-y-3">
      {/* 데이터 필드 매핑 */}
      {queryResult && (
        <>
          {/* 복잡한 타입 경고 */}
          {complexColumns.length > 0 && (
            <Alert variant="destructive">
              <AlertCircle className="h-4 w-4" />
              <AlertDescription>
                <div className="font-semibold">차트에 사용할 수 없는 컬럼 감지</div>
                <div className="mt-1 text-sm">
                  다음 컬럼은 객체 또는 배열 타입이라서 차트 축으로 선택할 수 없습니다:
                  <div className="mt-1 flex flex-wrap gap-1">
                    {complexColumns.map((col) => (
                      <Badge key={col} variant="outline" className="bg-red-50">
                        {col} ({columnTypes[col]})
                      </Badge>
                    ))}
                  </div>
                </div>
                <div className="mt-2 text-xs text-gray-600">
                  <strong>해결 방법:</strong> JSON Path를 사용하여 중첩된 객체 내부의 값을 직접 추출하세요.
                  <br />
                  예: <code className="rounded bg-gray-100 px-1">main</code> 또는{" "}
                  <code className="rounded bg-gray-100 px-1">data.items</code>
                </div>
              </AlertDescription>
            </Alert>
          )}

          {/* 차트 제목 */}
          <div className="space-y-1.5">
            <Label className="text-xs font-medium text-gray-700">차트 제목</Label>
            <Input
              type="text"
              value={currentConfig.title || ""}
              onChange={(e) => updateConfig({ title: e.target.value })}
              placeholder="차트 제목을 입력하세요"
              className="h-8 text-xs"
            />
          </div>

          <Separator />

          {/* X축 설정 */}
          <div className="space-y-1.5">
            <Label className="text-xs font-medium text-gray-700">
              X축 (카테고리)
              <span className="ml-1 text-red-500">*</span>
            </Label>
            <Select value={currentConfig.xAxis || undefined} onValueChange={(value) => updateConfig({ xAxis: value })}>
              <SelectTrigger className="h-8 text-xs">
                <SelectValue placeholder="선택하세요" />
              </SelectTrigger>
              <SelectContent className="z-[99999]">
                {simpleColumns.map((col) => {
                  const preview = sampleData[col];
                  const previewText =
                    preview !== undefined && preview !== null
                      ? typeof preview === "object"
                        ? JSON.stringify(preview).substring(0, 30)
                        : String(preview).substring(0, 30)
                      : "";

                  return (
                    <SelectItem key={col} value={col} className="text-xs">
                      {col}
                      {previewText && <span className="ml-1.5 text-[10px] text-gray-500">(예: {previewText})</span>}
                    </SelectItem>
                  );
                })}
              </SelectContent>
            </Select>
            {simpleColumns.length === 0 && (
              <p className="text-[11px] text-red-500">사용 가능한 컬럼이 없습니다. JSON Path를 확인하세요.</p>
            )}
          </div>

          {/* Y축 설정 (다중 선택 가능) */}
          <div className="space-y-1.5">
            <Label className="text-xs font-medium text-gray-700">
              Y축 (값) - 여러 개 선택 가능
              {!isPieChart && !isApiSource && <span className="ml-1 text-red-500">*</span>}
              {(isPieChart || isApiSource) && (
                <span className="ml-1.5 text-[11px] text-gray-500">(선택사항 - 그룹핑+집계 사용 가능)</span>
              )}
            </Label>
            <div className="max-h-48 overflow-y-auto rounded border border-gray-200 bg-gray-50 p-2">
              <div className="space-y-1.5">
                {/* 숫자 타입 우선 표시 */}
                {numericColumns.length > 0 && (
                  <>
                    <div className="mb-1.5 text-[11px] font-medium text-green-700">숫자 타입 (권장)</div>
                    {numericColumns.map((col) => {
                      const isSelected = Array.isArray(currentConfig.yAxis)
                        ? currentConfig.yAxis.includes(col)
                        : currentConfig.yAxis === col;

                      return (
                        <div key={col} className="flex items-center gap-1.5 rounded border-green-500 bg-green-50 p-1.5">
                          <Checkbox
                            checked={isSelected}
                            onCheckedChange={(checked) => {
                              const currentYAxis = Array.isArray(currentConfig.yAxis)
                                ? currentConfig.yAxis
                                : currentConfig.yAxis
                                  ? [currentConfig.yAxis]
                                  : [];

                              let newYAxis: string | string[];
                              if (checked) {
                                newYAxis = [...currentYAxis, col];
                              } else {
                                newYAxis = currentYAxis.filter((c) => c !== col);
                              }

                              if (newYAxis.length === 1) {
                                newYAxis = newYAxis[0];
                              }

                              updateConfig({ yAxis: newYAxis });
                            }}
                          />
                          <Label className="flex-1 cursor-pointer text-xs font-normal">
                            <span className="font-medium">{col}</span>
                            {sampleData[col] !== undefined && (
                              <span className="ml-1.5 text-[10px] text-gray-600">(예: {sampleData[col]})</span>
                            )}
                          </Label>
                        </div>
                      );
                    })}
                  </>
                )}

                {/* 기타 간단한 타입 */}
                {simpleColumns.filter((col) => !numericColumns.includes(col)).length > 0 && (
                  <>
                    {numericColumns.length > 0 && <div className="my-1.5 border-t"></div>}
                    <div className="mb-1.5 text-[11px] font-medium text-gray-600">기타 타입</div>
                    {simpleColumns
                      .filter((col) => !numericColumns.includes(col))
                      .map((col) => {
                        const isSelected = Array.isArray(currentConfig.yAxis)
                          ? currentConfig.yAxis.includes(col)
                          : currentConfig.yAxis === col;

                        return (
                          <div key={col} className="flex items-center gap-1.5 rounded p-1.5 hover:bg-gray-50">
                            <Checkbox
                              checked={isSelected}
                              onCheckedChange={(checked) => {
                                const currentYAxis = Array.isArray(currentConfig.yAxis)
                                  ? currentConfig.yAxis
                                  : currentConfig.yAxis
                                    ? [currentConfig.yAxis]
                                    : [];

                                let newYAxis: string | string[];
                                if (checked) {
                                  newYAxis = [...currentYAxis, col];
                                } else {
                                  newYAxis = currentYAxis.filter((c) => c !== col);
                                }

                                if (newYAxis.length === 1) {
                                  newYAxis = newYAxis[0];
                                }

                                updateConfig({ yAxis: newYAxis });
                              }}
                            />
                            <Label className="flex-1 cursor-pointer text-xs font-normal">
                              {col}
                              {sampleData[col] !== undefined && (
                                <span className="ml-1.5 text-[10px] text-gray-500">
                                  (예: {String(sampleData[col]).substring(0, 30)})
                                </span>
                              )}
                            </Label>
                          </div>
                        );
                      })}
                  </>
                )}
              </div>
            </div>
            {simpleColumns.length === 0 && (
              <p className="text-[11px] text-red-500">사용 가능한 컬럼이 없습니다. JSON Path를 확인하세요.</p>
            )}
            <p className="text-[11px] text-gray-500">
              팁: 여러 항목을 선택하면 비교 차트가 생성됩니다 (예: 갤럭시 vs 아이폰)
            </p>
          </div>

          <Separator />

          {/* 집계 함수 */}
          <div className="space-y-1.5">
            <Label className="text-xs font-medium text-gray-700">
              집계 함수
              <span className="ml-1.5 text-[11px] text-gray-500">(데이터 처리 방식)</span>
            </Label>
            <Select
              value={currentConfig.aggregation || "none"}
              onValueChange={(value) =>
                updateConfig({
                  aggregation: value === "none" ? undefined : (value as "sum" | "avg" | "count" | "max" | "min"),
                })
              }
            >
              <SelectTrigger className="h-8 text-xs">
                <SelectValue />
              </SelectTrigger>
              <SelectContent className="z-[99999]">
                <SelectItem value="none" className="text-xs">
                  없음 - SQL에서 집계됨
                </SelectItem>
                <SelectItem value="sum" className="text-xs">
                  합계 (SUM) - 모든 값을 더함
                </SelectItem>
                <SelectItem value="avg" className="text-xs">
                  평균 (AVG) - 평균값 계산
                </SelectItem>
                <SelectItem value="count" className="text-xs">
                  개수 (COUNT) - 데이터 개수
                </SelectItem>
                <SelectItem value="max" className="text-xs">
                  최대값 (MAX) - 가장 큰 값
                </SelectItem>
                <SelectItem value="min" className="text-xs">
                  최소값 (MIN) - 가장 작은 값
                </SelectItem>
              </SelectContent>
            </Select>
            <p className="text-[11px] text-gray-500">
              그룹핑 필드와 함께 사용하면 자동으로 데이터를 집계합니다. (예: 부서별 개수, 월별 합계)
            </p>
          </div>

          {/* 그룹핑 필드 (선택사항) */}
          <div className="space-y-1.5">
            <Label className="text-xs font-medium text-gray-700">
              그룹핑 필드 (선택사항)
              <span className="ml-1.5 text-[11px] text-gray-500">(같은 값끼리 묶어서 집계)</span>
            </Label>
            <Select
              value={currentConfig.groupBy || undefined}
              onValueChange={(value) => updateConfig({ groupBy: value })}
            >
              <SelectTrigger className="h-8 text-xs">
                <SelectValue placeholder="없음" />
              </SelectTrigger>
              <SelectContent className="z-[99999]">
                <SelectItem value="__none__" className="text-xs">
                  없음
                </SelectItem>
                {availableColumns.map((col) => (
                  <SelectItem key={col} value={col} className="text-xs">
                    {col}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <Separator />

          {/* 차트 색상 */}
          <div className="space-y-1.5">
            <Label className="text-xs font-medium text-gray-700">차트 색상</Label>
            <div className="grid grid-cols-4 gap-2">
              {[
                ["#3B82F6", "#EF4444", "#10B981", "#F59E0B"], // 기본
                ["#8B5CF6", "#EC4899", "#06B6D4", "#84CC16"], // 밝은
                ["#1F2937", "#374151", "#6B7280", "#9CA3AF"], // 회색
                ["#DC2626", "#EA580C", "#CA8A04", "#65A30D"], // 따뜻한
              ].map((colorSet, setIdx) => (
                <button
                  key={setIdx}
                  type="button"
                  onClick={() => updateConfig({ colors: colorSet })}
                  className={`flex h-8 rounded border-2 transition-colors ${
                    JSON.stringify(currentConfig.colors) === JSON.stringify(colorSet)
                      ? "border-gray-800"
                      : "border-gray-300 hover:border-gray-400"
                  }`}
                >
                  {colorSet.map((color, idx) => (
                    <div
                      key={idx}
                      className="flex-1 first:rounded-l last:rounded-r"
                      style={{ backgroundColor: color }}
                    />
                  ))}
                </button>
              ))}
            </div>
          </div>

          {/* 범례 표시 */}
          <div className="flex items-center gap-2">
            <Checkbox
              id="showLegend"
              checked={currentConfig.showLegend !== false}
              onCheckedChange={(checked) => updateConfig({ showLegend: checked as boolean })}
            />
            <Label htmlFor="showLegend" className="cursor-pointer font-normal">
              범례 표시
            </Label>
          </div>

          <Separator />

          {/* 날짜 필터 */}
          {dateColumns.length > 0 && (
            <DateFilterPanel config={currentConfig} dateColumns={dateColumns} onChange={updateConfig} />
          )}

          {/* 필수 필드 확인 */}
          {!currentConfig.xAxis && (
            <Alert variant="destructive">
              <AlertCircle className="h-4 w-4" />
              <AlertDescription>X축은 필수입니다.</AlertDescription>
            </Alert>
          )}
          {!isPieChart && !isApiSource && !currentConfig.yAxis && (
            <Alert variant="destructive">
              <AlertCircle className="h-4 w-4" />
              <AlertDescription>Y축을 설정해야 차트가 표시됩니다.</AlertDescription>
            </Alert>
          )}
          {(isPieChart || isApiSource) && !currentConfig.yAxis && !currentConfig.aggregation && (
            <Alert variant="destructive">
              <AlertCircle className="h-4 w-4" />
              <AlertDescription>Y축 또는 집계 함수(COUNT 등)를 설정해야 차트가 표시됩니다.</AlertDescription>
            </Alert>
          )}
        </>
      )}
    </div>
  );
}
