import React, { useState, useEffect, useCallback } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Badge } from "@/components/ui/badge";
import {
  Plus,
  Trash2,
  GripVertical,
  Layers,
  SplitSquareVertical,
  ChevronDown,
  ChevronRight,
  Zap,
  Loader2,
  Box,
  Settings2,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { screenApi } from "@/lib/api/screen";
import { toast } from "sonner";
import { ComponentData, ConditionalZone } from "@/types/screen-management";

// DB 레이어 타입
interface DBLayer {
  layer_id: number;
  layer_name: string;
  condition_config: any;
  component_count: number;
  updated_at: string;
}

interface LayerManagerPanelProps {
  screenId: number | null;
  activeLayerId: number; // 현재 활성 레이어 ID (DB layer_id)
  onLayerChange: (layerId: number) => void; // 레이어 전환
  components?: ComponentData[]; // 현재 활성 레이어의 컴포넌트 (폴백용)
  zones?: ConditionalZone[]; // Zone 목록 (ScreenDesigner에서 전달)
  onZonesChange?: (zones: ConditionalZone[]) => void; // Zone 목록 변경 콜백
}

export const LayerManagerPanel: React.FC<LayerManagerPanelProps> = ({
  screenId,
  activeLayerId,
  onLayerChange,
  components = [],
  zones: externalZones,
  onZonesChange,
}) => {
  const [layers, setLayers] = useState<DBLayer[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  // 펼침/접힘 상태: zone_id별
  const [expandedZones, setExpandedZones] = useState<Set<number>>(new Set());
  // Zone에 레이어 추가 시 조건값 입력 상태
  const [addingToZoneId, setAddingToZoneId] = useState<number | null>(null);
  const [newConditionValue, setNewConditionValue] = useState("");
  // Zone 트리거 설정 열기 상태
  const [triggerEditZoneId, setTriggerEditZoneId] = useState<number | null>(null);
  // 기본 레이어 컴포넌트 (트리거 선택용)
  const [baseLayerComponents, setBaseLayerComponents] = useState<ComponentData[]>([]);

  const zones = externalZones || [];

  // 레이어 목록 로드
  const loadLayers = useCallback(async () => {
    if (!screenId) return;
    setIsLoading(true);
    try {
      const data = await screenApi.getScreenLayers(screenId);
      setLayers(data);
    } catch (error) {
      console.error("레이어 목록 로드 실패:", error);
    } finally {
      setIsLoading(false);
    }
  }, [screenId]);

  // 기본 레이어 컴포넌트 로드
  const loadBaseLayerComponents = useCallback(async () => {
    if (!screenId) return;
    try {
      const data = await screenApi.getLayerLayout(screenId, 1);
      if (data?.components) {
        setBaseLayerComponents(data.components as ComponentData[]);
      }
    } catch {
      setBaseLayerComponents(components);
    }
  }, [screenId, components]);

  useEffect(() => {
    loadLayers();
    loadBaseLayerComponents();
  }, [loadLayers, loadBaseLayerComponents]);

  // Zone별 레이어 그룹핑
  const getLayersForZone = useCallback((zoneId: number): DBLayer[] => {
    return layers.filter(l => {
      const cc = l.condition_config;
      return cc && cc.zone_id === zoneId;
    });
  }, [layers]);

  // Zone에 속하지 않는 조건부 레이어 (레거시)
  const orphanLayers = layers.filter(l => {
    if (l.layer_id === 1) return false;
    const cc = l.condition_config;
    return !cc || !cc.zone_id;
  });

  // 기본 레이어
  const baseLayer = layers.find(l => l.layer_id === 1);

  // Zone에 레이어 추가
  const handleAddLayerToZone = useCallback(async (zoneId: number) => {
    if (!screenId || !newConditionValue.trim()) return;
    try {
      const result = await screenApi.addLayerToZone(
        screenId, zoneId, newConditionValue.trim(),
        `레이어 (${newConditionValue.trim()})`,
      );
      toast.success(`레이어가 Zone에 추가되었습니다. (ID: ${result.layerId})`);
      setAddingToZoneId(null);
      setNewConditionValue("");
      await loadLayers();
      onLayerChange(result.layerId);
    } catch (error) {
      console.error("Zone 레이어 추가 실패:", error);
      toast.error("레이어 추가에 실패했습니다.");
    }
  }, [screenId, newConditionValue, loadLayers, onLayerChange]);

  // 레이어 삭제
  const handleDeleteLayer = useCallback(async (layerId: number) => {
    if (!screenId || layerId === 1) return;
    try {
      await screenApi.deleteLayer(screenId, layerId);
      toast.success("레이어가 삭제되었습니다.");
      await loadLayers();
      if (activeLayerId === layerId) onLayerChange(1);
    } catch (error) {
      console.error("레이어 삭제 실패:", error);
      toast.error("레이어 삭제에 실패했습니다.");
    }
  }, [screenId, activeLayerId, loadLayers, onLayerChange]);

  // Zone 삭제
  const handleDeleteZone = useCallback(async (zoneId: number) => {
    if (!screenId) return;
    try {
      await screenApi.deleteZone(zoneId);
      toast.success("조건부 영역이 삭제되었습니다.");
      // Zone 목록 새로고침
      const loadedZones = await screenApi.getScreenZones(screenId);
      onZonesChange?.(loadedZones);
      await loadLayers();
      onLayerChange(1);
    } catch (error) {
      console.error("Zone 삭제 실패:", error);
      toast.error("Zone 삭제에 실패했습니다.");
    }
  }, [screenId, loadLayers, onLayerChange, onZonesChange]);

  // Zone 트리거 컴포넌트 업데이트
  const handleUpdateZoneTrigger = useCallback(async (zoneId: number, triggerComponentId: string, operator: string = "eq") => {
    try {
      await screenApi.updateZone(zoneId, {
        trigger_component_id: triggerComponentId,
        trigger_operator: operator,
      });
      const loadedZones = await screenApi.getScreenZones(screenId!);
      onZonesChange?.(loadedZones);
      toast.success("트리거가 설정되었습니다.");
    } catch (error) {
      console.error("Zone 트리거 업데이트 실패:", error);
      toast.error("트리거 설정에 실패했습니다.");
    }
  }, [screenId, onZonesChange]);

  // Zone 접힘/펼침 토글
  const toggleZone = (zoneId: number) => {
    setExpandedZones(prev => {
      const next = new Set(prev);
      next.has(zoneId) ? next.delete(zoneId) : next.add(zoneId);
      return next;
    });
  };

  // 트리거로 사용 가능한 컴포넌트 (select, combobox 등)
  const triggerableComponents = baseLayerComponents.filter(c =>
    ["select", "combobox", "radio-group"].some(t => c.componentType?.includes(t))
  );

  return (
    <div className="flex h-full flex-col bg-background">
      {/* 헤더 */}
      <div className="flex items-center justify-between border-b px-3 py-2">
        <div className="flex items-center gap-2">
          <Layers className="h-4 w-4 text-muted-foreground" />
          <h3 className="text-sm font-semibold">레이어</h3>
          <Badge variant="secondary" className="px-1.5 py-0 text-[10px]">
            {layers.length}
          </Badge>
        </div>
      </div>

      {/* 레이어 + Zone 목록 */}
      <ScrollArea className="flex-1">
        <div className="space-y-1 p-2">
          {isLoading ? (
            <div className="flex items-center justify-center py-8 text-muted-foreground">
              <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              <span className="text-sm">로딩 중...</span>
            </div>
          ) : (
            <>
              {/* 기본 레이어 */}
              {baseLayer && (
                <div
                  className={cn(
                    "flex cursor-pointer items-center gap-2 rounded-md border p-2 text-sm transition-all",
                    activeLayerId === 1
                      ? "border-primary bg-primary/5 shadow-sm"
                      : "border-transparent hover:bg-muted",
                  )}
                  onClick={() => onLayerChange(1)}
                >
                  <span className="shrink-0 rounded bg-blue-100 p-1 text-blue-700 dark:bg-blue-900 dark:text-blue-300">
                    <Layers className="h-3 w-3" />
                  </span>
                  <div className="min-w-0 flex-1">
                    <span className="truncate font-medium">{baseLayer.layer_name}</span>
                    <div className="flex items-center gap-2">
                      <Badge variant="outline" className="h-4 px-1 py-0 text-[10px]">기본</Badge>
                      <span className="text-[10px] text-muted-foreground">{baseLayer.component_count}개 컴포넌트</span>
                    </div>
                  </div>
                </div>
              )}

              {/* 조건부 영역(Zone) 목록 */}
              {zones.map((zone) => {
                const zoneLayers = getLayersForZone(zone.zone_id);
                const isExpanded = expandedZones.has(zone.zone_id);
                const isTriggerEdit = triggerEditZoneId === zone.zone_id;

                return (
                  <div key={`zone-${zone.zone_id}`} className="space-y-0">
                    {/* Zone 헤더 */}
                    <div
                      className={cn(
                        "flex cursor-pointer items-center gap-2 rounded-md border p-2 text-sm transition-all",
                        "border-amber-200 bg-amber-50/50 hover:bg-amber-100/50 dark:border-amber-800 dark:bg-amber-950/20",
                        isExpanded && "rounded-b-none border-b-0",
                      )}
                      onClick={() => toggleZone(zone.zone_id)}
                    >
                      {isExpanded ? (
                        <ChevronDown className="h-3.5 w-3.5 shrink-0 text-amber-600" />
                      ) : (
                        <ChevronRight className="h-3.5 w-3.5 shrink-0 text-amber-600" />
                      )}
                      <Box className="h-3.5 w-3.5 shrink-0 text-amber-600" />
                      <div className="min-w-0 flex-1">
                        <span className="truncate font-medium text-amber-800 dark:text-amber-300">{zone.zone_name}</span>
                        <div className="flex items-center gap-2">
                          <Badge variant="outline" className="h-4 px-1 py-0 text-[10px] border-amber-300 text-amber-700">
                            Zone
                          </Badge>
                          <span className="text-[10px] text-muted-foreground">
                            {zoneLayers.length}개 레이어 | {zone.width}x{zone.height}
                          </span>
                          {zone.trigger_component_id && (
                            <Badge variant="secondary" className="h-4 gap-0.5 px-1 py-0 text-[10px]">
                              <Zap className="h-2.5 w-2.5" /> 트리거
                            </Badge>
                          )}
                        </div>
                      </div>

                      {/* Zone 액션 버튼 */}
                      <div className="flex shrink-0 items-center gap-0.5">
                        <Button
                          variant="ghost" size="icon"
                          className="h-6 w-6 text-amber-600 hover:text-amber-800"
                          title="트리거 설정"
                          onClick={(e) => { e.stopPropagation(); setTriggerEditZoneId(isTriggerEdit ? null : zone.zone_id); }}
                        >
                          <Settings2 className="h-3.5 w-3.5" />
                        </Button>
                        <Button
                          variant="ghost" size="icon"
                          className="h-6 w-6 hover:text-destructive"
                          title="Zone 삭제"
                          onClick={(e) => { e.stopPropagation(); handleDeleteZone(zone.zone_id); }}
                        >
                          <Trash2 className="h-3.5 w-3.5" />
                        </Button>
                      </div>
                    </div>

                    {/* 펼쳐진 Zone 내용 */}
                    {isExpanded && (
                      <div className={cn(
                        "rounded-b-md border border-t-0 border-amber-200 bg-amber-50/20 p-2 space-y-1",
                        "dark:border-amber-800 dark:bg-amber-950/10",
                      )}>
                        {/* 트리거 설정 패널 */}
                        {isTriggerEdit && (
                          <div className="mb-2 rounded border bg-background p-2 space-y-2">
                            <p className="text-[10px] font-medium text-muted-foreground">트리거 컴포넌트 선택</p>
                            {triggerableComponents.length === 0 ? (
                              <p className="text-[10px] text-muted-foreground">기본 레이어에 Select/Combobox/Radio 컴포넌트가 없습니다.</p>
                            ) : (
                              <div className="space-y-1">
                                {triggerableComponents.map(c => (
                                  <button
                                    key={c.id}
                                    className={cn(
                                      "w-full text-left rounded px-2 py-1 text-[11px] transition-colors",
                                      zone.trigger_component_id === c.id
                                        ? "bg-primary/10 text-primary font-medium"
                                        : "hover:bg-muted",
                                    )}
                                    onClick={() => handleUpdateZoneTrigger(zone.zone_id, c.id!)}
                                  >
                                    {c.componentConfig?.label || c.id} ({c.componentType})
                                  </button>
                                ))}
                              </div>
                            )}
                          </div>
                        )}

                        {/* Zone 소속 레이어 목록 */}
                        {zoneLayers.map((layer) => {
                          const isActive = activeLayerId === layer.layer_id;
                          return (
                            <div
                              key={layer.layer_id}
                              className={cn(
                                "flex cursor-pointer items-center gap-2 rounded-md border p-1.5 text-sm transition-all",
                                isActive
                                  ? "border-primary bg-primary/5 shadow-sm"
                                  : "border-transparent hover:bg-background",
                              )}
                              onClick={() => onLayerChange(layer.layer_id)}
                            >
                              <SplitSquareVertical className="h-3 w-3 shrink-0 text-amber-600" />
                              <div className="min-w-0 flex-1">
                                <span className="text-xs font-medium truncate">{layer.layer_name}</span>
                                <div className="flex items-center gap-2">
                                  <span className="text-[10px] text-muted-foreground">
                                    조건값: {layer.condition_config?.condition_value || "미설정"}
                                  </span>
                                  <span className="text-[10px] text-muted-foreground">
                                    | {layer.component_count}개
                                  </span>
                                </div>
                              </div>
                              <Button
                                variant="ghost" size="icon"
                                className="h-5 w-5 hover:text-destructive"
                                title="레이어 삭제"
                                onClick={(e) => { e.stopPropagation(); handleDeleteLayer(layer.layer_id); }}
                              >
                                <Trash2 className="h-3 w-3" />
                              </Button>
                            </div>
                          );
                        })}

                        {/* 레이어 추가 */}
                        {addingToZoneId === zone.zone_id ? (
                          <div className="flex items-center gap-1 rounded border bg-background p-1.5">
                            <Input
                              value={newConditionValue}
                              onChange={(e) => setNewConditionValue(e.target.value)}
                              placeholder="조건값 입력 (예: 옵션1)"
                              className="h-6 text-[11px] flex-1"
                              autoFocus
                              onKeyDown={(e) => { if (e.key === "Enter") handleAddLayerToZone(zone.zone_id); }}
                            />
                            <Button
                              variant="default" size="sm"
                              className="h-6 px-2 text-[10px]"
                              onClick={() => handleAddLayerToZone(zone.zone_id)}
                              disabled={!newConditionValue.trim()}
                            >
                              추가
                            </Button>
                            <Button
                              variant="ghost" size="sm"
                              className="h-6 px-1 text-[10px]"
                              onClick={() => { setAddingToZoneId(null); setNewConditionValue(""); }}
                            >
                              취소
                            </Button>
                          </div>
                        ) : (
                          <Button
                            variant="outline" size="sm"
                            className="h-6 w-full gap-1 text-[10px] border-dashed"
                            onClick={() => setAddingToZoneId(zone.zone_id)}
                          >
                            <Plus className="h-3 w-3" />
                            레이어 추가
                          </Button>
                        )}
                      </div>
                    )}
                  </div>
                );
              })}

              {/* 고아 레이어 (Zone에 소속되지 않은 조건부 레이어) */}
              {orphanLayers.length > 0 && (
                <div className="mt-2 space-y-1">
                  <p className="text-[10px] font-medium text-muted-foreground px-1">Zone 미할당 레이어</p>
                  {orphanLayers.map((layer) => {
                    const isActive = activeLayerId === layer.layer_id;
                    return (
                      <div
                        key={layer.layer_id}
                        className={cn(
                          "flex cursor-pointer items-center gap-2 rounded-md border p-2 text-sm transition-all",
                          isActive
                            ? "border-primary bg-primary/5 shadow-sm"
                            : "border-transparent hover:bg-muted",
                        )}
                        onClick={() => onLayerChange(layer.layer_id)}
                      >
                        <GripVertical className="h-4 w-4 shrink-0 cursor-grab text-muted-foreground" />
                        <div className="min-w-0 flex-1">
                          <span className="truncate font-medium">{layer.layer_name}</span>
                          <div className="flex items-center gap-2">
                            <Badge variant="outline" className="h-4 px-1 py-0 text-[10px]">조건부</Badge>
                            <span className="text-[10px] text-muted-foreground">{layer.component_count}개</span>
                          </div>
                        </div>
                        <Button
                          variant="ghost" size="icon"
                          className="h-6 w-6 hover:text-destructive"
                          onClick={(e) => { e.stopPropagation(); handleDeleteLayer(layer.layer_id); }}
                        >
                          <Trash2 className="h-3.5 w-3.5" />
                        </Button>
                      </div>
                    );
                  })}
                </div>
              )}
            </>
          )}
        </div>
      </ScrollArea>

      {/* Zone 생성 드래그 영역 */}
      <div className="border-t px-3 py-2 space-y-1">
        <div
          className="flex cursor-grab items-center gap-2 rounded border border-dashed border-amber-300 bg-amber-50/50 px-2 py-1.5 text-xs text-amber-700 dark:border-amber-700 dark:bg-amber-950/20 dark:text-amber-400"
          draggable
          onDragStart={(e) => {
            e.dataTransfer.setData("application/json", JSON.stringify({ type: "create-zone" }));
            e.dataTransfer.effectAllowed = "copy";
          }}
        >
          <GripVertical className="h-3.5 w-3.5" />
          <Box className="h-3.5 w-3.5" />
          <span>조건부 영역 추가 (캔버스로 드래그)</span>
        </div>
        <p className="text-[10px] text-muted-foreground">
          기본 레이어에서 Zone을 배치한 후, Zone 내에 레이어를 추가하세요
        </p>
      </div>
    </div>
  );
};
