"use client";

import React, { useState } from "react";
import { DashboardElement, CustomMetricConfig } from "@/components/admin/dashboard/types";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { GripVertical, Plus, Trash2, ChevronDown, ChevronUp, X } from "lucide-react";
import { DatabaseConfig } from "../../data-sources/DatabaseConfig";
import { ChartDataSource } from "../../types";
import { ApiConfig } from "../../data-sources/ApiConfig";
import { QueryEditor } from "../../QueryEditor";
import { v4 as uuidv4 } from "uuid";
import { cn } from "@/lib/utils";

interface CustomMetricConfigSidebarProps {
  element: DashboardElement;
  isOpen: boolean;
  onClose: () => void;
  onApply: (updates: Partial<DashboardElement>) => void;
}

export default function CustomMetricConfigSidebar({
  element,
  isOpen,
  onClose,
  onApply,
}: CustomMetricConfigSidebarProps) {
  const [metrics, setMetrics] = useState<CustomMetricConfig["metrics"]>(element.customMetricConfig?.metrics || []);
  const [expandedMetric, setExpandedMetric] = useState<string | null>(null);
  const [queryColumns, setQueryColumns] = useState<string[]>([]);
  const [dataSourceType, setDataSourceType] = useState<"database" | "api">(element.dataSource?.type || "database");
  const [dataSource, setDataSource] = useState<ChartDataSource>(
    element.dataSource || { type: "database", connectionType: "current", refreshInterval: 0 },
  );
  const [draggedIndex, setDraggedIndex] = useState<number | null>(null);
  const [dragOverIndex, setDragOverIndex] = useState<number | null>(null);
  const [customTitle, setCustomTitle] = useState<string>(element.customTitle || element.title || "");
  const [showHeader, setShowHeader] = useState<boolean>(element.showHeader !== false);

  // 쿼리 실행 결과 처리
  const handleQueryTest = (result: any) => {
    // QueryEditor에서 오는 경우: { success: true, data: { columns: [...], rows: [...] } }
    if (result.success && result.data?.columns) {
      setQueryColumns(result.data.columns);
    }
    // ApiConfig에서 오는 경우: { columns: [...], data: [...] } 또는 { success: true, columns: [...] }
    else if (result.columns && Array.isArray(result.columns)) {
      setQueryColumns(result.columns);
    }
    // 오류 처리
    else {
      setQueryColumns([]);
    }
  };

  // 메트릭 추가
  const addMetric = () => {
    const newMetric = {
      id: uuidv4(),
      field: "",
      label: "새 지표",
      aggregation: "count" as const,
      unit: "",
      color: "gray" as const,
      decimals: 1,
    };
    setMetrics([...metrics, newMetric]);
    setExpandedMetric(newMetric.id);
  };

  // 메트릭 삭제
  const deleteMetric = (id: string) => {
    setMetrics(metrics.filter((m) => m.id !== id));
    if (expandedMetric === id) {
      setExpandedMetric(null);
    }
  };

  // 메트릭 업데이트
  const updateMetric = (id: string, field: string, value: any) => {
    setMetrics(metrics.map((m) => (m.id === id ? { ...m, [field]: value } : m)));
  };

  // 메트릭 순서 변경
  // 드래그 앤 드롭 핸들러
  const handleDragStart = (index: number) => {
    setDraggedIndex(index);
  };

  const handleDragOver = (e: React.DragEvent, index: number) => {
    e.preventDefault();
    setDragOverIndex(index);
  };

  const handleDrop = (e: React.DragEvent, dropIndex: number) => {
    e.preventDefault();
    if (draggedIndex === null || draggedIndex === dropIndex) {
      setDraggedIndex(null);
      setDragOverIndex(null);
      return;
    }

    const newMetrics = [...metrics];
    const [draggedItem] = newMetrics.splice(draggedIndex, 1);
    newMetrics.splice(dropIndex, 0, draggedItem);

    setMetrics(newMetrics);
    setDraggedIndex(null);
    setDragOverIndex(null);
  };

  const handleDragEnd = () => {
    setDraggedIndex(null);
    setDragOverIndex(null);
  };

  // 데이터 소스 업데이트
  const handleDataSourceUpdate = (updates: Partial<ChartDataSource>) => {
    const newDataSource = { ...dataSource, ...updates };
    setDataSource(newDataSource);
    onApply({ dataSource: newDataSource });
  };

  // 데이터 소스 타입 변경
  const handleDataSourceTypeChange = (type: "database" | "api") => {
    setDataSourceType(type);
    const newDataSource: ChartDataSource =
      type === "database"
        ? { type: "database", connectionType: "current", refreshInterval: 0 }
        : { type: "api", method: "GET", refreshInterval: 0 };

    setDataSource(newDataSource);
    onApply({ dataSource: newDataSource });
    setQueryColumns([]);
  };

  // 저장
  const handleSave = () => {
    onApply({
      customTitle: customTitle,
      showHeader: showHeader,
      customMetricConfig: {
        metrics,
      },
    });
  };

  if (!isOpen) return null;

  return (
    <div
      className={cn(
        "fixed top-14 left-0 z-[100] flex h-[calc(100vh-3.5rem)] w-80 flex-col bg-gray-50 transition-transform duration-300 ease-in-out",
        isOpen ? "translate-x-0" : "translate-x-[-100%]",
      )}
    >
      {/* 헤더 */}
      <div className="flex items-center justify-between bg-white px-3 py-2 shadow-sm">
        <div className="flex items-center gap-2">
          <div className="bg-primary/10 flex h-6 w-6 items-center justify-center rounded">
            <span className="text-primary text-xs font-bold">📊</span>
          </div>
          <span className="text-xs font-semibold text-gray-900">커스텀 카드 설정</span>
        </div>
        <button
          onClick={onClose}
          className="flex h-6 w-6 items-center justify-center rounded transition-colors hover:bg-gray-100"
        >
          <X className="h-3.5 w-3.5 text-gray-500" />
        </button>
      </div>

      {/* 본문: 스크롤 가능 영역 */}
      <div className="flex-1 overflow-y-auto p-3">
        <div className="space-y-3">
          {/* 헤더 설정 */}
          <div className="rounded-lg bg-white p-3 shadow-sm">
            <div className="mb-2 text-[10px] font-semibold tracking-wide text-gray-500 uppercase">헤더 설정</div>
            <div className="space-y-2">
              {/* 제목 입력 */}
              <div>
                <label className="mb-0.5 block text-[9px] font-medium text-gray-500">제목</label>
                <Input
                  value={customTitle}
                  onChange={(e) => setCustomTitle(e.target.value)}
                  placeholder="위젯 제목을 입력하세요"
                  className="h-8 text-xs"
                  style={{ fontSize: "12px" }}
                />
              </div>

              {/* 헤더 표시 여부 */}
              <div className="flex items-center justify-between">
                <label className="text-[9px] font-medium text-gray-500">헤더 표시</label>
                <button
                  onClick={() => setShowHeader(!showHeader)}
                  className={`relative inline-flex h-5 w-9 items-center rounded-full transition-colors ${
                    showHeader ? "bg-primary" : "bg-gray-300"
                  }`}
                >
                  <span
                    className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
                      showHeader ? "translate-x-5" : "translate-x-0.5"
                    }`}
                  />
                </button>
              </div>
            </div>
          </div>

          {/* 데이터 소스 타입 선택 */}
          <div className="rounded-lg bg-white p-3 shadow-sm">
            <div className="mb-2 text-[10px] font-semibold tracking-wide text-gray-500 uppercase">데이터 소스 타입</div>
            <div className="grid grid-cols-2 gap-2">
              <button
                onClick={() => handleDataSourceTypeChange("database")}
                className={`flex h-16 items-center justify-center rounded border transition-all ${
                  dataSourceType === "database"
                    ? "border-primary bg-primary/5 text-primary"
                    : "border-gray-200 bg-gray-50 text-gray-600 hover:border-gray-300"
                }`}
              >
                <span className="text-sm font-medium">데이터베이스</span>
              </button>
              <button
                onClick={() => handleDataSourceTypeChange("api")}
                className={`flex h-16 items-center justify-center rounded border transition-all ${
                  dataSourceType === "api"
                    ? "border-primary bg-primary/5 text-primary"
                    : "border-gray-200 bg-gray-50 text-gray-600 hover:border-gray-300"
                }`}
              >
                <span className="text-sm font-medium">REST API</span>
              </button>
            </div>
          </div>

          {/* 데이터 소스 설정 */}
          {dataSourceType === "database" ? (
            <>
              <DatabaseConfig dataSource={dataSource} onChange={handleDataSourceUpdate} />
              <QueryEditor
                dataSource={dataSource}
                onDataSourceChange={handleDataSourceUpdate}
                onQueryTest={handleQueryTest}
              />
            </>
          ) : (
            <ApiConfig dataSource={dataSource} onChange={handleDataSourceUpdate} onTestResult={handleQueryTest} />
          )}

          {/* 지표 설정 섹션 - 쿼리 실행 후에만 표시 */}
          {queryColumns.length > 0 && (
            <div className="rounded-lg bg-white p-3 shadow-sm">
              <div className="mb-3 flex items-center justify-between">
                <div className="text-[10px] font-semibold tracking-wide text-gray-500 uppercase">지표</div>
                <Button size="sm" variant="outline" className="h-7 gap-1 text-xs" onClick={addMetric}>
                  <Plus className="h-3 w-3" />
                  추가
                </Button>
              </div>

              <div className="space-y-2">
                {metrics.length === 0 ? (
                  <p className="text-xs text-gray-500">추가된 지표가 없습니다</p>
                ) : (
                  metrics.map((metric, index) => (
                    <div
                      key={metric.id}
                      onDragOver={(e) => handleDragOver(e, index)}
                      onDrop={(e) => handleDrop(e, index)}
                      className={cn(
                        "rounded-md border bg-white p-2 transition-all",
                        draggedIndex === index && "opacity-50",
                        dragOverIndex === index && draggedIndex !== index && "border-primary border-2",
                      )}
                    >
                      {/* 헤더 */}
                      <div className="flex w-full items-center gap-2">
                        <div
                          draggable
                          onDragStart={() => handleDragStart(index)}
                          onDragEnd={handleDragEnd}
                          className="cursor-grab active:cursor-grabbing"
                        >
                          <GripVertical className="h-4 w-4 shrink-0 text-gray-400" />
                        </div>
                        <div className="grid min-w-0 flex-1 grid-cols-[1fr,auto,auto] items-center gap-2">
                          <span className="truncate text-xs font-medium text-gray-900">
                            {metric.label || "새 지표"}
                          </span>
                          <span className="text-[10px] text-gray-500">{metric.aggregation.toUpperCase()}</span>
                          <button
                            onClick={() => setExpandedMetric(expandedMetric === metric.id ? null : metric.id)}
                            className="flex items-center justify-center rounded p-0.5 hover:bg-gray-100"
                          >
                            {expandedMetric === metric.id ? (
                              <ChevronUp className="h-3.5 w-3.5 text-gray-500" />
                            ) : (
                              <ChevronDown className="h-3.5 w-3.5 text-gray-500" />
                            )}
                          </button>
                        </div>
                      </div>

                      {/* 설정 영역 */}
                      {expandedMetric === metric.id && (
                        <div className="mt-2 space-y-1.5 border-t border-gray-200 pt-2">
                          {/* 2열 그리드 레이아웃 */}
                          <div className="grid grid-cols-2 gap-1.5">
                            {/* 컬럼 */}
                            <div>
                              <label className="mb-0.5 block text-[9px] font-medium text-gray-500">컬럼</label>
                              <Select
                                value={metric.field}
                                onValueChange={(value) => updateMetric(metric.id, "field", value)}
                              >
                                <SelectTrigger className="h-6 w-full text-[10px]">
                                  <SelectValue placeholder="선택" />
                                </SelectTrigger>
                                <SelectContent>
                                  {queryColumns.map((col) => (
                                    <SelectItem key={col} value={col}>
                                      {col}
                                    </SelectItem>
                                  ))}
                                </SelectContent>
                              </Select>
                            </div>

                            {/* 집계 함수 */}
                            <div>
                              <label className="mb-0.5 block text-[9px] font-medium text-gray-500">집계</label>
                              <Select
                                value={metric.aggregation}
                                onValueChange={(value: any) => updateMetric(metric.id, "aggregation", value)}
                              >
                                <SelectTrigger className="h-6 w-full text-[10px]">
                                  <SelectValue />
                                </SelectTrigger>
                                <SelectContent>
                                  <SelectItem value="count">COUNT</SelectItem>
                                  <SelectItem value="sum">SUM</SelectItem>
                                  <SelectItem value="avg">AVG</SelectItem>
                                  <SelectItem value="min">MIN</SelectItem>
                                  <SelectItem value="max">MAX</SelectItem>
                                </SelectContent>
                              </Select>
                            </div>

                            {/* 단위 */}
                            <div>
                              <label className="mb-0.5 block text-[9px] font-medium text-gray-500">단위</label>
                              <Input
                                value={metric.unit}
                                onChange={(e) => updateMetric(metric.id, "unit", e.target.value)}
                                className="h-6 w-full text-[10px]"
                                placeholder="건, %, km"
                              />
                            </div>

                            {/* 소수점 */}
                            <div>
                              <label className="mb-0.5 block text-[9px] font-medium text-gray-500">소수점</label>
                              <Select
                                value={String(metric.decimals)}
                                onValueChange={(value) => updateMetric(metric.id, "decimals", parseInt(value))}
                              >
                                <SelectTrigger className="h-6 w-full text-[10px]">
                                  <SelectValue />
                                </SelectTrigger>
                                <SelectContent>
                                  {[0, 1, 2].map((num) => (
                                    <SelectItem key={num} value={String(num)}>
                                      {num}
                                    </SelectItem>
                                  ))}
                                </SelectContent>
                              </Select>
                            </div>
                          </div>

                          {/* 표시 이름 (전체 너비) */}
                          <div>
                            <label className="mb-0.5 block text-[9px] font-medium text-gray-500">표시 이름</label>
                            <Input
                              value={metric.label}
                              onChange={(e) => updateMetric(metric.id, "label", e.target.value)}
                              className="h-6 w-full text-[10px]"
                              placeholder="라벨"
                            />
                          </div>

                          {/* 삭제 버튼 */}
                          <div className="border-t border-gray-200 pt-1.5">
                            <Button
                              size="sm"
                              variant="ghost"
                              className="text-destructive hover:bg-destructive/10 hover:text-destructive h-6 w-full gap-1 text-[10px]"
                              onClick={() => deleteMetric(metric.id)}
                            >
                              <Trash2 className="h-3 w-3" />
                              삭제
                            </Button>
                          </div>
                        </div>
                      )}
                    </div>
                  ))
                )}
              </div>
            </div>
          )}
        </div>
      </div>

      {/* 푸터 */}
      <div className="flex gap-2 border-t bg-white p-3 shadow-sm">
        <Button variant="outline" className="h-8 flex-1 text-xs" onClick={onClose}>
          취소
        </Button>
        <Button className="focus:ring-primary/20 h-8 flex-1 text-xs" onClick={handleSave}>
          적용
        </Button>
      </div>
    </div>
  );
}
