import {ActionSheetIOS, Alert} from 'react-native'

import {cleanError} from '@/lib/errors'
import {hapticWarning} from '@/lib/haptics'

// the native prompt shapes every screen repeats, behind one typed api so
// no call site hand-maintains button indices or alert arrays

// mutation failure alert carrying the error's friendly copy
export const alertError = (err: unknown): void => {
  Alert.alert(
    'Something went wrong',
    cleanError(err, 'Please try again.'),
  )
}

// plain acknowledgement alert for a completed action
export const alertInfo = (title: string, message?: string): void => {
  Alert.alert(title, message)
}

// destructive confirmation: resolves true when the user confirms
export const confirmDestructive = ({
  title,
  message,
  actionLabel,
  cancelLabel = 'Cancel',
}: {
  title: string
  message: string
  actionLabel: string
  cancelLabel?: string
}): Promise<boolean> =>
  new Promise((resolve) => {
    Alert.alert(title, message, [
      {
        text: cancelLabel,
        style: 'cancel',
        onPress: () => resolve(false),
      },
      {
        text: actionLabel,
        style: 'destructive',
        onPress: () => {
          hapticWarning()
          resolve(true)
        },
      },
    ])
  })

// single text-field prompt: resolves the trimmed value, null on cancel/empty
export const promptText = ({
  title,
  message,
  defaultValue,
  actionLabel = 'Save',
}: {
  title: string
  message?: string
  defaultValue?: string
  actionLabel?: string
}): Promise<string | null> =>
  new Promise((resolve) => {
    Alert.prompt(
      title,
      message,
      [
        {
          text: 'Cancel',
          style: 'cancel',
          onPress: () => resolve(null),
        },
        {
          text: actionLabel,
          onPress: (value?: string) => resolve(value?.trim() || null),
        },
      ],
      'plain-text',
      defaultValue,
    )
  })

export type SheetAction = {
  label: string
  destructive?: boolean
  onPress: () => void
}

// action sheet with derived indices: cancel is always present, destructive
// styling follows the action, handlers are attached to actions directly
export const showActionSheet = (
  actions: SheetAction[],
  {title}: {title?: string} = {},
): void => {
  const destructiveIndexes = actions.flatMap((action, i) =>
    action.destructive ? [i + 1] : [],
  )
  ActionSheetIOS.showActionSheetWithOptions(
    {
      title,
      options: ['Cancel', ...actions.map((a) => a.label)],
      cancelButtonIndex: 0,
      ...(destructiveIndexes.length && {
        destructiveButtonIndex: destructiveIndexes,
      }),
    },
    (index) => {
      if (index > 0) actions[index - 1]?.onPress()
    },
  )
}
