import React, { useState, useEffect, useCallback } from "react";
import { Button } from "@/components/ui/button";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Badge } from "@/components/ui/badge";
import {
  Plus,
  Trash2,
  GripVertical,
  Layers,
  SplitSquareVertical,
  ChevronDown,
  ChevronRight,
  Zap,
  Loader2,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { screenApi } from "@/lib/api/screen";
import { convertV2ToLegacy } from "@/lib/utils/layoutV2Converter";
import { toast } from "sonner";
import { LayerConditionPanel } from "./LayerConditionPanel";
import { ComponentData, LayerCondition, DisplayRegion } 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[]; // 현재 활성 레이어의 컴포넌트 (폴백용)
}

export const LayerManagerPanel: React.FC<LayerManagerPanelProps> = ({
  screenId,
  activeLayerId,
  onLayerChange,
  components = [],
}) => {
  const [layers, setLayers] = useState<DBLayer[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [conditionOpenLayerId, setConditionOpenLayerId] = useState<number | null>(null);
  // 기본 레이어(layer_id=1)의 컴포넌트 (조건 설정 시 트리거 대상)
  const [baseLayerComponents, setBaseLayerComponents] = useState<ComponentData[]>([]);

  // 레이어 목록 로드
  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 && data.components) {
        const legacy = convertV2ToLegacy(data);
        if (legacy) {
          setBaseLayerComponents(legacy.components as ComponentData[]);
          return;
        }
      }
      setBaseLayerComponents([]);
    } catch {
      // 기본 레이어가 없거나 로드 실패 시 현재 컴포넌트 사용
      setBaseLayerComponents(components);
    }
  }, [screenId, components]);

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

  // 조건 설정 패널이 열릴 때 기본 레이어 컴포넌트 로드
  useEffect(() => {
    if (conditionOpenLayerId !== null) {
      loadBaseLayerComponents();
    }
  }, [conditionOpenLayerId, loadBaseLayerComponents]);

  // 새 레이어 추가
  const handleAddLayer = useCallback(async () => {
    if (!screenId) return;
    // 다음 layer_id 계산
    const maxLayerId = layers.length > 0 ? Math.max(...layers.map((l) => l.layer_id)) : 0;
    const newLayerId = maxLayerId + 1;

    try {
      // 빈 레이아웃으로 새 레이어 저장
      await screenApi.saveLayoutV2(screenId, {
        version: "2.0",
        components: [],
        layerId: newLayerId,
        layerName: `조건부 레이어 ${newLayerId}`,
      });
      toast.success(`조건부 레이어 ${newLayerId}가 생성되었습니다.`);
      await loadLayers();
      // 새 레이어로 전환
      onLayerChange(newLayerId);
    } catch (error) {
      console.error("레이어 추가 실패:", error);
      toast.error("레이어 추가에 실패했습니다.");
    }
  }, [screenId, layers, 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]);

  // 조건 업데이트
  const handleUpdateCondition = useCallback(async (layerId: number, condition: LayerCondition | undefined) => {
    if (!screenId) return;
    try {
      await screenApi.updateLayerCondition(screenId, layerId, condition || null);
      toast.success("조건이 저장되었습니다.");
      await loadLayers();
    } catch (error) {
      console.error("조건 업데이트 실패:", error);
      toast.error("조건 저장에 실패했습니다.");
    }
  }, [screenId, loadLayers]);

  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>

        <Button
          variant="ghost"
          size="sm"
          className="h-7 gap-1 px-2"
          onClick={handleAddLayer}
        >
          <Plus className="h-3.5 w-3.5" />
          추가
        </Button>
      </div>

      {/* 레이어 목록 */}
      <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>
          ) : layers.length === 0 ? (
            <div className="space-y-2 py-4 text-center">
              <p className="text-sm text-muted-foreground">레이어를 로드하는 중...</p>
              <p className="text-[10px] text-muted-foreground">먼저 화면을 저장하면 기본 레이어가 생성됩니다.</p>
            </div>
          ) : (
            layers
              .slice()
              .reverse()
              .map((layer) => {
                const isActive = activeLayerId === layer.layer_id;
                const isBase = layer.layer_id === 1;
                const hasCondition = !!layer.condition_config;
                const isConditionOpen = conditionOpenLayerId === layer.layer_id;

                return (
                  <div key={layer.layer_id} className="space-y-0">
                    <div
                      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",
                        isConditionOpen && "rounded-b-none border-b-0",
                      )}
                      onClick={() => onLayerChange(layer.layer_id)}
                      // 조건부 레이어를 캔버스로 드래그 (영역 배치용)
                      draggable={!isBase}
                      onDragStart={(e) => {
                        if (isBase) return;
                        e.dataTransfer.setData("application/json", JSON.stringify({
                          type: "layer-region",
                          layerId: layer.layer_id,
                          layerName: layer.layer_name,
                        }));
                        e.dataTransfer.effectAllowed = "copy";
                      }}
                    >
                      <GripVertical className="h-4 w-4 shrink-0 cursor-grab text-muted-foreground" />

                      <div className="min-w-0 flex-1">
                        <div className="flex items-center gap-2">
                          <span className={cn(
                            "shrink-0 rounded p-1",
                            isBase
                              ? "bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-300"
                              : "bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300",
                          )}>
                            {isBase ? <Layers className="h-3 w-3" /> : <SplitSquareVertical className="h-3 w-3" />}
                          </span>
                          <span className="flex-1 truncate font-medium">{layer.layer_name}</span>
                        </div>
                        <div className="mt-0.5 flex items-center gap-2">
                          <Badge variant="outline" className="h-4 px-1 py-0 text-[10px]">
                            {isBase ? "기본" : "조건부"}
                          </Badge>
                          <span className="text-[10px] text-muted-foreground">
                            {layer.component_count}개 컴포넌트
                          </span>
                          {hasCondition && (
                            <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>

                      {/* 액션 버튼 */}
                      <div className="flex shrink-0 items-center gap-0.5">
                        {!isBase && (
                          <Button
                            variant="ghost"
                            size="icon"
                            className={cn("h-6 w-6", hasCondition && "text-amber-600")}
                            title="조건 설정"
                            onClick={(e) => {
                              e.stopPropagation();
                              setConditionOpenLayerId(isConditionOpen ? null : layer.layer_id);
                            }}
                          >
                            {isConditionOpen ? (
                              <ChevronDown className="h-3.5 w-3.5" />
                            ) : (
                              <ChevronRight className="h-3.5 w-3.5" />
                            )}
                          </Button>
                        )}
                        {!isBase && (
                          <Button
                            variant="ghost"
                            size="icon"
                            className="h-6 w-6 hover:text-destructive"
                            title="레이어 삭제"
                            onClick={(e) => {
                              e.stopPropagation();
                              handleDeleteLayer(layer.layer_id);
                            }}
                          >
                            <Trash2 className="h-3.5 w-3.5" />
                          </Button>
                        )}
                      </div>
                    </div>

                    {/* 조건 설정 패널 */}
                    {!isBase && isConditionOpen && (
                      <div className={cn(
                        "rounded-b-md border border-t-0 bg-muted/30",
                        isActive ? "border-primary" : "border-border",
                      )}>
                        <LayerConditionPanel
                          layer={{
                            id: String(layer.layer_id),
                            name: layer.layer_name,
                            type: "conditional",
                            zIndex: layer.layer_id,
                            isVisible: true,
                            isLocked: false,
                            condition: layer.condition_config || undefined,
                            components: [],
                          }}
                          components={baseLayerComponents}
                          baseLayerComponents={baseLayerComponents}
                          onUpdateCondition={(condition) => handleUpdateCondition(layer.layer_id, condition)}
                          onUpdateDisplayRegion={() => {}}
                          onClose={() => setConditionOpenLayerId(null)}
                        />
                      </div>
                    )}
                  </div>
                );
              })
          )}
        </div>
      </ScrollArea>

      {/* 도움말 */}
      <div className="border-t px-3 py-2 text-[10px] text-muted-foreground">
        <p>레이어를 클릭하여 편집 | 조건부 레이어를 캔버스에 드래그하여 영역 설정</p>
      </div>
    </div>
  );
};
