import { Modal as RNModal, Pressable, StyleProp, TextStyle, View, ViewStyle } from "react-native"

import { useAppTheme } from "@/theme/context"
import type { ThemedStyle } from "@/theme/types"
import { s } from "@/utils/responsive"

import { Button } from "./Button"
import { Text, TextProps } from "./Text"

type Presets = "default" | "destructive"

export interface DialogProps {
  /**
   * Whether the dialog is visible.
   */
  visible: boolean
  /**
   * Callback when the dialog is closed.
   */
  onClose: () => void
  /**
   * Dialog preset style.
   * - `default`: Normal dialog with filled confirm button
   * - `destructive`: Dangerous action with red confirm button
   * @default "default"
   */
  preset?: Presets
  /**
   * Title text which is looked up via i18n.
   */
  titleTx?: TextProps["tx"]
  /**
   * Title text to display if not using `titleTx`.
   */
  title?: string
  /**
   * Optional title options to pass to i18n.
   */
  titleTxOptions?: TextProps["txOptions"]
  /**
   * Message text which is looked up via i18n.
   */
  messageTx?: TextProps["tx"]
  /**
   * Message text to display if not using `messageTx`.
   */
  message?: string
  /**
   * Optional message options to pass to i18n.
   */
  messageTxOptions?: TextProps["txOptions"]
  /**
   * Confirm button text which is looked up via i18n.
   * @default "common:ok"
   */
  confirmTx?: TextProps["tx"]
  /**
   * Confirm button text to display if not using `confirmTx`.
   */
  confirmText?: string
  /**
   * Callback when confirm button is pressed.
   */
  onConfirm?: () => void
  /**
   * Cancel button text which is looked up via i18n.
   * @default "common:cancel"
   */
  cancelTx?: TextProps["tx"]
  /**
   * Cancel button text to display if not using `cancelTx`.
   */
  cancelText?: string
  /**
   * Callback when cancel button is pressed. If not provided, cancel button will not be shown.
   */
  onCancel?: () => void
  /**
   * Whether to show the cancel button.
   * @default true (if onCancel is provided)
   */
  showCancel?: boolean
  /**
   * Whether the confirm button is in loading state.
   */
  loading?: boolean
  /**
   * Whether to close the dialog when pressing the overlay.
   * @default false
   */
  closeOnOverlayPress?: boolean
  /**
   * Style overrides for the content container.
   */
  contentStyle?: StyleProp<ViewStyle>
}

/**
 * A simple dialog component for confirmations and alerts.
 * Use this for simple confirm/cancel dialogs. For complex content, use Modal instead.
 * @param {DialogProps} props - The props for the `Dialog` component.
 * @returns {JSX.Element} The rendered `Dialog` component.
 * @example
 * // Simple alert
 * <Dialog
 *   visible={showAlert}
 *   onClose={() => setShowAlert(false)}
 *   title="Success"
 *   message="Operation completed successfully."
 *   onConfirm={() => setShowAlert(false)}
 * />
 *
 * @example
 * // Destructive confirmation
 * <Dialog
 *   visible={showConfirm}
 *   onClose={() => setShowConfirm(false)}
 *   preset="destructive"
 *   titleTx="common:confirm"
 *   messageTx="session:confirmLogoutMessage"
 *   confirmTx="session:logout"
 *   onConfirm={handleLogout}
 *   onCancel={() => setShowConfirm(false)}
 * />
 */
export function Dialog(props: DialogProps) {
  const {
    visible,
    onClose,
    preset = "default",
    titleTx,
    title,
    titleTxOptions,
    messageTx,
    message,
    messageTxOptions,
    confirmTx = "common:ok",
    confirmText,
    onConfirm,
    cancelTx = "common:cancel",
    cancelText,
    onCancel,
    showCancel = !!onCancel,
    loading = false,
    closeOnOverlayPress = false,
    contentStyle: $contentStyleOverride,
  } = props

  const { themed, theme } = useAppTheme()

  const isDestructive = preset === "destructive"

  const handleConfirm = () => {
    onConfirm?.()
  }

  const handleCancel = () => {
    onCancel?.()
    onClose()
  }

  const handleOverlayPress = () => {
    if (closeOnOverlayPress) {
      onClose()
    }
  }

  const $confirmButtonStyle: StyleProp<ViewStyle> = [
    themed($button),
    isDestructive && themed($destructiveButton),
  ]

  return (
    <RNModal
      visible={visible}
      transparent
      animationType="fade"
      onRequestClose={onClose}
      statusBarTranslucent
    >
      <Pressable style={themed($overlay)} onPress={handleOverlayPress}>
        <Pressable
          style={[themed($contentContainer), $contentStyleOverride]}
          onPress={(e) => e.stopPropagation()}
        >
          {/* Title */}
          {(titleTx || title) && (
            <Text
              preset="subheading"
              tx={titleTx}
              text={title}
              txOptions={titleTxOptions}
              style={themed($title)}
            />
          )}

          {/* Message */}
          {(messageTx || message) && (
            <Text
              tx={messageTx}
              text={message}
              txOptions={messageTxOptions}
              style={themed($message)}
            />
          )}

          {/* Buttons */}
          <View style={themed($buttonContainer)}>
            {showCancel && (
              <Button
                preset="default"
                tx={cancelTx}
                text={cancelText}
                style={themed($button)}
                onPress={handleCancel}
                disabled={loading}
              />
            )}
            <Button
              preset={isDestructive ? "default" : "filled"}
              tx={confirmTx}
              text={confirmText}
              style={$confirmButtonStyle}
              textStyle={isDestructive ? { color: theme.colors.error } : undefined}
              onPress={handleConfirm}
              loading={loading}
            />
          </View>
        </Pressable>
      </Pressable>
    </RNModal>
  )
}

const $overlay: ThemedStyle<ViewStyle> = ({ colors, spacing }) => ({
  flex: 1,
  backgroundColor: colors.palette.overlay50,
  justifyContent: "center",
  alignItems: "center",
  padding: spacing.lg,
})

const $contentContainer: ThemedStyle<ViewStyle> = ({ colors, spacing }) => ({
  backgroundColor: colors.background,
  borderRadius: s(12),
  width: "100%",
  maxWidth: s(320),
  paddingHorizontal: spacing.lg,
  paddingVertical: spacing.lg,
})

const $title: ThemedStyle<TextStyle> = ({ spacing }) => ({
  textAlign: "center",
  marginBottom: spacing.sm,
})

const $message: ThemedStyle<TextStyle> = ({ colors, spacing }) => ({
  textAlign: "center",
  color: colors.textDim,
  marginBottom: spacing.lg,
})

const $buttonContainer: ThemedStyle<ViewStyle> = ({ spacing }) => ({
  flexDirection: "row",
  justifyContent: "center",
  gap: spacing.sm,
})

const $button: ThemedStyle<ViewStyle> = () => ({
  flex: 1,
  minWidth: s(100),
})

const $destructiveButton: ThemedStyle<ViewStyle> = ({ colors }) => ({
  borderColor: colors.error,
})
