/**
 * 폼 검증 상태 관리 훅
 * 실시간 검증과 사용자 피드백을 위한 커스텀 훅
 */

import { useState, useCallback, useEffect, useRef } from "react";
import { ComponentData, ColumnInfo, ScreenDefinition } from "@/types/screen";
import { validateFormData, ValidationResult, ValidationError, ValidationWarning } from "@/lib/utils/formValidation";
import { enhancedFormService, SaveContext, EnhancedSaveResult } from "@/lib/services/enhancedFormService";
import { useToast } from "@/hooks/use-toast";

// 검증 상태
export type ValidationStatus = "idle" | "validating" | "valid" | "invalid";

// 필드별 검증 상태
export interface FieldValidationState {
  status: ValidationStatus;
  error?: ValidationError;
  warning?: ValidationWarning;
  lastValidated?: Date;
}

// 폼 검증 상태
export interface FormValidationState {
  status: ValidationStatus;
  isValid: boolean;
  errors: ValidationError[];
  warnings: ValidationWarning[];
  fieldStates: Record<string, FieldValidationState>;
  lastValidated?: Date;
  validationCount: number;
}

// 저장 상태
export interface SaveState {
  status: "idle" | "saving" | "success" | "error";
  message?: string;
  result?: EnhancedSaveResult;
  lastSaved?: Date;
}

// 훅 옵션
export interface UseFormValidationOptions {
  enableRealTimeValidation?: boolean;
  validationDelay?: number; // debounce 지연시간 (ms)
  enableAutoSave?: boolean;
  autoSaveDelay?: number; // 자동저장 지연시간 (ms)
  showToastMessages?: boolean;
  validateOnMount?: boolean;
}

// 훅 반환값
export interface UseFormValidationReturn {
  // 상태
  validationState: FormValidationState;
  saveState: SaveState;

  // 액션
  validateForm: () => Promise<ValidationResult>;
  validateField: (fieldName: string, value: any) => Promise<void>;
  saveForm: () => Promise<boolean>;
  clearValidation: () => void;

  // 유틸리티
  getFieldError: (fieldName: string) => ValidationError | undefined;
  getFieldWarning: (fieldName: string) => ValidationWarning | undefined;
  hasFieldError: (fieldName: string) => boolean;
  isFieldValid: (fieldName: string) => boolean;
  canSave: boolean;
}

/**
 * 폼 검증 관리 훅
 */
export const useFormValidation = (
  formData: Record<string, any>,
  components: ComponentData[],
  tableColumns: ColumnInfo[],
  screenInfo: ScreenDefinition,
  options: UseFormValidationOptions = {},
): UseFormValidationReturn => {
  const {
    enableRealTimeValidation = true,
    validationDelay = 500,
    enableAutoSave = false,
    autoSaveDelay = 2000,
    showToastMessages = true,
    validateOnMount = false,
  } = options;

  const { toast } = useToast();

  // 상태
  const [validationState, setValidationState] = useState<FormValidationState>({
    status: "idle",
    isValid: false,
    errors: [],
    warnings: [],
    fieldStates: {},
    validationCount: 0,
  });

  const [saveState, setSaveState] = useState<SaveState>({
    status: "idle",
  });

  // 타이머 참조
  const validationTimer = useRef<NodeJS.Timeout>();
  const autoSaveTimer = useRef<NodeJS.Timeout>();
  const lastValidationData = useRef<string>("");

  /**
   * 전체 폼 검증
   */
  const validateForm = useCallback(async (): Promise<ValidationResult> => {
    if (!screenInfo?.tableName) {
      return {
        isValid: false,
        errors: [
          {
            field: "form",
            code: "NO_TABLE",
            message: "테이블명이 설정되지 않았습니다.",
            severity: "error",
          },
        ],
        warnings: [],
      };
    }

    setValidationState((prev) => ({
      ...prev,
      status: "validating",
    }));

    try {
      const result = await validateFormData(formData, components, tableColumns, screenInfo.tableName);

      // 필드별 상태 업데이트
      const fieldStates: Record<string, FieldValidationState> = {};

      // 기존 필드 상태 초기화
      Object.keys(formData).forEach((fieldName) => {
        fieldStates[fieldName] = {
          status: "valid",
          lastValidated: new Date(),
        };
      });

      // 오류가 있는 필드 업데이트
      result.errors.forEach((error) => {
        fieldStates[error.field] = {
          status: "invalid",
          error,
          lastValidated: new Date(),
        };
      });

      // 경고가 있는 필드 업데이트
      result.warnings.forEach((warning) => {
        if (fieldStates[warning.field]) {
          fieldStates[warning.field].warning = warning;
        } else {
          fieldStates[warning.field] = {
            status: "valid",
            warning,
            lastValidated: new Date(),
          };
        }
      });

      setValidationState((prev) => ({
        status: result.isValid ? "valid" : "invalid",
        isValid: result.isValid,
        errors: result.errors,
        warnings: result.warnings,
        fieldStates,
        lastValidated: new Date(),
        validationCount: prev.validationCount + 1,
      }));

      if (showToastMessages) {
        if (result.isValid && result.warnings.length > 0) {
          toast({
            title: "검증 완료",
            description: `${result.warnings.length}개의 경고가 있습니다.`,
            variant: "default",
          });
        } else if (!result.isValid) {
          toast({
            title: "검증 실패",
            description: `${result.errors.length}개의 오류를 수정해주세요.`,
            variant: "destructive",
          });
        }
      }

      return result;
    } catch (error) {
      console.error("❌ 폼 검증 중 오류:", error);

      const errorResult: ValidationResult = {
        isValid: false,
        errors: [
          {
            field: "form",
            code: "VALIDATION_ERROR",
            message: `검증 중 오류가 발생했습니다: ${error}`,
            severity: "error",
          },
        ],
        warnings: [],
      };

      setValidationState((prev) => ({
        ...prev,
        status: "invalid",
        isValid: false,
        errors: errorResult.errors,
        warnings: [],
        lastValidated: new Date(),
        validationCount: prev.validationCount + 1,
      }));

      return errorResult;
    }
  }, [formData, components, tableColumns, screenInfo, showToastMessages, toast]);

  /**
   * 개별 필드 검증
   */
  const validateField = useCallback(
    async (fieldName: string, value: any): Promise<void> => {
      const component = components.find((c) => (c as any).columnName === fieldName || c.id === fieldName);

      if (!component || component.type !== "widget") return;

      setValidationState((prev) => ({
        ...prev,
        fieldStates: {
          ...prev.fieldStates,
          [fieldName]: {
            ...prev.fieldStates[fieldName],
            status: "validating",
          },
        },
      }));

      // 개별 필드 검증 로직
      // (실제 구현에서는 validateFieldValue 함수 사용)

      setValidationState((prev) => ({
        ...prev,
        fieldStates: {
          ...prev.fieldStates,
          [fieldName]: {
            status: "valid",
            lastValidated: new Date(),
          },
        },
      }));
    },
    [components],
  );

  /**
   * 폼 저장
   */
  const saveForm = useCallback(async (): Promise<boolean> => {
    if (!validationState.isValid) {
      if (showToastMessages) {
        toast({
          title: "저장 실패",
          description: "검증 오류를 먼저 수정해주세요.",
          variant: "destructive",
        });
      }
      return false;
    }

    setSaveState({ status: "saving" });

    try {
      const saveContext: SaveContext = {
        tableName: screenInfo.tableName,
        screenInfo,
        components,
        formData,
        options: {
          transformData: true,
          showProgress: true,
        },
      };

      const result = await enhancedFormService.saveFormData(saveContext);

      setSaveState({
        status: result.success ? "success" : "error",
        message: result.message,
        result,
        lastSaved: new Date(),
      });

      if (showToastMessages) {
        toast({
          title: result.success ? "저장 성공" : "저장 실패",
          description: result.message,
          variant: result.success ? "default" : "destructive",
        });
      }

      return result.success;
    } catch (error) {
      console.error("❌ 폼 저장 중 오류:", error);

      setSaveState({
        status: "error",
        message: `저장 중 오류가 발생했습니다: ${error}`,
        lastSaved: new Date(),
      });

      if (showToastMessages) {
        toast({
          title: "저장 실패",
          description: "저장 중 오류가 발생했습니다.",
          variant: "destructive",
        });
      }

      return false;
    }
  }, [validationState.isValid, screenInfo, components, formData, showToastMessages, toast]);

  /**
   * 검증 상태 초기화
   */
  const clearValidation = useCallback(() => {
    setValidationState({
      status: "idle",
      isValid: false,
      errors: [],
      warnings: [],
      fieldStates: {},
      validationCount: 0,
    });

    setSaveState({ status: "idle" });
  }, []);

  /**
   * 필드 오류 조회
   */
  const getFieldError = useCallback(
    (fieldName: string): ValidationError | undefined => {
      return validationState.fieldStates[fieldName]?.error;
    },
    [validationState.fieldStates],
  );

  /**
   * 필드 경고 조회
   */
  const getFieldWarning = useCallback(
    (fieldName: string): ValidationWarning | undefined => {
      return validationState.fieldStates[fieldName]?.warning;
    },
    [validationState.fieldStates],
  );

  /**
   * 필드 오류 여부 확인
   */
  const hasFieldError = useCallback(
    (fieldName: string): boolean => {
      return validationState.fieldStates[fieldName]?.status === "invalid";
    },
    [validationState.fieldStates],
  );

  /**
   * 필드 유효성 확인
   */
  const isFieldValid = useCallback(
    (fieldName: string): boolean => {
      const fieldState = validationState.fieldStates[fieldName];
      return fieldState?.status === "valid" || !fieldState;
    },
    [validationState.fieldStates],
  );

  // 저장 가능 여부
  const canSave = validationState.isValid && saveState.status !== "saving" && Object.keys(formData).length > 0;

  // 실시간 검증 (debounced)
  useEffect(() => {
    if (!enableRealTimeValidation) return;

    const currentDataString = JSON.stringify(formData);
    if (currentDataString === lastValidationData.current) return;

    // 이전 타이머 클리어
    if (validationTimer.current) {
      clearTimeout(validationTimer.current);
    }

    // 새 타이머 설정
    validationTimer.current = setTimeout(() => {
      lastValidationData.current = currentDataString;
      validateForm();
    }, validationDelay);

    return () => {
      if (validationTimer.current) {
        clearTimeout(validationTimer.current);
      }
    };
  }, [formData, enableRealTimeValidation, validationDelay, validateForm]);

  // 자동 저장
  useEffect(() => {
    if (!enableAutoSave || !validationState.isValid) return;

    // 이전 타이머 클리어
    if (autoSaveTimer.current) {
      clearTimeout(autoSaveTimer.current);
    }

    // 새 타이머 설정
    autoSaveTimer.current = setTimeout(() => {
      saveForm();
    }, autoSaveDelay);

    return () => {
      if (autoSaveTimer.current) {
        clearTimeout(autoSaveTimer.current);
      }
    };
  }, [validationState.isValid, enableAutoSave, autoSaveDelay, saveForm]);

  // 마운트 시 검증
  useEffect(() => {
    if (validateOnMount && Object.keys(formData).length > 0) {
      validateForm();
    }
  }, [validateOnMount]); // formData는 의존성에서 제외 (무한 루프 방지)

  // 클린업
  useEffect(() => {
    return () => {
      if (validationTimer.current) {
        clearTimeout(validationTimer.current);
      }
      if (autoSaveTimer.current) {
        clearTimeout(autoSaveTimer.current);
      }
    };
  }, []);

  return {
    validationState,
    saveState,
    validateForm,
    validateField,
    saveForm,
    clearValidation,
    getFieldError,
    getFieldWarning,
    hasFieldError,
    isFieldValid,
    canSave,
  };
};
