'use client'

import { useState, useTransition } from 'react'
import { useRouter } from 'next/navigation'
import { useForm, Controller } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import TextareaAutosize from 'react-textarea-autosize'
import { toast } from 'sonner'
import { Loader2 } from 'lucide-react'
import type { TaskStatus } from '@prisma/client'
import { taskSchema, type TaskInput } from '@/lib/schemas/task'
import { saveTask, deleteTask } from '@/actions/tasks'
import {
  Dialog,
  DialogContent,
  DialogTitle,
} from '@/components/ui/dialog'
import {
  AlertDialog,
  AlertDialogContent,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogAction,
  AlertDialogCancel,
} from '@/components/ui/alert-dialog'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { CodeBadge } from '@/components/shared/code-badge'
import { MAX_CODE_LENGTH } from '@/lib/code'
import { DemoTooltip } from '@/components/shared/demo-tooltip'
import {
  useDirtyCloseGuard,
  DirtyCloseGuardDialog,
} from '@/components/shared/use-dirty-close-guard'
import { useDialogSubmitShortcut } from '@/components/shared/use-dialog-submit-shortcut'
import {
  entityDialogBodyClasses,
  entityDialogContentClasses,
  entityDialogFooterClasses,
  entityDialogHeaderClasses,
} from '@/components/shared/entity-dialog-layout'
import { PrioritySegmented } from './priority-segmented'
import { StatusSelect } from './status-select'
import { cn } from '@/lib/utils'

export interface TaskDialogTask {
  id: string
  code: string | null
  title: string
  description: string | null
  implementation_plan: string | null
  priority: number
  status: TaskStatus
  created_at: Date
}

interface TaskDialogProps {
  task?: TaskDialogTask
  storyId?: string
  productId: string
  closePath?: string
  onClose?: () => void
  onSaved?: (taskId: string) => void
  isDemo?: boolean
}

function CharCount({ value, max }: { value: string; max: number }) {
  const len = (value ?? '').length
  if (len < Math.floor(max * 0.75)) return null
  return (
    <span className="text-xs text-muted-foreground text-right block mt-1">
      {len} / {max}
    </span>
  )
}

const textareaClass = cn(
  'flex w-full rounded-lg border border-border bg-input-background px-2.5 py-2 text-sm',
  'transition-colors outline-none placeholder:text-muted-foreground resize-none',
  'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50',
  'overflow-y-auto',
)

export function TaskDialog({ task, storyId, productId, closePath, onClose, onSaved, isDemo = false }: TaskDialogProps) {
  const router = useRouter()
  const [isPending, startTransition] = useTransition()
  const [confirmDelete, setConfirmDelete] = useState(false)
  const isEdit = !!task

  const form = useForm<TaskInput>({
    resolver: zodResolver(taskSchema),
    mode: 'onTouched',
    defaultValues: {
      code: task?.code ?? '',
      title: task?.title ?? '',
      description: task?.description ?? '',
      implementation_plan: task?.implementation_plan ?? '',
      priority: task?.priority ?? 3,
      status: task?.status,
    },
  })

  function close() {
    if (onClose) { onClose(); return }
    if (closePath) router.push(closePath)
  }

  const closeGuard = useDirtyCloseGuard(form.formState.isDirty, close)
  const handleKeyDown = useDialogSubmitShortcut(() => form.handleSubmit(onSubmit)())

  function onSubmit(data: TaskInput) {
    startTransition(async () => {
      const result = await saveTask(data, {
        taskId: task?.id,
        storyId,
        productId,
      })

      if (result.ok) {
        toast.success(isEdit ? 'Taak opgeslagen' : 'Taak aangemaakt')
        onSaved?.(result.task.id)
        close()
        return
      }

      if (result.code === 422 && result.error === 'validation') {
        for (const [field, errors] of Object.entries(result.fieldErrors)) {
          form.setError(field as keyof TaskInput, { message: errors[0] })
        }
        const firstError = Object.keys(result.fieldErrors)[0] as keyof TaskInput
        form.setFocus(firstError)
        return
      }

      if (result.code === 403) {
        toast.error(
          result.error === 'demo_readonly'
            ? 'Demo-modus: opslaan uitgeschakeld'
            : 'Geen toegang',
        )
        return
      }

      toast.error('Er ging iets mis. Probeer het opnieuw.', {
        action: { label: 'Opnieuw', onClick: () => form.handleSubmit(onSubmit)() },
      })
    })
  }

  function handleDelete() {
    if (!task) return
    setConfirmDelete(false)
    startTransition(async () => {
      const result = await deleteTask(task.id, { productId })
      if (result.ok) {
        toast.success('Taak verwijderd')
        close()
        return
      }
      if (result.code === 403) {
        toast.error(
          result.error === 'demo_readonly'
            ? 'Demo-modus: verwijderen uitgeschakeld'
            : 'Geen toegang',
        )
        return
      }
      toast.error('Verwijderen mislukt')
    })
  }

  return (
    <>
      <Dialog open onOpenChange={(open) => { if (!open) closeGuard.attemptClose() }}>
        <DialogContent
          showCloseButton={false}
          onKeyDown={handleKeyDown}
          className={entityDialogContentClasses}
        >
          {/* Sticky header */}
          <div className={entityDialogHeaderClasses}>
            <div className="flex items-center gap-2">
              <DialogTitle className="text-xl font-semibold">
                {isEdit ? 'Taak bewerken' : 'Nieuwe taak'}
              </DialogTitle>
              {isEdit && task?.code && <CodeBadge code={task.code} />}
            </div>
            {isEdit && (
              <span className="text-xs text-muted-foreground">
                Aangemaakt:{' '}
                {new Intl.DateTimeFormat('nl-NL', {
                  day: 'numeric',
                  month: 'short',
                  year: 'numeric',
                }).format(new Date(task.created_at))}
              </span>
            )}
          </div>

          {/* Scrollable form body */}
          <div className={entityDialogBodyClasses}>
            {/* Code */}
            <div>
              <label htmlFor="task-code" className="text-sm font-medium mb-2 block">
                Code
              </label>
              <Input
                id="task-code"
                {...form.register('code')}
                aria-invalid={!!form.formState.errors.code}
                placeholder="auto (T-1, T-2, ...)"
                className="font-mono"
                maxLength={MAX_CODE_LENGTH}
                onKeyDown={(e) => { if (e.key === 'Enter') e.preventDefault() }}
              />
              {form.formState.errors.code && (
                <p className="text-xs text-destructive mt-1">
                  {form.formState.errors.code.message}
                </p>
              )}
            </div>

            {/* Title */}
            <div>
              <label htmlFor="task-title" className="text-sm font-medium mb-2 block">
                Titel <span className="text-destructive">*</span>
              </label>
              <Input
                id="task-title"
                {...form.register('title')}
                aria-invalid={!!form.formState.errors.title}
                autoFocus
                placeholder="Taaknaam..."
                className="h-14"
                onKeyDown={(e) => { if (e.key === 'Enter') e.preventDefault() }}
              />
              {form.formState.errors.title && (
                <p className="text-xs text-destructive mt-1">
                  {form.formState.errors.title.message}
                </p>
              )}
            </div>

            {/* Description */}
            <div>
              <label htmlFor="task-description" className="text-sm font-medium mb-2 block">Omschrijving</label>
              <Controller
                control={form.control}
                name="description"
                render={({ field }) => (
                  <>
                    <TextareaAutosize
                      id="task-description"
                      {...field}
                      value={field.value ?? ''}
                      aria-invalid={!!form.formState.errors.description}
                      minRows={3}
                      maxRows={6}
                      placeholder="Optionele omschrijving..."
                      className={cn(
                        textareaClass,
                        form.formState.errors.description &&
                          'border-destructive ring-3 ring-destructive/20',
                      )}
                    />
                    <CharCount value={field.value ?? ''} max={2000} />
                    <p className="text-xs text-muted-foreground mt-1">
                      Markdown ondersteund (lijstjes, **vet**, `code`)
                    </p>
                  </>
                )}
              />
              {form.formState.errors.description && (
                <p className="text-xs text-destructive mt-1">
                  {form.formState.errors.description.message}
                </p>
              )}
            </div>

            {/* Implementation plan */}
            <div>
              <label htmlFor="task-implementation-plan" className="text-sm font-medium mb-2 block">Implementatieplan</label>
              <Controller
                control={form.control}
                name="implementation_plan"
                render={({ field }) => (
                  <>
                    <TextareaAutosize
                      id="task-implementation-plan"
                      {...field}
                      value={field.value ?? ''}
                      aria-invalid={!!form.formState.errors.implementation_plan}
                      minRows={5}
                      maxRows={12}
                      placeholder="Optioneel implementatieplan..."
                      className={cn(
                        textareaClass,
                        form.formState.errors.implementation_plan &&
                          'border-destructive ring-3 ring-destructive/20',
                      )}
                    />
                    <CharCount value={field.value ?? ''} max={10000} />
                    <p className="text-xs text-muted-foreground mt-1">
                      Markdown ondersteund (lijstjes, **vet**, `code`)
                    </p>
                  </>
                )}
              />
              {form.formState.errors.implementation_plan && (
                <p className="text-xs text-destructive mt-1">
                  {form.formState.errors.implementation_plan.message}
                </p>
              )}
            </div>

            {/* Priority */}
            <div>
              <label className="text-sm font-medium mb-2 block">Prioriteit</label>
              <Controller
                control={form.control}
                name="priority"
                render={({ field }) => (
                  <PrioritySegmented
                    value={field.value}
                    onChange={field.onChange}
                    disabled={isPending}
                  />
                )}
              />
            </div>

            {/* Status — edit only */}
            {isEdit && (
              <div>
                <label className="text-sm font-medium mb-2 block">Status</label>
                <Controller
                  control={form.control}
                  name="status"
                  render={({ field }) => (
                    <StatusSelect
                      value={field.value}
                      onChange={field.onChange}
                      disabled={isPending}
                    />
                  )}
                />
              </div>
            )}
          </div>

          {/* Sticky footer */}
          <div className={entityDialogFooterClasses}>
            <div className="flex items-center justify-between gap-2">
              {isEdit ? (
                <DemoTooltip show={isDemo}>
                  <Button
                    type="button"
                    variant="destructive"
                    disabled={isPending || isDemo}
                    onClick={() => setConfirmDelete(true)}
                  >
                    Verwijderen
                  </Button>
                </DemoTooltip>
              ) : (
                <div />
              )}

              <div className="flex gap-2">
                <Button
                  type="button"
                  variant="ghost"
                  onClick={closeGuard.attemptClose}
                  disabled={isPending}
                >
                  Annuleren
                </Button>
                <DemoTooltip show={isDemo}>
                  <Button
                    type="button"
                    disabled={isPending || isDemo}
                    onClick={form.handleSubmit(onSubmit)}
                  >
                    {isPending ? (
                      <>
                        <Loader2 className="size-4 animate-spin" />
                        {isEdit ? 'Opslaan...' : 'Aanmaken...'}
                      </>
                    ) : isEdit ? (
                      'Opslaan'
                    ) : (
                      'Aanmaken'
                    )}
                  </Button>
                </DemoTooltip>
              </div>
            </div>
          </div>
        </DialogContent>
      </Dialog>

      {/* Dirty-check confirm */}
      <DirtyCloseGuardDialog guard={closeGuard} />

      {/* Delete confirm */}
      <AlertDialog open={confirmDelete} onOpenChange={setConfirmDelete}>
        <AlertDialogContent size="sm">
          <AlertDialogHeader>
            <AlertDialogTitle>Taak verwijderen</AlertDialogTitle>
            <AlertDialogDescription>
              Weet je zeker dat je deze taak wilt verwijderen? Dit kan niet ongedaan worden gemaakt.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel onClick={() => setConfirmDelete(false)}>
              Annuleren
            </AlertDialogCancel>
            <AlertDialogAction
              variant="destructive"
              disabled={isPending}
              onClick={handleDelete}
            >
              {isPending ? <Loader2 className="size-4 animate-spin" /> : 'Verwijderen'}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </>
  )
}
