"use client";

/**
 * 폼 호환성 브릿지 훅
 *
 * 레거시 컴포넌트와 새로운 V2 폼 시스템 간의 호환성을 제공합니다.
 *
 * 사용 시나리오:
 * 1. V2FormProvider 내부에서 사용 → V2 시스템 사용
 * 2. V2FormProvider 없이 사용 → 레거시 방식 사용
 * 3. 두 시스템이 공존할 때 → 양쪽에 모두 전파
 */

import { useCallback, useContext, useMemo } from "react";
import V2FormContext, { useV2FormOptional } from "@/components/v2/V2FormContext";
import { useScreenContext } from "@/contexts/ScreenContext";
import type {
  FormCompatibilityBridge,
  FormCompatibilityOptions,
  SubmitConfig,
  SubmitResult,
  ValidationResult,
  FieldError,
  FormEventDetail,
} from "@/types/v2-form";

/**
 * 폼 호환성 브릿지 훅
 *
 * @param options - 레거시 시스템 연동 옵션
 * @returns 통합된 폼 API
 *
 * @example
 * // 레거시 컴포넌트에서 사용
 * const { getValue, setValue, formData } = useFormCompatibility({
 *   legacyOnFormDataChange: props.onFormDataChange,
 * });
 *
 * // 값 변경 시
 * setValue("fieldName", newValue);
 *
 * // 저장 시
 * const result = await submit({ tableName: "my_table", mode: "insert" });
 */
export function useFormCompatibility(options: FormCompatibilityOptions = {}): FormCompatibilityBridge {
  const { legacyOnFormDataChange, screenContext: externalScreenContext, emitLegacyEvents = true } = options;

  // V2 시스템 (있으면 사용)
  const v2Context = useV2FormOptional();

  // ScreenContext (레거시 시스템)
  const internalScreenContext = useScreenContext();
  const screenContext = externalScreenContext || internalScreenContext;

  // 모드 판별
  const isV2Mode = !!v2Context;
  const isLegacyMode = !v2Context;

  // ===== 값 관리 =====

  /**
   * 필드 값 가져오기
   */
  const getValue = useCallback(
    (field: string): unknown => {
      // V2 시스템 우선
      if (v2Context) {
        return v2Context.getValue(field);
      }

      // ScreenContext 폴백
      if (screenContext?.formData) {
        return screenContext.formData[field];
      }

      return undefined;
    },
    [v2Context, screenContext?.formData],
  );

  /**
   * 필드 값 설정 (모든 시스템에 전파)
   */
  const setValue = useCallback(
    (field: string, value: unknown) => {
      // 1. V2 시스템
      if (v2Context) {
        v2Context.setValue(field, value);
      }

      // 2. ScreenContext (레거시)
      if (screenContext?.updateFormData) {
        screenContext.updateFormData(field, value);
      }

      // 3. 레거시 콜백
      if (legacyOnFormDataChange) {
        legacyOnFormDataChange(field, value);
      }
    },
    [v2Context, screenContext, legacyOnFormDataChange],
  );

  // ===== 폼 데이터 =====

  const formData = useMemo(() => {
    if (v2Context) {
      return v2Context.formData as Record<string, unknown>;
    }
    if (screenContext?.formData) {
      return screenContext.formData as Record<string, unknown>;
    }
    return {};
  }, [v2Context, screenContext?.formData]);

  // ===== 폼 액션 =====

  /**
   * 저장
   */
  const submit = useCallback(
    async (config?: Partial<SubmitConfig>): Promise<SubmitResult> => {
      // V2 시스템이 있으면 그쪽 사용 (레거시 이벤트도 내부적으로 발생시킴)
      if (v2Context) {
        return v2Context.submit(config);
      }

      // 레거시 모드: beforeFormSave 이벤트 발생
      if (emitLegacyEvents && typeof window !== "undefined") {
        const eventDetail: FormEventDetail = { formData: { ...formData } };
        const legacyEvent = new CustomEvent("beforeFormSave", { detail: eventDetail });
        window.dispatchEvent(legacyEvent);

        // 이벤트에서 수집된 데이터 반환 (실제 저장은 외부에서 처리)
        return {
          success: true,
          data: { ...formData, ...eventDetail.formData },
        };
      }

      return { success: true, data: formData };
    },
    [v2Context, formData, emitLegacyEvents],
  );

  /**
   * 초기화
   */
  const reset = useCallback(() => {
    if (v2Context) {
      v2Context.reset();
    }
    // 레거시 모드에서는 특별한 처리 없음 (외부에서 처리)
  }, [v2Context]);

  /**
   * 검증
   */
  const validate = useCallback(async (): Promise<ValidationResult> => {
    if (v2Context) {
      return v2Context.validate();
    }

    // 레거시 모드에서는 항상 valid
    return { valid: true, errors: [] };
  }, [v2Context]);

  // ===== 상태 =====

  const isSubmitting = v2Context?.status.isSubmitting ?? false;
  const isDirty = v2Context?.status.isDirty ?? false;
  const errors = v2Context?.errors ?? [];

  return {
    // 값 관리
    getValue,
    setValue,
    formData,

    // 폼 액션
    submit,
    reset,
    validate,

    // 상태
    isSubmitting,
    isDirty,
    errors,

    // 모드
    isV2Mode,
    isLegacyMode,
  };
}

/**
 * ScreenContext를 사용하는 레거시 컴포넌트를 위한 간편 훅
 * ScreenContext가 없어도 동작 (null 반환하지 않고 빈 객체)
 */
function useScreenContext() {
  // ScreenContext import는 동적으로 처리 (순환 의존성 방지)
  try {
    // eslint-disable-next-line @typescript-eslint/no-require-imports
    const { useScreenContext: useCtx } = require("@/contexts/ScreenContext");
    return useCtx?.() || null;
  } catch {
    return null;
  }
}

/**
 * DynamicComponentRenderer에서 사용하는 통합 onChange 핸들러 생성
 *
 * @example
 * const handleChange = createV2ChangeHandler({
 *   fieldName: "customer_name",
 *   v2Context,
 *   screenContext,
 *   legacyOnFormDataChange: props.onFormDataChange,
 * });
 */
export function createV2ChangeHandler(options: {
  fieldName: string;
  v2Context?: ReturnType<typeof useV2FormOptional>;
  screenContext?: { updateFormData?: (field: string, value: unknown) => void };
  legacyOnFormDataChange?: (field: string, value: unknown) => void;
}): (value: unknown) => void {
  const { fieldName, v2Context, screenContext, legacyOnFormDataChange } = options;

  return (value: unknown) => {
    // 1. V2 시스템
    if (v2Context) {
      v2Context.setValue(fieldName, value);
    }

    // 2. ScreenContext
    if (screenContext?.updateFormData) {
      screenContext.updateFormData(fieldName, value);
    }

    // 3. 레거시 콜백
    if (legacyOnFormDataChange) {
      legacyOnFormDataChange(fieldName, value);
    }
  };
}

/**
 * 레거시 beforeFormSave 이벤트 리스너 등록 훅
 *
 * 리피터 컴포넌트 등에서 저장 시 데이터를 수집하기 위해 사용
 *
 * @example
 * useBeforeFormSave((event) => {
 *   event.detail.formData["repeater_field"] = myRepeaterData;
 * });
 */
export function useBeforeFormSave(handler: (event: CustomEvent<FormEventDetail>) => void, deps: unknown[] = []) {
  const stableHandler = useCallback(handler, deps);

  // 이벤트 리스너 등록
  if (typeof window !== "undefined") {
    // useEffect 내에서 처리해야 하지만, 훅의 단순성을 위해 여기서 처리
    // 실제 사용 시에는 컴포넌트에서 useEffect로 감싸서 사용
  }

  return stableHandler;
}

export default useFormCompatibility;
