"use client";

/**
 * UnifiedFormContext
 * 
 * Unified 컴포넌트들이 폼 상태를 공유하고
 * 조건부 로직을 처리할 수 있도록 하는 Context
 */

import React, { createContext, useContext, useState, useCallback, useMemo } from "react";
import { ConditionalConfig, CascadingConfig } from "@/types/unified-components";

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

export interface FormFieldState {
  value: unknown;
  disabled?: boolean;
  visible?: boolean;
  error?: string;
}

export interface FormState {
  [fieldId: string]: FormFieldState;
}

export interface UnifiedFormContextValue {
  // 폼 상태
  formData: Record<string, unknown>;
  fieldStates: FormState;
  
  // 값 관리
  getValue: (fieldId: string) => unknown;
  setValue: (fieldId: string, value: unknown) => void;
  setValues: (values: Record<string, unknown>) => void;
  
  // 조건부 로직
  evaluateCondition: (fieldId: string, config?: ConditionalConfig) => {
    visible: boolean;
    disabled: boolean;
  };
  
  // 연쇄 관계
  getCascadingFilter: (config?: CascadingConfig) => unknown;
  
  // 필드 등록
  registerField: (fieldId: string, initialValue?: unknown) => void;
  unregisterField: (fieldId: string) => void;
}

// ===== Context 생성 =====

const UnifiedFormContext = createContext<UnifiedFormContextValue | null>(null);

// ===== 조건 평가 함수 =====

function evaluateOperator(
  fieldValue: unknown,
  operator: ConditionalConfig["operator"],
  conditionValue: unknown
): boolean {
  switch (operator) {
    case "=":
      return fieldValue === conditionValue;
    case "!=":
      return fieldValue !== conditionValue;
    case ">":
      return Number(fieldValue) > Number(conditionValue);
    case "<":
      return Number(fieldValue) < Number(conditionValue);
    case "in":
      if (Array.isArray(conditionValue)) {
        return conditionValue.includes(fieldValue);
      }
      return false;
    case "notIn":
      if (Array.isArray(conditionValue)) {
        return !conditionValue.includes(fieldValue);
      }
      return true;
    case "isEmpty":
      return fieldValue === null || fieldValue === undefined || fieldValue === "" || 
        (Array.isArray(fieldValue) && fieldValue.length === 0);
    case "isNotEmpty":
      return fieldValue !== null && fieldValue !== undefined && fieldValue !== "" &&
        !(Array.isArray(fieldValue) && fieldValue.length === 0);
    default:
      return true;
  }
}

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

interface UnifiedFormProviderProps {
  children: React.ReactNode;
  initialValues?: Record<string, unknown>;
  onChange?: (formData: Record<string, unknown>) => void;
}

export function UnifiedFormProvider({
  children,
  initialValues = {},
  onChange,
}: UnifiedFormProviderProps) {
  const [formData, setFormData] = useState<Record<string, unknown>>(initialValues);
  const [fieldStates, setFieldStates] = useState<FormState>({});

  // 값 가져오기
  const getValue = useCallback((fieldId: string): unknown => {
    return formData[fieldId];
  }, [formData]);

  // 단일 값 설정
  const setValue = useCallback((fieldId: string, value: unknown) => {
    setFormData(prev => {
      const newData = { ...prev, [fieldId]: value };
      onChange?.(newData);
      return newData;
    });
  }, [onChange]);

  // 여러 값 한 번에 설정
  const setValues = useCallback((values: Record<string, unknown>) => {
    setFormData(prev => {
      const newData = { ...prev, ...values };
      onChange?.(newData);
      return newData;
    });
  }, [onChange]);

  // 조건 평가
  const evaluateCondition = useCallback((
    fieldId: string,
    config?: ConditionalConfig
  ): { visible: boolean; disabled: boolean } => {
    // 조건부 설정이 없으면 기본값 반환
    if (!config || !config.enabled) {
      return { visible: true, disabled: false };
    }

    const { field, operator, value, action } = config;
    const fieldValue = formData[field];
    
    // 조건 평가
    const conditionMet = evaluateOperator(fieldValue, operator, value);

    // 액션에 따른 결과
    switch (action) {
      case "show":
        return { visible: conditionMet, disabled: false };
      case "hide":
        return { visible: !conditionMet, disabled: false };
      case "enable":
        return { visible: true, disabled: !conditionMet };
      case "disable":
        return { visible: true, disabled: conditionMet };
      default:
        return { visible: true, disabled: false };
    }
  }, [formData]);

  // 연쇄 관계 필터값 가져오기
  const getCascadingFilter = useCallback((config?: CascadingConfig): unknown => {
    if (!config) return undefined;
    return formData[config.parentField];
  }, [formData]);

  // 필드 등록
  const registerField = useCallback((fieldId: string, initialValue?: unknown) => {
    if (initialValue !== undefined && formData[fieldId] === undefined) {
      setFormData(prev => ({ ...prev, [fieldId]: initialValue }));
    }
    setFieldStates(prev => ({
      ...prev,
      [fieldId]: { value: initialValue, visible: true, disabled: false },
    }));
  }, [formData]);

  // 필드 해제
  const unregisterField = useCallback((fieldId: string) => {
    setFieldStates(prev => {
      const next = { ...prev };
      delete next[fieldId];
      return next;
    });
  }, []);

  // Context 값
  const contextValue = useMemo<UnifiedFormContextValue>(() => ({
    formData,
    fieldStates,
    getValue,
    setValue,
    setValues,
    evaluateCondition,
    getCascadingFilter,
    registerField,
    unregisterField,
  }), [
    formData,
    fieldStates,
    getValue,
    setValue,
    setValues,
    evaluateCondition,
    getCascadingFilter,
    registerField,
    unregisterField,
  ]);

  return (
    <UnifiedFormContext.Provider value={contextValue}>
      {children}
    </UnifiedFormContext.Provider>
  );
}

// ===== 커스텀 훅 =====

export function useUnifiedForm(): UnifiedFormContextValue {
  const context = useContext(UnifiedFormContext);
  if (!context) {
    throw new Error("useUnifiedForm must be used within UnifiedFormProvider");
  }
  return context;
}

/**
 * 개별 필드 훅 - 조건부 상태와 값을 한 번에 관리
 */
export function useUnifiedField(
  fieldId: string,
  conditional?: ConditionalConfig
): {
  value: unknown;
  setValue: (value: unknown) => void;
  visible: boolean;
  disabled: boolean;
} {
  const { getValue, setValue, evaluateCondition } = useUnifiedForm();
  
  const value = getValue(fieldId);
  const { visible, disabled } = evaluateCondition(fieldId, conditional);
  
  const handleSetValue = useCallback((newValue: unknown) => {
    setValue(fieldId, newValue);
  }, [fieldId, setValue]);
  
  return {
    value,
    setValue: handleSetValue,
    visible,
    disabled,
  };
}

/**
 * 연쇄 선택 훅 - 부모 필드 값에 따라 옵션 필터링
 */
export function useCascadingOptions<T extends { parentValue?: unknown }>(
  options: T[],
  cascading?: CascadingConfig
): T[] {
  const { getCascadingFilter } = useUnifiedForm();
  
  if (!cascading) return options;
  
  const parentValue = getCascadingFilter(cascading);
  
  if (parentValue === undefined || parentValue === null || parentValue === "") {
    return []; // 부모 값이 없으면 빈 배열
  }
  
  // parentValue로 필터링
  return options.filter(opt => opt.parentValue === parentValue);
}

export default UnifiedFormContext;


