import React, { createContext, useContext, useState, useCallback, useMemo } from 'react';
import { Alert, Platform } from 'react-native';

import { ConfirmDialog, type IConfirmDialogButton } from '@/components/common/ConfirmDialog';

interface DialogConfig {
  title: string;
  message: string;
  buttons: IConfirmDialogButton[];
}

interface DialogContextValue {
  /**
   * Show a simple alert with an OK button.
   */
  showAlert: (title: string, message: string, onOk?: () => void) => void;

  /**
   * Show a confirm dialog with Cancel and a custom action button.
   */
  showConfirm: (
    title: string,
    message: string,
    confirmText: string,
    onConfirm: () => void | Promise<void>,
    options?: {
      cancelText?: string;
      confirmStyle?: 'default' | 'destructive';
    }
  ) => void;

  /**
   * Show a custom dialog with any buttons.
   */
  showDialog: (title: string, message: string, buttons: IConfirmDialogButton[]) => void;

  /**
   * Hide the current dialog.
   */
  hideDialog: () => void;
}

const DialogContext = createContext<DialogContextValue | null>(null);

/**
 * Hook to access the dialog service.
 *
 * Usage:
 * ```tsx
 * const { showAlert, showConfirm } = useDialog();
 *
 * // Simple alert
 * showAlert(t('common.error'), t('auth.errors.enterPassword'));
 *
 * // Confirm dialog
 * showConfirm(
 *   t('items.deleteItem'),
 *   t('items.deleteConfirm'),
 *   t('common.delete'),
 *   async () => { await deleteItem(); },
 *   { confirmStyle: 'destructive' }
 * );
 * ```
 */
export function useDialog(): DialogContextValue {
  const context = useContext(DialogContext);
  if (!context) {
    throw new Error('useDialog must be used within a DialogProvider');
  }
  return context;
}

interface DialogProviderProps {
  children: React.ReactNode;
}

/**
 * Provider component that enables the dialog service.
 * Add this near the root of your app (e.g., in _layout.tsx).
 */
export function DialogProvider({ children }: DialogProviderProps): React.ReactNode {
  const [dialogConfig, setDialogConfig] = useState<DialogConfig | null>(null);

  /**
   * Hide the dialog.
   */
  const hideDialog = useCallback((): void => {
    setDialogConfig(null);
  }, []);

  /**
   * Show a simple alert with an OK button.
   */
  const showAlert = useCallback((title: string, message: string, onOk?: () => void): void => {
    // On iOS, use native Alert for simple alerts too
    if (Platform.OS === 'ios') {
      Alert.alert(title, message, [{
        text: 'OK',
        style: 'default',
        onPress: onOk,
      }]);
      return;
    }

    setDialogConfig({
      title,
      message,
      buttons: [{
        text: 'OK',
        style: 'default',
        onPress: (): void => {
          onOk?.();
          setDialogConfig(null);
        },
      }],
    });
  }, []);

  /**
   * Show a confirm dialog with Cancel and action button.
   */
  const showConfirm = useCallback((
    title: string,
    message: string,
    confirmText: string,
    onConfirm: () => void | Promise<void>,
    options?: {
      cancelText?: string;
      confirmStyle?: 'default' | 'destructive';
    }
  ): void => {
    // On iOS, use native Alert
    if (Platform.OS === 'ios') {
      Alert.alert(title, message, [
        { text: options?.cancelText ?? 'Cancel', style: 'cancel' },
        {
          text: confirmText,
          style: options?.confirmStyle ?? 'default',
          onPress: () => { onConfirm(); },
        },
      ]);
      return;
    }

    setDialogConfig({
      title,
      message,
      buttons: [
        {
          text: options?.cancelText ?? 'Cancel',
          style: 'cancel',
          onPress: (): void => setDialogConfig(null),
        },
        {
          text: confirmText,
          style: options?.confirmStyle ?? 'default',
          onPress: async (): Promise<void> => {
            await onConfirm();
            setDialogConfig(null);
          },
        },
      ],
    });
  }, []);

  /**
   * Show a custom dialog with any buttons.
   */
  const showDialog = useCallback((title: string, message: string, buttons: IConfirmDialogButton[]): void => {
    // On iOS, use native Alert
    if (Platform.OS === 'ios') {
      const alertButtons = buttons.map(btn => ({
        text: btn.text,
        style: btn.style,
        onPress: () => { btn.onPress?.(); },
      }));
      Alert.alert(title, message, alertButtons);
      return;
    }

    // Wrap button onPress to auto-close dialog
    const wrappedButtons = buttons.map(btn => ({
      ...btn,
      onPress: async (): Promise<void> => {
        await btn.onPress?.();
        setDialogConfig(null);
      },
    }));

    setDialogConfig({ title, message, buttons: wrappedButtons });
  }, []);

  const contextValue = useMemo(() => ({
    showAlert,
    showConfirm,
    showDialog,
    hideDialog,
  }), [showAlert, showConfirm, showDialog, hideDialog]);

  return (
    <DialogContext.Provider value={contextValue}>
      {children}
      {/* Only render on Android since iOS uses native Alert */}
      {Platform.OS !== 'ios' && (
        <ConfirmDialog
          isVisible={dialogConfig !== null}
          title={dialogConfig?.title ?? ''}
          message={dialogConfig?.message ?? ''}
          buttons={dialogConfig?.buttons ?? []}
          onClose={hideDialog}
        />
      )}
    </DialogContext.Provider>
  );
}

export default DialogProvider;
