import { createContext, useCallback, useContext, useRef, useState, type ReactNode } from 'react'
import { Modal } from './Modal'

export type ConfirmOptions = {
  title?: string
  message: string
  confirmLabel?: string
  cancelLabel?: string
  danger?: boolean
}

type ConfirmFn = (opts: ConfirmOptions) => Promise<boolean>

const ConfirmContext = createContext<ConfirmFn | null>(null)

// Drop-in async replacement for window.confirm(): `await confirm({ message })`.
export function useConfirm(): ConfirmFn {
  const ctx = useContext(ConfirmContext)
  if (!ctx) throw new Error('useConfirm must be used within <ConfirmProvider>')
  return ctx
}

export function ConfirmProvider({ children }: { children: ReactNode }) {
  const [opts, setOpts] = useState<ConfirmOptions | null>(null)
  const resolver = useRef<(v: boolean) => void>(() => {})

  const confirm = useCallback<ConfirmFn>((o) => {
    setOpts(o)
    return new Promise<boolean>((resolve) => {
      resolver.current = resolve
    })
  }, [])

  const finish = useCallback((result: boolean) => {
    resolver.current(result)
    resolver.current = () => {}
    setOpts(null)
  }, [])

  return (
    <ConfirmContext.Provider value={confirm}>
      {children}
      <Modal open={opts !== null} title={opts?.title ?? 'Confirm'} onClose={() => finish(false)}>
        {opts && (
          <div
            className="confirm-body"
            onKeyDown={(e) => {
              if (e.key === 'Enter') {
                e.preventDefault()
                finish(true)
              }
            }}
          >
            <p className="confirm-message">{opts.message}</p>
            <div className="modal-actions">
              <button type="button" className="btn" onClick={() => finish(false)}>
                {opts.cancelLabel ?? 'Cancel'}
              </button>
              <button
                type="button"
                className={opts.danger ? 'btn btn-danger' : 'btn btn-primary'}
                data-modal-autofocus
                onClick={() => finish(true)}
              >
                {opts.confirmLabel ?? 'Confirm'}
              </button>
            </div>
          </div>
        )}
      </Modal>
    </ConfirmContext.Provider>
  )
}
