'use client'

import { useEffect, useRef, useState } from 'react'
import { useActionState } from 'react'
import { useFormStatus } from 'react-dom'
import { toast } from 'sonner'
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
  DialogClose,
} from '@/components/ui/dialog'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
import { PrioritySelect } from '@/components/shared/priority-select'
import { createPbiAction, updatePbiAction } from '@/actions/pbis'

export interface PbiDialogPbi {
  id: string
  title: string
  priority: number
  description?: string | null
  code?: string | null
}

type CreateState = { mode: 'create'; productId: string; defaultPriority?: number }
type EditState = { mode: 'edit'; pbi: PbiDialogPbi; productId: string }
export type PbiDialogState = CreateState | EditState

interface PbiDialogProps {
  state: PbiDialogState | null
  onClose: () => void
}

function SubmitButton({ label }: { label: string }) {
  const { pending } = useFormStatus()
  return (
    <Button type="submit" disabled={pending}>
      {pending ? '…' : label}
    </Button>
  )
}

export function PbiDialog({ state, onClose }: PbiDialogProps) {
  const isEdit = state?.mode === 'edit'
  const pbi = isEdit ? state.pbi : null

  const initialPriority = isEdit ? pbi!.priority : (state?.defaultPriority ?? 2)
  const [priority, setPriority] = useState<number>(initialPriority)

  // Sync priority when dialog opens for a different PBI or switches create/edit mode
  useEffect(() => {
    if (state) {
      // eslint-disable-next-line react-hooks/set-state-in-effect
      setPriority(isEdit ? (state as EditState).pbi.priority : ((state as CreateState).defaultPriority ?? 2))
    }
  }, [state, isEdit])

  const [createState, createAction] = useActionState(
    async (_prev: unknown, fd: FormData) => {
      const result = await createPbiAction(_prev, fd)
      if (result?.success) { toast.success('PBI aangemaakt'); onClose() }
      else if (typeof result?.error === 'string') toast.error(result.error)
      return result
    },
    undefined
  )

  const [updateState, updateAction] = useActionState(
    async (_prev: unknown, fd: FormData) => {
      const result = await updatePbiAction(_prev, fd)
      if (result?.success) { toast.success('PBI opgeslagen'); onClose() }
      else if (typeof result?.error === 'string') toast.error(result.error)
      return result
    },
    undefined
  )

  const activeState = isEdit ? updateState : createState
  const error = typeof activeState?.error === 'string' ? activeState.error : null
  const fieldError = (field: string) => {
    const err = activeState?.error
    if (!err || typeof err === 'string') return undefined
    return (err as Record<string, string[]>)[field]?.[0]
  }

  const titleRef = useRef<HTMLInputElement>(null)
  useEffect(() => {
    if (state) {
      setTimeout(() => titleRef.current?.focus(), 50)
    }
  }, [state])

  return (
    <Dialog open={!!state} onOpenChange={(open) => { if (!open) onClose() }}>
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle>{isEdit ? 'PBI bewerken' : 'Nieuw PBI'}</DialogTitle>
        </DialogHeader>

        <form key={isEdit ? pbi!.id : 'create'} action={isEdit ? updateAction : createAction} className="grid gap-4">
          {isEdit && <input type="hidden" name="id" value={pbi!.id} />}
          {!isEdit && <input type="hidden" name="productId" value={(state as CreateState | null)?.productId ?? ''} />}
          <input type="hidden" name="priority" value={priority} />

          <div className="grid grid-cols-[6rem_1fr] gap-3">
            <div className="grid gap-1.5">
              <label htmlFor="pbi-code" className="text-sm font-medium">Code</label>
              <Input
                id="pbi-code"
                name="code"
                defaultValue={pbi?.code ?? ''}
                placeholder={isEdit ? '' : 'auto'}
                maxLength={30}
                className={fieldError('code') ? 'font-mono text-sm border-error' : 'font-mono text-sm'}
              />
              {fieldError('code') && <p className="text-xs text-error">{fieldError('code')}</p>}
            </div>
            <div className="grid gap-1.5">
              <label htmlFor="pbi-title" className="text-sm font-medium">Titel</label>
              <Input
                id="pbi-title"
                ref={titleRef}
                name="title"
                defaultValue={pbi?.title ?? ''}
                placeholder="PBI-titel…"
                required
                maxLength={200}
                className={fieldError('title') ? 'border-error' : ''}
              />
              {fieldError('title') && <p className="text-xs text-error">{fieldError('title')}</p>}
            </div>
          </div>

          <div className="grid gap-1.5">
            <label className="text-sm font-medium">Prioriteit</label>
            <PrioritySelect value={priority} onChange={setPriority} />
          </div>

          <div className="grid gap-1.5">
            <label htmlFor="pbi-description" className="text-sm font-medium">
              Beschrijving <span className="text-muted-foreground font-normal">(optioneel)</span>
            </label>
            <Textarea
              id="pbi-description"
              name="description"
              defaultValue={pbi?.description ?? ''}
              placeholder="Korte omschrijving van het PBI…"
              rows={3}
              maxLength={2000}
              className="resize-none"
            />
          </div>

          {error && <p className="text-xs text-error">{error}</p>}

          <DialogFooter>
            <DialogClose render={<Button type="button" variant="outline" />}>
              Annuleren
            </DialogClose>
            <SubmitButton label={isEdit ? 'Opslaan' : 'Aanmaken'} />
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  )
}
