import { useToastController } from '@tamagui/toast'
import { useState } from 'react'
import type { ActIntent, CommitIntent } from '../intents'
import { ICON_SIZE_BOLD, MenuIconButton, MenuPrimaryButton } from '../MenuBar'
import { ConfirmDialog } from '../overlays/ConfirmDialog'
import type { MenuPrimary } from '../types'

// renderAct — act/commit intent with busy/disabled/destructive states. Wires
// the shared confirm dialog and toast feedback so screens don't reimplement
// either flow.

export function RenderAct({
  intent,
  reduceMotion,
  size,
  tint,
}: {
  intent: ActIntent
  reduceMotion?: boolean
  size?: number
  tint?: string
}) {
  const toast = useToastController()
  const [confirming, setConfirming] = useState(false)

  const run = async () => {
    try {
      await Promise.resolve(intent.onPress())
      if (intent.feedback?.success) {
        toast.show(intent.feedback.success, { preset: 'success' })
      }
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err)
      toast.show(intent.feedback?.error ?? msg, { preset: 'error' })
    }
  }

  const disabled = intent.state === 'disabled' || intent.state === 'busy'

  const onPress = () => {
    if (disabled) return
    if (intent.confirm) {
      setConfirming(true)
      return
    }
    void run()
  }

  const icon = intent.state === 'busy' ? 'loader' : intent.icon

  return (
    <>
      <MenuIconButton
        icon={icon}
        onPress={onPress}
        disabled={disabled}
        selected={intent.toggled}
        accessibilityLabel={intent.accessibilityLabel ?? intent.label}
        accessibilityHint={intent.accessibilityHint}
        reduceMotion={reduceMotion}
        size={size}
        tint={intent.destructive ? undefined : tint}
      />
      <ConfirmDialog
        open={confirming}
        onOpenChange={setConfirming}
        title={intent.confirmTitle ?? intent.label}
        message={intent.confirm ?? ''}
        confirmLabel={intent.confirmLabel ?? intent.label}
        destructive={intent.destructive}
        onConfirm={run}
      />
    </>
  )
}

// Render a commit (primary) pill. Commit is an act with `weight: 'primary'`.
export function RenderCommit({
  intent,
  reduceMotion,
  boldText,
}: {
  intent: ActIntent | CommitIntent
  reduceMotion?: boolean
  boldText?: boolean
}) {
  const toast = useToastController()
  const [confirming, setConfirming] = useState(false)

  const run = async () => {
    try {
      await Promise.resolve(intent.onPress())
      if (intent.feedback?.success) {
        toast.show(intent.feedback.success, { preset: 'success' })
      }
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err)
      toast.show(intent.feedback?.error ?? msg, { preset: 'error' })
    }
  }

  const disabled = intent.state === 'disabled' || intent.state === 'busy'

  const onPress = () => {
    if (disabled) return
    if (intent.confirm) {
      setConfirming(true)
      return
    }
    void run()
  }

  const primary: MenuPrimary = {
    icon: intent.state === 'busy' ? 'loader' : intent.icon,
    accessibilityLabel: intent.accessibilityLabel ?? intent.label,
    accessibilityHint: intent.accessibilityHint,
    onPress,
    disabled,
    selected: intent.toggled,
  }

  return (
    <>
      <MenuPrimaryButton
        primary={primary}
        reduceMotion={reduceMotion}
        boldText={boldText}
      />
      <ConfirmDialog
        open={confirming}
        onOpenChange={setConfirming}
        title={intent.confirmTitle ?? intent.label}
        message={intent.confirm ?? ''}
        confirmLabel={intent.confirmLabel ?? intent.label}
        destructive={intent.destructive}
        onConfirm={run}
      />
    </>
  )
}

// Suppress unused-import warnings for ICON_SIZE_BOLD which is kept for future
// variant wiring.
void ICON_SIZE_BOLD
