import React, { useState, useEffect, useMemo, useCallback } from "react";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import { Loader2, AlertCircle, Check, X } from "lucide-react";
import { cn } from "@/lib/utils";
import { ComponentData, LayerCondition, LayerDefinition } from "@/types/screen-management";
import { getCodesByCategory, CodeItem } from "@/lib/api/codeManagement";

interface LayerConditionPanelProps {
  layer: LayerDefinition;
  components: ComponentData[]; // 화면의 모든 컴포넌트
  onUpdateCondition: (condition: LayerCondition | undefined) => void;
  onClose?: () => void;
}

// 조건 연산자 옵션
const OPERATORS = [
  { value: "eq", label: "같음 (=)" },
  { value: "neq", label: "같지 않음 (≠)" },
  { value: "in", label: "포함 (in)" },
] as const;

type OperatorType = "eq" | "neq" | "in";

export const LayerConditionPanel: React.FC<LayerConditionPanelProps> = ({
  layer,
  components,
  onUpdateCondition,
  onClose,
}) => {
  // 조건 설정 상태
  const [targetComponentId, setTargetComponentId] = useState<string>(
    layer.condition?.targetComponentId || ""
  );
  const [operator, setOperator] = useState<OperatorType>(
    (layer.condition?.operator as OperatorType) || "eq"
  );
  const [value, setValue] = useState<string>(
    layer.condition?.value?.toString() || ""
  );
  const [multiValues, setMultiValues] = useState<string[]>(
    Array.isArray(layer.condition?.value) ? layer.condition.value : []
  );

  // 코드 목록 로딩 상태
  const [codeOptions, setCodeOptions] = useState<CodeItem[]>([]);
  const [isLoadingCodes, setIsLoadingCodes] = useState(false);
  const [codeLoadError, setCodeLoadError] = useState<string | null>(null);

  // 트리거 가능한 컴포넌트 필터링 (셀렉트, 라디오, 코드 타입 등)
  const triggerableComponents = useMemo(() => {
    return components.filter((comp) => {
      const componentType = (comp.componentType || "").toLowerCase();
      const widgetType = ((comp as any).widgetType || "").toLowerCase();
      const webType = ((comp as any).webType || "").toLowerCase();
      const inputType = ((comp as any).componentConfig?.inputType || "").toLowerCase();
      
      // 셀렉트, 라디오, 코드 타입 컴포넌트만 허용
      const triggerTypes = ["select", "radio", "code", "checkbox", "toggle"];
      const isTriggerType = triggerTypes.some((type) => 
        componentType.includes(type) ||
        widgetType.includes(type) ||
        webType.includes(type) ||
        inputType.includes(type)
      );
      
      return isTriggerType;
    });
  }, [components]);

  // 선택된 컴포넌트 정보
  const selectedComponent = useMemo(() => {
    return components.find((c) => c.id === targetComponentId);
  }, [components, targetComponentId]);

  // 선택된 컴포넌트의 코드 카테고리
  const codeCategory = useMemo(() => {
    if (!selectedComponent) return null;
    
    // codeCategory 확인 (다양한 위치에 있을 수 있음)
    const category = 
      (selectedComponent as any).codeCategory ||
      (selectedComponent as any).componentConfig?.codeCategory ||
      (selectedComponent as any).webTypeConfig?.codeCategory;
    
    return category || null;
  }, [selectedComponent]);

  // 컴포넌트 선택 시 코드 목록 로드
  useEffect(() => {
    if (!codeCategory) {
      setCodeOptions([]);
      return;
    }

    const loadCodes = async () => {
      setIsLoadingCodes(true);
      setCodeLoadError(null);
      
      try {
        const codes = await getCodesByCategory(codeCategory);
        setCodeOptions(codes);
      } catch (error: any) {
        console.error("코드 목록 로드 실패:", error);
        setCodeLoadError(error.message || "코드 목록을 불러올 수 없습니다.");
        setCodeOptions([]);
      } finally {
        setIsLoadingCodes(false);
      }
    };

    loadCodes();
  }, [codeCategory]);

  // 조건 저장
  const handleSave = useCallback(() => {
    if (!targetComponentId) {
      return;
    }

    const condition: LayerCondition = {
      targetComponentId,
      operator,
      value: operator === "in" ? multiValues : value,
    };

    onUpdateCondition(condition);
    onClose?.();
  }, [targetComponentId, operator, value, multiValues, onUpdateCondition, onClose]);

  // 조건 삭제
  const handleClear = useCallback(() => {
    onUpdateCondition(undefined);
    setTargetComponentId("");
    setOperator("eq");
    setValue("");
    setMultiValues([]);
    onClose?.();
  }, [onUpdateCondition, onClose]);

  // in 연산자용 다중 값 토글
  const toggleMultiValue = useCallback((val: string) => {
    setMultiValues((prev) => 
      prev.includes(val) 
        ? prev.filter((v) => v !== val) 
        : [...prev, val]
    );
  }, []);

  // 컴포넌트 라벨 가져오기
  const getComponentLabel = (comp: ComponentData) => {
    return comp.label || (comp as any).columnName || comp.id;
  };

  return (
    <div className="space-y-4 p-4">
      <div className="flex items-center justify-between">
        <h4 className="text-sm font-semibold">조건부 표시 설정</h4>
        {layer.condition && (
          <Badge variant="secondary" className="text-xs">
            설정됨
          </Badge>
        )}
      </div>

      {/* 트리거 컴포넌트 선택 */}
      <div className="space-y-2">
        <Label className="text-xs">트리거 컴포넌트</Label>
        <Select value={targetComponentId} onValueChange={setTargetComponentId}>
          <SelectTrigger className="h-8 text-xs">
            <SelectValue placeholder="컴포넌트 선택..." />
          </SelectTrigger>
          <SelectContent>
            {triggerableComponents.length === 0 ? (
              <div className="p-2 text-xs text-muted-foreground text-center">
                조건 설정 가능한 컴포넌트가 없습니다.
                <br />
                (셀렉트, 라디오, 코드 타입)
              </div>
            ) : (
              triggerableComponents.map((comp) => (
                <SelectItem key={comp.id} value={comp.id} className="text-xs">
                  <div className="flex items-center gap-2">
                    <span>{getComponentLabel(comp)}</span>
                    <Badge variant="outline" className="text-[10px]">
                      {comp.componentType || (comp as any).widgetType}
                    </Badge>
                  </div>
                </SelectItem>
              ))
            )}
          </SelectContent>
        </Select>
        
        {/* 코드 카테고리 표시 */}
        {codeCategory && (
          <div className="flex items-center gap-2 text-xs text-muted-foreground">
            <span>카테고리:</span>
            <Badge variant="secondary" className="text-[10px]">
              {codeCategory}
            </Badge>
          </div>
        )}
      </div>

      {/* 연산자 선택 */}
      {targetComponentId && (
        <div className="space-y-2">
          <Label className="text-xs">조건</Label>
          <Select 
            value={operator} 
            onValueChange={(val) => setOperator(val as OperatorType)}
          >
            <SelectTrigger className="h-8 text-xs">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {OPERATORS.map((op) => (
                <SelectItem key={op.value} value={op.value} className="text-xs">
                  {op.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      )}

      {/* 조건 값 선택 */}
      {targetComponentId && (
        <div className="space-y-2">
          <Label className="text-xs">
            {operator === "in" ? "값 선택 (복수)" : "값"}
          </Label>
          
          {isLoadingCodes ? (
            <div className="flex items-center gap-2 text-xs text-muted-foreground p-2">
              <Loader2 className="h-3 w-3 animate-spin" />
              코드 목록 로딩 중...
            </div>
          ) : codeLoadError ? (
            <div className="flex items-center gap-2 text-xs text-destructive p-2">
              <AlertCircle className="h-3 w-3" />
              {codeLoadError}
            </div>
          ) : codeOptions.length > 0 ? (
            // 코드 카테고리가 있는 경우 - 선택 UI
            operator === "in" ? (
              // 다중 선택 (in 연산자)
              <div className="space-y-1 max-h-40 overflow-y-auto border rounded-md p-2">
                {codeOptions.map((code) => (
                  <div
                    key={code.codeValue}
                    className={cn(
                      "flex items-center gap-2 p-1.5 rounded cursor-pointer text-xs hover:bg-accent",
                      multiValues.includes(code.codeValue) && "bg-primary/10"
                    )}
                    onClick={() => toggleMultiValue(code.codeValue)}
                  >
                    <div className={cn(
                      "w-4 h-4 rounded border flex items-center justify-center",
                      multiValues.includes(code.codeValue) 
                        ? "bg-primary border-primary" 
                        : "border-input"
                    )}>
                      {multiValues.includes(code.codeValue) && (
                        <Check className="h-3 w-3 text-primary-foreground" />
                      )}
                    </div>
                    <span>{code.codeName}</span>
                    <span className="text-muted-foreground">({code.codeValue})</span>
                  </div>
                ))}
              </div>
            ) : (
              // 단일 선택 (eq, neq 연산자)
              <Select value={value} onValueChange={setValue}>
                <SelectTrigger className="h-8 text-xs">
                  <SelectValue placeholder="값 선택..." />
                </SelectTrigger>
                <SelectContent>
                  {codeOptions.map((code) => (
                    <SelectItem 
                      key={code.codeValue} 
                      value={code.codeValue} 
                      className="text-xs"
                    >
                      {code.codeName} ({code.codeValue})
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            )
          ) : (
            // 코드 카테고리가 없는 경우 - 직접 입력
            <Input
              value={value}
              onChange={(e) => setValue(e.target.value)}
              placeholder="조건 값 입력..."
              className="h-8 text-xs"
            />
          )}
          
          {/* 선택된 값 표시 (in 연산자) */}
          {operator === "in" && multiValues.length > 0 && (
            <div className="flex flex-wrap gap-1 mt-2">
              {multiValues.map((val) => {
                const code = codeOptions.find((c) => c.codeValue === val);
                return (
                  <Badge 
                    key={val} 
                    variant="secondary" 
                    className="text-[10px] gap-1"
                  >
                    {code?.codeName || val}
                    <X 
                      className="h-2.5 w-2.5 cursor-pointer hover:text-destructive"
                      onClick={() => toggleMultiValue(val)}
                    />
                  </Badge>
                );
              })}
            </div>
          )}
        </div>
      )}

      {/* 현재 조건 요약 */}
      {targetComponentId && (value || multiValues.length > 0) && (
        <div className="p-2 bg-muted rounded-md text-xs">
          <span className="font-medium">요약: </span>
          <span className="text-muted-foreground">
            "{getComponentLabel(selectedComponent!)}" 값이{" "}
            {operator === "eq" && `"${codeOptions.find(c => c.codeValue === value)?.codeName || value}"와 같으면`}
            {operator === "neq" && `"${codeOptions.find(c => c.codeValue === value)?.codeName || value}"와 다르면`}
            {operator === "in" && `[${multiValues.map(v => codeOptions.find(c => c.codeValue === v)?.codeName || v).join(", ")}] 중 하나이면`}
            {" "}이 레이어 표시
          </span>
        </div>
      )}

      {/* 버튼 */}
      <div className="flex gap-2 pt-2">
        <Button
          variant="outline"
          size="sm"
          className="flex-1 h-8 text-xs"
          onClick={handleClear}
        >
          조건 삭제
        </Button>
        <Button
          size="sm"
          className="flex-1 h-8 text-xs"
          onClick={handleSave}
          disabled={!targetComponentId || (!value && multiValues.length === 0)}
        >
          저장
        </Button>
      </div>
    </div>
  );
};
