"use client";

/**
 * ConditionalConfigPanel
 * 
 * 비개발자도 쉽게 조건부 표시/숨김/활성화/비활성화를 설정할 수 있는 UI
 * 
 * 사용처:
 * - 화면관리 > 상세설정 패널
 * - 화면관리 > 속성 패널
 */

import React, { useState, useEffect, useMemo } from "react";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import { Button } from "@/components/ui/button";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Separator } from "@/components/ui/separator";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { Zap, Plus, Trash2, HelpCircle, Check, ChevronsUpDown } from "lucide-react";
import { ConditionalConfig } from "@/types/v2-components";
import { cn } from "@/lib/utils";

// ===== 타입 정의 =====

interface FieldOption {
  id: string;
  label: string;
  type?: string; // text, number, select, checkbox, entity, code 등
  options?: Array<{ value: string; label: string }>; // select 타입일 경우 옵션들
  // 동적 옵션 로드를 위한 정보
  entityTable?: string;
  entityValueColumn?: string;
  entityLabelColumn?: string;
  codeGroup?: string;
}

interface ConditionalConfigPanelProps {
  /** 현재 조건부 설정 */
  config?: ConditionalConfig;
  /** 설정 변경 콜백 */
  onChange: (config: ConditionalConfig | undefined) => void;
  /** 같은 화면에 있는 다른 필드들 (조건 필드로 선택 가능) */
  availableFields: FieldOption[];
  /** 현재 컴포넌트 ID (자기 자신은 조건 필드에서 제외) */
  currentComponentId?: string;
}

// 연산자 옵션
const OPERATORS: Array<{ value: ConditionalConfig["operator"]; label: string; description: string }> = [
  { value: "=", label: "같음", description: "값이 정확히 일치할 때" },
  { value: "!=", label: "다름", description: "값이 일치하지 않을 때" },
  { value: ">", label: "보다 큼", description: "값이 더 클 때 (숫자)" },
  { value: "<", label: "보다 작음", description: "값이 더 작을 때 (숫자)" },
  { value: "in", label: "포함됨", description: "여러 값 중 하나일 때" },
  { value: "notIn", label: "포함 안됨", description: "여러 값 중 아무것도 아닐 때" },
  { value: "isEmpty", label: "비어있음", description: "값이 없을 때" },
  { value: "isNotEmpty", label: "값이 있음", description: "값이 있을 때" },
];

// 동작 옵션
const ACTIONS: Array<{ value: ConditionalConfig["action"]; label: string; description: string }> = [
  { value: "show", label: "표시", description: "조건 만족 시 이 필드를 표시" },
  { value: "hide", label: "숨김", description: "조건 만족 시 이 필드를 숨김" },
  { value: "enable", label: "활성화", description: "조건 만족 시 이 필드를 활성화" },
  { value: "disable", label: "비활성화", description: "조건 만족 시 이 필드를 비활성화" },
];

// ===== 컴포넌트 =====

export function ConditionalConfigPanel({
  config,
  onChange,
  availableFields,
  currentComponentId,
}: ConditionalConfigPanelProps) {
  // 로컬 상태
  const [enabled, setEnabled] = useState(config?.enabled ?? false);
  const [field, setField] = useState(config?.field ?? "");
  const [operator, setOperator] = useState<ConditionalConfig["operator"]>(config?.operator ?? "=");
  const [value, setValue] = useState<string>(String(config?.value ?? ""));
  const [action, setAction] = useState<ConditionalConfig["action"]>(config?.action ?? "show");

  // 자기 자신을 제외한 필드 목록
  const selectableFields = useMemo(() => {
    return availableFields.filter((f) => f.id !== currentComponentId);
  }, [availableFields, currentComponentId]);

  // 선택된 필드 정보
  const selectedField = useMemo(() => {
    return selectableFields.find((f) => f.id === field);
  }, [selectableFields, field]);

  // 동적 옵션 로드 상태
  const [dynamicOptions, setDynamicOptions] = useState<Array<{ value: string; label: string }>>([]);
  const [loadingOptions, setLoadingOptions] = useState(false);
  
  // Combobox 열림 상태
  const [comboboxOpen, setComboboxOpen] = useState(false);

  // 엔티티/공통코드 필드 선택 시 동적으로 옵션 로드
  useEffect(() => {
    const loadDynamicOptions = async () => {
      if (!selectedField) {
        setDynamicOptions([]);
        return;
      }

      // 정적 옵션이 있으면 사용
      if (selectedField.options && selectedField.options.length > 0) {
        setDynamicOptions([]);
        return;
      }

      // 엔티티 타입 (타입이 entity이거나, entityTable이 있으면 엔티티로 간주)
      if (selectedField.entityTable) {
        setLoadingOptions(true);
        try {
          const { apiClient } = await import("@/lib/api/client");
          const valueCol = selectedField.entityValueColumn || "id";
          const labelCol = selectedField.entityLabelColumn || "name";
          const response = await apiClient.get(`/entity/${selectedField.entityTable}/options`, {
            params: { value: valueCol, label: labelCol },
          });
          if (response.data.success && response.data.data) {
            setDynamicOptions(response.data.data);
          }
        } catch (error) {
          console.error("엔티티 옵션 로드 실패:", error);
          setDynamicOptions([]);
        } finally {
          setLoadingOptions(false);
        }
        return;
      }

      // 공통코드 타입 (타입이 code이거나, codeGroup이 있으면 공통코드로 간주)
      if (selectedField.codeGroup) {
        setLoadingOptions(true);
        try {
          const { apiClient } = await import("@/lib/api/client");
          // 올바른 API 경로: /common-codes/categories/:categoryCode/options
          const response = await apiClient.get(`/common-codes/categories/${selectedField.codeGroup}/options`);
          if (response.data.success && response.data.data) {
            setDynamicOptions(
              response.data.data.map((item: { value: string; label: string }) => ({
                value: item.value,
                label: item.label,
              }))
            );
          }
        } catch (error) {
          console.error("공통코드 옵션 로드 실패:", error);
          setDynamicOptions([]);
        } finally {
          setLoadingOptions(false);
        }
        return;
      }

      setDynamicOptions([]);
    };

    loadDynamicOptions();
  }, [selectedField?.id, selectedField?.entityTable, selectedField?.entityValueColumn, selectedField?.entityLabelColumn, selectedField?.codeGroup]);

  // 최종 옵션 (정적 + 동적)
  const fieldOptions = useMemo(() => {
    if (selectedField?.options && selectedField.options.length > 0) {
      return selectedField.options;
    }
    return dynamicOptions;
  }, [selectedField?.options, dynamicOptions]);

  // config prop 변경 시 로컬 상태 동기화
  useEffect(() => {
    setEnabled(config?.enabled ?? false);
    setField(config?.field ?? "");
    setOperator(config?.operator ?? "=");
    setValue(String(config?.value ?? ""));
    setAction(config?.action ?? "show");
  }, [config]);

  // 설정 변경 시 부모에게 알림
  const updateConfig = (updates: Partial<ConditionalConfig>) => {
    const newConfig: ConditionalConfig = {
      enabled: updates.enabled ?? enabled,
      field: updates.field ?? field,
      operator: updates.operator ?? operator,
      value: updates.value ?? value,
      action: updates.action ?? action,
    };
    
    // enabled가 false이면 undefined 반환 (설정 제거)
    if (!newConfig.enabled) {
      onChange(undefined);
    } else {
      onChange(newConfig);
    }
  };

  // 활성화 토글
  const handleEnabledChange = (checked: boolean) => {
    setEnabled(checked);
    updateConfig({ enabled: checked });
  };

  // 조건 필드 변경
  const handleFieldChange = (newField: string) => {
    setField(newField);
    setValue(""); // 필드 변경 시 값 초기화
    updateConfig({ field: newField, value: "" });
  };

  // 연산자 변경
  const handleOperatorChange = (newOperator: ConditionalConfig["operator"]) => {
    setOperator(newOperator);
    // 비어있음/값이있음 연산자는 value 필요 없음
    if (newOperator === "isEmpty" || newOperator === "isNotEmpty") {
      setValue("");
      updateConfig({ operator: newOperator, value: "" });
    } else {
      updateConfig({ operator: newOperator });
    }
  };

  // 값 변경
  const handleValueChange = (newValue: string) => {
    setValue(newValue);
    
    // 타입에 따라 적절한 값으로 변환
    let parsedValue: unknown = newValue;
    if (selectedField?.type === "number") {
      parsedValue = Number(newValue);
    } else if (newValue === "true") {
      parsedValue = true;
    } else if (newValue === "false") {
      parsedValue = false;
    }
    
    updateConfig({ value: parsedValue });
  };

  // 동작 변경
  const handleActionChange = (newAction: ConditionalConfig["action"]) => {
    setAction(newAction);
    updateConfig({ action: newAction });
  };

  // 값 입력 필드 렌더링 (필드 타입에 따라 다르게)
  const renderValueInput = () => {
    // 비어있음/값이있음은 값 입력 불필요
    if (operator === "isEmpty" || operator === "isNotEmpty") {
      return (
        <div className="text-xs text-muted-foreground italic">
          (값 입력 불필요)
        </div>
      );
    }

    // 옵션 로딩 중
    if (loadingOptions) {
      return (
        <div className="text-xs text-muted-foreground italic">
          옵션 로딩 중...
        </div>
      );
    }

    // 옵션이 있으면 검색 가능한 Combobox로 표시
    if (fieldOptions.length > 0) {
      const selectedOption = fieldOptions.find((opt) => opt.value === value);
      
      return (
        <Popover open={comboboxOpen} onOpenChange={setComboboxOpen}>
          <PopoverTrigger asChild>
            <Button
              variant="outline"
              role="combobox"
              aria-expanded={comboboxOpen}
              className="h-8 w-full justify-between text-xs font-normal"
            >
              <span className="truncate">
                {selectedOption ? selectedOption.label : "값 선택"}
              </span>
              <ChevronsUpDown className="ml-2 h-3 w-3 shrink-0 opacity-50" />
            </Button>
          </PopoverTrigger>
          <PopoverContent className="w-[300px] p-0" align="start">
            <Command>
              <CommandInput placeholder="검색..." className="h-8 text-xs" />
              <CommandList>
                <CommandEmpty className="py-2 text-center text-xs">
                  검색 결과가 없습니다
                </CommandEmpty>
                <CommandGroup>
                  {fieldOptions.map((opt) => (
                    <CommandItem
                      key={opt.value}
                      value={opt.label}
                      onSelect={() => {
                        handleValueChange(opt.value);
                        setComboboxOpen(false);
                      }}
                      className="text-xs"
                    >
                      <Check
                        className={cn(
                          "mr-2 h-3 w-3",
                          value === opt.value ? "opacity-100" : "opacity-0"
                        )}
                      />
                      <span className="truncate">{opt.label}</span>
                    </CommandItem>
                  ))}
                </CommandGroup>
              </CommandList>
            </Command>
          </PopoverContent>
        </Popover>
      );
    }

    // 체크박스 타입이면 true/false Select
    if (selectedField?.type === "checkbox" || selectedField?.type === "boolean") {
      return (
        <Select value={value} onValueChange={handleValueChange}>
          <SelectTrigger className="h-8 text-xs">
            <SelectValue placeholder="값 선택" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="true" className="text-xs">체크됨</SelectItem>
            <SelectItem value="false" className="text-xs">체크 안됨</SelectItem>
          </SelectContent>
        </Select>
      );
    }

    // 숫자 타입
    if (selectedField?.type === "number") {
      return (
        <Input
          type="number"
          value={value}
          onChange={(e) => handleValueChange(e.target.value)}
          placeholder="숫자 입력"
          className="h-8 text-xs"
        />
      );
    }

    // 기본: 텍스트 입력
    return (
      <Input
        value={value}
        onChange={(e) => handleValueChange(e.target.value)}
        placeholder="값 입력"
        className="h-8 text-xs"
      />
    );
  };

  return (
    <div className="space-y-4">
      {/* 헤더 */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2">
          <Zap className="h-4 w-4 text-amber-500" />
          <span className="text-sm font-medium">조건부 표시</span>
          <span 
            className="text-muted-foreground cursor-help" 
            title="다른 필드의 값에 따라 이 필드를 표시/숨김/활성화/비활성화할 수 있습니다."
          >
            <HelpCircle className="h-3 w-3" />
          </span>
        </div>
        <Switch
          checked={enabled}
          onCheckedChange={handleEnabledChange}
          aria-label="조건부 표시 활성화"
        />
      </div>

      {/* 조건 설정 영역 */}
      {enabled && (
        <div className="space-y-3 rounded-lg border bg-muted/30 p-3">
          {/* 조건 필드 선택 */}
          <div className="space-y-1.5">
            <Label className="text-xs font-medium">조건 필드</Label>
            <Select value={field} onValueChange={handleFieldChange}>
              <SelectTrigger className="h-8 text-xs">
                <SelectValue placeholder="필드 선택" />
              </SelectTrigger>
              <SelectContent>
                {selectableFields.length === 0 ? (
                  <div className="p-2 text-xs text-muted-foreground">
                    선택 가능한 필드가 없습니다
                  </div>
                ) : (
                  selectableFields.map((f) => (
                    <SelectItem key={f.id} value={f.id} className="text-xs">
                      {f.label || f.id}
                    </SelectItem>
                  ))
                )}
              </SelectContent>
            </Select>
            <p className="text-[10px] text-muted-foreground">
              이 필드의 값에 따라 조건이 적용됩니다
            </p>
          </div>

          {/* 연산자 선택 */}
          <div className="space-y-1.5">
            <Label className="text-xs font-medium">조건</Label>
            <Select value={operator} onValueChange={handleOperatorChange}>
              <SelectTrigger className="h-8 text-xs">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {OPERATORS.map((op) => (
                  <SelectItem key={op.value} value={op.value} className="text-xs">
                    <div className="flex flex-col">
                      <span>{op.label}</span>
                    </div>
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          {/* 값 입력 */}
          <div className="space-y-1.5">
            <Label className="text-xs font-medium">값</Label>
            {renderValueInput()}
          </div>

          {/* 동작 선택 */}
          <div className="space-y-1.5">
            <Label className="text-xs font-medium">동작</Label>
            <Select value={action} onValueChange={handleActionChange}>
              <SelectTrigger className="h-8 text-xs">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {ACTIONS.map((act) => (
                  <SelectItem key={act.value} value={act.value} className="text-xs">
                    <div className="flex flex-col">
                      <span>{act.label}</span>
                    </div>
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <p className="text-[10px] text-muted-foreground">
              조건이 만족되면 이 필드를 {ACTIONS.find(a => a.value === action)?.label}합니다
            </p>
          </div>

          {/* 미리보기 */}
          {field && (
            <div className="mt-3 rounded bg-slate-100 p-2">
              <p className="text-[10px] font-medium text-slate-600">설정 요약:</p>
              <p className="text-[11px] text-slate-800">
                "{selectableFields.find(f => f.id === field)?.label || field}" 필드가{" "}
                <span className="font-medium">
                  {operator === "isEmpty" ? "비어있으면" :
                   operator === "isNotEmpty" ? "값이 있으면" :
                   `"${value}"${operator === "=" ? "이면" : 
                    operator === "!=" ? "이 아니면" :
                    operator === ">" ? "보다 크면" :
                    operator === "<" ? "보다 작으면" :
                    operator === "in" ? "에 포함되면" : "에 포함되지 않으면"}`}
                </span>{" "}
                → 이 필드를{" "}
                <span className="font-medium text-amber-600">
                  {action === "show" ? "표시" :
                   action === "hide" ? "숨김" :
                   action === "enable" ? "활성화" : "비활성화"}
                </span>
              </p>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

export default ConditionalConfigPanel;

