'use client';

/**
 * ConfirmDialog - 확인/취소 다이얼로그 공통 컴포넌트
 *
 * 사용 예시:
 * ```tsx
 * <ConfirmDialog
 *   open={showDeleteDialog}
 *   onOpenChange={setShowDeleteDialog}
 *   title="삭제 확인"
 *   description="정말 삭제하시겠습니까?"
 *   confirmText="삭제"
 *   variant="destructive"
 *   loading={isLoading}
 *   onConfirm={handleDelete}
 * />
 * ```
 */

import { ReactNode, useCallback, useState } from 'react';
import { Loader2 } from 'lucide-react';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { cn } from '@/lib/utils';

export type ConfirmDialogVariant = 'default' | 'destructive' | 'warning' | 'success';

export interface ConfirmDialogProps {
  /** 다이얼로그 열림 상태 */
  open: boolean;
  /** 열림 상태 변경 핸들러 */
  onOpenChange: (open: boolean) => void;
  /** 다이얼로그 제목 */
  title: ReactNode;
  /** 다이얼로그 설명 (문자열 또는 ReactNode) */
  description: ReactNode;
  /** 확인 버튼 텍스트 (기본값: '확인') */
  confirmText?: string;
  /** 취소 버튼 텍스트 (기본값: '취소') */
  cancelText?: string;
  /** 버튼 스타일 변형 */
  variant?: ConfirmDialogVariant;
  /** 외부 로딩 상태 (외부에서 관리할 때) */
  loading?: boolean;
  /** 확인 버튼 클릭 핸들러 (Promise 반환 시 내부 로딩 상태 자동 관리) */
  onConfirm: () => void | Promise<void>;
  /** 취소 버튼 클릭 핸들러 (선택사항) */
  onCancel?: () => void;
  /** 확인 버튼 비활성화 여부 */
  confirmDisabled?: boolean;
  /** 아이콘 (제목 옆에 표시) */
  icon?: ReactNode;
}

const variantStyles: Record<ConfirmDialogVariant, string> = {
  default: 'bg-primary text-primary-foreground hover:bg-primary/90',
  destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
  warning: 'bg-orange-600 text-white hover:bg-orange-700',
  success: 'bg-green-600 text-white hover:bg-green-700',
};

export function ConfirmDialog({
  open,
  onOpenChange,
  title,
  description,
  confirmText = '확인',
  cancelText = '취소',
  variant = 'default',
  loading: externalLoading,
  onConfirm,
  onCancel,
  confirmDisabled,
  icon,
}: ConfirmDialogProps) {
  const [internalLoading, setInternalLoading] = useState(false);
  const isLoading = externalLoading ?? internalLoading;

  const handleConfirm = useCallback(async () => {
    const result = onConfirm();

    // Promise인 경우 내부 로딩 상태 관리
    if (result instanceof Promise && externalLoading === undefined) {
      setInternalLoading(true);
      try {
        await result;
      } finally {
        setInternalLoading(false);
      }
    }
  }, [onConfirm, externalLoading]);

  const handleCancel = useCallback(() => {
    onCancel?.();
    onOpenChange(false);
  }, [onCancel, onOpenChange]);

  return (
    <AlertDialog open={open} onOpenChange={onOpenChange}>
      <AlertDialogContent>
        <AlertDialogHeader>
          <AlertDialogTitle className="flex items-center gap-2">
            {icon}
            {title}
          </AlertDialogTitle>
          <AlertDialogDescription asChild={typeof description !== 'string'}>
            {typeof description === 'string' ? (
              description
            ) : (
              <div>{description}</div>
            )}
          </AlertDialogDescription>
        </AlertDialogHeader>
        <AlertDialogFooter>
          <AlertDialogCancel onClick={handleCancel} disabled={isLoading}>
            {cancelText}
          </AlertDialogCancel>
          <AlertDialogAction
            onClick={handleConfirm}
            disabled={isLoading || confirmDisabled}
            className={cn(variantStyles[variant])}
          >
            {isLoading && <Loader2 className="h-4 w-4 mr-2 animate-spin" />}
            {confirmText}
          </AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
}

/**
 * 삭제 확인 다이얼로그 프리셋
 */
export interface DeleteConfirmDialogProps
  extends Omit<ConfirmDialogProps, 'title' | 'confirmText' | 'variant'> {
  /** 삭제 대상 이름 (선택사항) */
  itemName?: string;
  /** 커스텀 제목 (기본: '삭제 확인') */
  title?: string;
}

export function DeleteConfirmDialog({
  itemName,
  description,
  title,
  ...props
}: DeleteConfirmDialogProps) {
  return (
    <ConfirmDialog
      title={title || '삭제 확인'}
      description={
        description ?? (
          <>
            {itemName ? `"${itemName}"을(를) ` : ''}정말 삭제하시겠습니까?
            <br />
            삭제된 데이터는 복구할 수 없습니다.
          </>
        )
      }
      confirmText="삭제"
      variant="destructive"
      {...props}
    />
  );
}

/**
 * 저장 확인 다이얼로그 프리셋
 */
export interface SaveConfirmDialogProps
  extends Omit<ConfirmDialogProps, 'title' | 'confirmText' | 'variant' | 'description'> {
  /** 커스텀 제목 (기본: '저장 확인') */
  title?: string;
  /** 커스텀 설명 (기본: '변경사항을 저장하시겠습니까?') */
  description?: ReactNode;
}

export function SaveConfirmDialog({
  description = '변경사항을 저장하시겠습니까?',
  title,
  ...props
}: SaveConfirmDialogProps) {
  return (
    <ConfirmDialog
      title={title || '저장 확인'}
      description={description}
      confirmText="저장"
      variant="default"
      {...props}
    />
  );
}

/**
 * 취소 확인 다이얼로그 프리셋
 */
export type CancelConfirmDialogProps = Omit<ConfirmDialogProps, 'title' | 'confirmText' | 'variant'>;

export function CancelConfirmDialog({
  description = '작업을 취소하시겠습니까? 변경사항이 저장되지 않습니다.',
  ...props
}: CancelConfirmDialogProps) {
  return (
    <ConfirmDialog
      title="취소 확인"
      description={description}
      confirmText="취소"
      variant="warning"
      {...props}
    />
  );
}

export default ConfirmDialog;
