
import { useCallback, useState } from 'react';
import { useRouter } from 'next/navigation';
import { toast } from 'sonner';

/**
 * API 응답 타입 (Server Action 표준 형식)
 */
export interface ApiResponse<T = unknown> {
  success: boolean;
  data?: T;
  error?: string;
}

/**
 * CRUD 핸들러 반환 타입
 */
export interface CRUDResult {
  success: boolean;
  error?: string;
}

/**
 * 성공 메시지 설정
 */
export interface SuccessMessages {
  create?: string;
  update?: string;
  delete?: string;
}

/**
 * 에러 메시지 설정
 */
export interface ErrorMessages {
  create?: string;
  update?: string;
  delete?: string;
}

export interface UseCRUDHandlersOptions<TCreate = unknown, TUpdate = unknown> {
  /** 등록 API 함수 */
  onCreate?: (data: TCreate) => Promise<ApiResponse>;
  /** 수정 API 함수 */
  onUpdate?: (id: string | number, data: TUpdate) => Promise<ApiResponse>;
  /** 삭제 API 함수 */
  onDelete?: (id: string | number) => Promise<ApiResponse>;
  /** 성공 후 이동할 경로 (절대 경로 권장) */
  successRedirect?: string;
  /** 성공 메시지 (기본값 제공) */
  successMessages?: SuccessMessages;
  /** 에러 메시지 (기본값 제공) */
  errorMessages?: ErrorMessages;
  /** 성공 후 콜백 (리다이렉트 전) */
  onSuccess?: (action: 'create' | 'update' | 'delete') => void | Promise<void>;
  /** 에러 발생 시 콜백 */
  onError?: (action: 'create' | 'update' | 'delete', error: string) => void;
  /** 리다이렉트 비활성화 (커스텀 처리 시) */
  disableRedirect?: boolean;
}

export interface UseCRUDHandlersReturn<TCreate = unknown, TUpdate = unknown> {
  /** 등록 핸들러 */
  handleCreate: (data: TCreate) => Promise<CRUDResult>;
  /** 수정 핸들러 */
  handleUpdate: (id: string | number, data: TUpdate) => Promise<CRUDResult>;
  /** 삭제 핸들러 */
  handleDelete: (id: string | number) => Promise<CRUDResult>;
  /** 등록/수정 통합 핸들러 (isCreateMode에 따라 분기) */
  handleSubmit: (
    data: TCreate | TUpdate,
    options: { isCreateMode: boolean; id?: string | number }
  ) => Promise<CRUDResult>;
  /** 처리 중 상태 */
  isSubmitting: boolean;
  /** 삭제 중 상태 */
  isDeleting: boolean;
}

const DEFAULT_SUCCESS_MESSAGES: SuccessMessages = {
  create: '등록되었습니다.',
  update: '저장되었습니다.',
  delete: '삭제되었습니다.',
};

const DEFAULT_ERROR_MESSAGES: ErrorMessages = {
  create: '등록에 실패했습니다.',
  update: '저장에 실패했습니다.',
  delete: '삭제에 실패했습니다.',
};

/**
 * CRUD 핸들러 통합 훅
 *
 * 등록/수정/삭제 로직을 표준화하고 toast 알림, 리다이렉트를 자동 처리합니다.
 *
 * @example
 * ```tsx
 * const { handleSubmit, handleDelete, isSubmitting } = useCRUDHandlers({
 *   onCreate: createBankAccount,
 *   onUpdate: updateBankAccount,
 *   onDelete: deleteBankAccount,
 *   successRedirect: '/ko/settings/accounts',
 *   successMessages: {
 *     create: '계좌가 등록되었습니다.',
 *     update: '계좌가 수정되었습니다.',
 *     delete: '계좌가 삭제되었습니다.',
 *   },
 * });
 *
 * // 폼 제출
 * const onSubmit = async () => {
 *   const result = await handleSubmit(formData, { isCreateMode, id });
 *   // result.success로 추가 처리 가능
 * };
 *
 * // 삭제
 * const onDelete = async () => {
 *   await handleDelete(id);
 * };
 * ```
 */
export function useCRUDHandlers<TCreate = unknown, TUpdate = unknown>(
  options: UseCRUDHandlersOptions<TCreate, TUpdate> = {}
): UseCRUDHandlersReturn<TCreate, TUpdate> {
  const {
    onCreate,
    onUpdate,
    onDelete,
    successRedirect,
    successMessages = {},
    errorMessages = {},
    onSuccess,
    onError,
    disableRedirect = false,
  } = options;

  const router = useRouter();
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [isDeleting, setIsDeleting] = useState(false);

  // 메시지 병합
  const messages = {
    success: { ...DEFAULT_SUCCESS_MESSAGES, ...successMessages },
    error: { ...DEFAULT_ERROR_MESSAGES, ...errorMessages },
  };

  // 리다이렉트 처리
  const handleRedirect = useCallback(() => {
    if (!disableRedirect && successRedirect) {
      router.push(successRedirect);
    }
  }, [router, successRedirect, disableRedirect]);

  // 등록 핸들러
  const handleCreate = useCallback(
    async (data: TCreate): Promise<CRUDResult> => {
      if (!onCreate) {
        console.warn('[useCRUDHandlers] onCreate is not defined');
        return { success: false, error: 'onCreate is not defined' };
      }

      setIsSubmitting(true);
      try {
        const result = await onCreate(data);

        if (result.success) {
          toast.success(messages.success.create);
          await onSuccess?.('create');
          handleRedirect();
          return { success: true };
        } else {
          const errorMsg = result.error || messages.error.create!;
          toast.error(errorMsg);
          onError?.('create', errorMsg);
          return { success: false, error: errorMsg };
        }
      } catch (err) {
        const errorMsg = err instanceof Error ? err.message : messages.error.create!;
        console.error('[useCRUDHandlers] Create error:', err);
        toast.error(errorMsg);
        onError?.('create', errorMsg);
        return { success: false, error: errorMsg };
      } finally {
        setIsSubmitting(false);
      }
    },
    [onCreate, messages, onSuccess, onError, handleRedirect]
  );

  // 수정 핸들러
  const handleUpdate = useCallback(
    async (id: string | number, data: TUpdate): Promise<CRUDResult> => {
      if (!onUpdate) {
        console.warn('[useCRUDHandlers] onUpdate is not defined');
        return { success: false, error: 'onUpdate is not defined' };
      }

      setIsSubmitting(true);
      try {
        const result = await onUpdate(id, data);

        if (result.success) {
          toast.success(messages.success.update);
          await onSuccess?.('update');
          handleRedirect();
          return { success: true };
        } else {
          const errorMsg = result.error || messages.error.update!;
          toast.error(errorMsg);
          onError?.('update', errorMsg);
          return { success: false, error: errorMsg };
        }
      } catch (err) {
        const errorMsg = err instanceof Error ? err.message : messages.error.update!;
        console.error('[useCRUDHandlers] Update error:', err);
        toast.error(errorMsg);
        onError?.('update', errorMsg);
        return { success: false, error: errorMsg };
      } finally {
        setIsSubmitting(false);
      }
    },
    [onUpdate, messages, onSuccess, onError, handleRedirect]
  );

  // 삭제 핸들러
  const handleDelete = useCallback(
    async (id: string | number): Promise<CRUDResult> => {
      if (!onDelete) {
        console.warn('[useCRUDHandlers] onDelete is not defined');
        return { success: false, error: 'onDelete is not defined' };
      }

      setIsDeleting(true);
      try {
        const result = await onDelete(id);

        if (result.success) {
          toast.success(messages.success.delete);
          await onSuccess?.('delete');
          handleRedirect();
          return { success: true };
        } else {
          const errorMsg = result.error || messages.error.delete!;
          toast.error(errorMsg);
          onError?.('delete', errorMsg);
          return { success: false, error: errorMsg };
        }
      } catch (err) {
        const errorMsg = err instanceof Error ? err.message : messages.error.delete!;
        console.error('[useCRUDHandlers] Delete error:', err);
        toast.error(errorMsg);
        onError?.('delete', errorMsg);
        return { success: false, error: errorMsg };
      } finally {
        setIsDeleting(false);
      }
    },
    [onDelete, messages, onSuccess, onError, handleRedirect]
  );

  // 등록/수정 통합 핸들러
  const handleSubmit = useCallback(
    async (
      data: TCreate | TUpdate,
      { isCreateMode, id }: { isCreateMode: boolean; id?: string | number }
    ): Promise<CRUDResult> => {
      if (isCreateMode) {
        return handleCreate(data as TCreate);
      } else {
        if (!id) {
          const errorMsg = 'ID is required for update';
          toast.error(errorMsg);
          return { success: false, error: errorMsg };
        }
        return handleUpdate(id, data as TUpdate);
      }
    },
    [handleCreate, handleUpdate]
  );

  return {
    handleCreate,
    handleUpdate,
    handleDelete,
    handleSubmit,
    isSubmitting,
    isDeleting,
  };
}
