'use client'

import { useState, useTransition, useMemo, useEffect, useRef, useCallback } from 'react'
import { useActionState } from 'react'
import { useFormStatus } from 'react-dom'
import {
  useReactTable,
  getCoreRowModel,
  getPaginationRowModel,
  flexRender,
  type ColumnDef,
  type RowSelectionState,
  type PaginationState,
} from '@tanstack/react-table'
import { toast } from 'sonner'
import { cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
import { DemoTooltip } from '@/components/shared/demo-tooltip'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
import {
  createTodoAction,
  updateTodoAction,
  archiveSelectedTodosAction,
  promoteTodoToPbiAction,
  promoteTodoToStoryAction,
} from '@/actions/todos'

interface Todo {
  id: string
  title: string
  description: string | null
  done: boolean
  created_at: string
  product_id: string | null
  product_name: string | null
}

interface Pbi {
  id: string
  title: string
}

interface Product {
  id: string
  name: string
  pbis: Pbi[]
}

interface TodoListProps {
  todos: Todo[]
  products: Product[]
  isDemo: boolean
}

// Checkbox with indeterminate support for TanStack row selection
function IndeterminateCheckbox({
  indeterminate,
  className,
  ...props
}: React.InputHTMLAttributes<HTMLInputElement> & { indeterminate?: boolean }) {
  const ref = useRef<HTMLInputElement>(null)
  useEffect(() => {
    if (ref.current) ref.current.indeterminate = indeterminate ?? false
  }, [indeterminate])
  return (
    <input
      ref={ref}
      type="checkbox"
      className={cn('size-4 cursor-pointer accent-primary', className)}
      {...props}
    />
  )
}

function SaveButton() {
  const { pending } = useFormStatus()
  return (
    <Button type="submit" size="sm" disabled={pending}>
      {pending ? '…' : 'Opslaan'}
    </Button>
  )
}

// --- Promote to PBI dialog ---
function PromotePbiDialog({
  todo,
  products,
  onClose,
}: { todo: Todo; products: Product[]; onClose: () => void }) {
  const handleKey = useCallback((e: KeyboardEvent) => { if (e.key === 'Escape') onClose() }, [onClose])
  useEffect(() => {
    document.addEventListener('keydown', handleKey)
    return () => document.removeEventListener('keydown', handleKey)
  }, [handleKey])

  const [state, formAction] = useActionState(
    async (_prev: unknown, fd: FormData) => {
      const result = await promoteTodoToPbiAction(_prev, fd)
      if (result?.success) { toast.success('Todo gepromoveerd naar PBI'); onClose() }
      return result
    },
    undefined
  )

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40">
      <div className="bg-popover border border-border rounded-xl p-6 w-full max-w-md shadow-xl space-y-4">
        <h2 className="font-medium text-foreground">Promoveer naar PBI</h2>
        <p className="text-xs text-warning">Let op: dit kan niet ongedaan worden gemaakt.</p>
        <form action={formAction} className="space-y-3">
          <input type="hidden" name="todoId" value={todo.id} />
          <div className="space-y-1.5">
            <label className="text-sm font-medium">Titel</label>
            <Input name="title" defaultValue={todo.title} required />
          </div>
          <div className="space-y-1.5">
            <label className="text-sm font-medium">Product</label>
            {products.length === 0 ? (
              <p className="text-sm text-muted-foreground">Maak eerst een product aan.</p>
            ) : (
              <select
                name="productId"
                required
                defaultValue={todo.product_id ?? products[0]?.id}
                className="w-full border border-border rounded-lg px-3 py-1.5 text-sm bg-input-background"
              >
                {products.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
              </select>
            )}
          </div>
          <div className="space-y-1.5">
            <label className="text-sm font-medium">Prioriteit</label>
            <select name="priority" required className="w-full border border-border rounded-lg px-3 py-1.5 text-sm bg-input-background">
              <option value="1">Kritiek</option>
              <option value="2">Hoog</option>
              <option value="3">Gemiddeld</option>
              <option value="4">Laag</option>
            </select>
          </div>
          {typeof state?.error === 'string' && <p className="text-xs text-error">{state.error}</p>}
          <div className="flex gap-2 justify-end">
            <Button type="button" variant="ghost" onClick={onClose}>Annuleren</Button>
            <Button type="submit" disabled={products.length === 0}>Promoveren</Button>
          </div>
        </form>
      </div>
    </div>
  )
}

// --- Promote to Story dialog ---
function PromoteStoryDialog({
  todo,
  products,
  onClose,
}: { todo: Todo; products: Product[]; onClose: () => void }) {
  const handleKey = useCallback((e: KeyboardEvent) => { if (e.key === 'Escape') onClose() }, [onClose])
  useEffect(() => {
    document.addEventListener('keydown', handleKey)
    return () => document.removeEventListener('keydown', handleKey)
  }, [handleKey])

  const [selectedProductId, setSelectedProductId] = useState(todo.product_id ?? products[0]?.id ?? '')
  const selectedProduct = products.find(p => p.id === selectedProductId)

  const [state, formAction] = useActionState(
    async (_prev: unknown, fd: FormData) => {
      const result = await promoteTodoToStoryAction(_prev, fd)
      if (result?.success) { toast.success('Todo gepromoveerd naar Story'); onClose() }
      return result
    },
    undefined
  )

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40">
      <div className="bg-popover border border-border rounded-xl p-6 w-full max-w-md shadow-xl space-y-4">
        <h2 className="font-medium text-foreground">Promoveer naar Story</h2>
        <p className="text-xs text-warning">Let op: dit kan niet ongedaan worden gemaakt.</p>
        <form action={formAction} className="space-y-3">
          <input type="hidden" name="todoId" value={todo.id} />
          <input type="hidden" name="productId" value={selectedProductId} />
          <div className="space-y-1.5">
            <label className="text-sm font-medium">Titel</label>
            <Input name="title" defaultValue={todo.title} required />
          </div>
          <div className="space-y-1.5">
            <label className="text-sm font-medium">Product</label>
            {products.length === 0 ? (
              <p className="text-sm text-muted-foreground">Maak eerst een product aan.</p>
            ) : (
              <select
                value={selectedProductId}
                onChange={e => setSelectedProductId(e.target.value)}
                className="w-full border border-border rounded-lg px-3 py-1.5 text-sm bg-input-background"
              >
                {products.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
              </select>
            )}
          </div>
          <div className="space-y-1.5">
            <label className="text-sm font-medium">PBI</label>
            {!selectedProduct?.pbis.length ? (
              <p className="text-sm text-muted-foreground">Maak eerst een PBI aan in dit product.</p>
            ) : (
              <select name="pbiId" required className="w-full border border-border rounded-lg px-3 py-1.5 text-sm bg-input-background">
                {selectedProduct.pbis.map(p => <option key={p.id} value={p.id}>{p.title}</option>)}
              </select>
            )}
          </div>
          <div className="space-y-1.5">
            <label className="text-sm font-medium">Prioriteit</label>
            <select name="priority" required className="w-full border border-border rounded-lg px-3 py-1.5 text-sm bg-input-background">
              <option value="1">Kritiek</option>
              <option value="2">Hoog</option>
              <option value="3">Gemiddeld</option>
              <option value="4">Laag</option>
            </select>
          </div>
          {typeof state?.error === 'string' && <p className="text-xs text-error">{state.error}</p>}
          <div className="flex gap-2 justify-end">
            <Button type="button" variant="ghost" onClick={onClose}>Annuleren</Button>
            <Button type="submit" disabled={!selectedProduct?.pbis.length}>Promoveren</Button>
          </div>
        </form>
      </div>
    </div>
  )
}

// --- Detail card ---
function TodoCard({
  mode,
  activeTodo,
  products,
  isDemo,
  defaultProductId,
  onSuccess,
  onPromotePbi,
  onPromoteStory,
}: {
  mode: 'idle' | 'create' | 'edit'
  activeTodo: Todo | null
  products: Product[]
  isDemo: boolean
  defaultProductId: string
  onSuccess: () => void
  onPromotePbi: (todo: Todo) => void
  onPromoteStory: (todo: Todo) => void
}) {
  const [createState, createFormAction] = useActionState(createTodoAction, undefined)
  const [editState, editFormAction] = useActionState(updateTodoAction, undefined)

  useEffect(() => {
    if (createState?.success) onSuccess()
  }, [createState, onSuccess])

  useEffect(() => {
    if (editState?.success) onSuccess()
  }, [editState, onSuccess])

  if (mode === 'idle') {
    return (
      <div className="rounded-xl border border-border bg-surface-container-low p-5 min-h-[88px] flex items-center justify-center">
        <p className="text-sm text-muted-foreground">Selecteer een rij of klik op + om te beginnen.</p>
      </div>
    )
  }

  if (mode === 'create') {
    return (
      <div className="rounded-xl border border-border bg-surface-container-low p-5">
        <p className="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-3">Nieuwe todo</p>
        <form action={createFormAction} className="space-y-3">
          <div className="flex gap-3">
            <select
              name="productId"
              defaultValue={defaultProductId}
              disabled={isDemo}
              className="border border-border rounded-lg px-3 py-1.5 text-sm bg-input-background shrink-0"
            >
              <option value="">Geen product</option>
              {products.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
            </select>
            <Input
              name="title"
              placeholder="Titel…"
              disabled={isDemo}
              autoFocus
              className="flex-1"
              autoComplete="off"
            />
          </div>
          <Textarea
            name="description"
            placeholder="Beschrijving (optioneel, max 2000 tekens)…"
            disabled={isDemo}
            maxLength={2000}
            rows={4}
          />
          {typeof createState?.error === 'string' && (
            <p className="text-xs text-error">{createState.error}</p>
          )}
          <div className="flex gap-2 justify-end">
            <Button type="button" variant="ghost" size="sm" onClick={onSuccess}>Annuleren</Button>
            <SaveButton />
          </div>
        </form>
      </div>
    )
  }

  // Edit mode
  if (!activeTodo) return null

  return (
    <div className="rounded-xl border border-border bg-surface-container-low p-5">
      <p className="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-3">Todo bewerken</p>
      <form action={editFormAction} className="space-y-3">
        <input type="hidden" name="id" value={activeTodo.id} />
        <div className="flex gap-3">
          <select
            name="productId"
            defaultValue={activeTodo.product_id ?? ''}
            disabled={isDemo}
            className="border border-border rounded-lg px-3 py-1.5 text-sm bg-input-background shrink-0"
          >
            <option value="">Geen product</option>
            {products.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
          </select>
          <Input
            name="title"
            defaultValue={activeTodo.title}
            disabled={isDemo}
            autoFocus
            className="flex-1"
            autoComplete="off"
          />
        </div>
        <Textarea
          name="description"
          defaultValue={activeTodo.description ?? ''}
          placeholder="Beschrijving (optioneel, max 2000 tekens)…"
          disabled={isDemo}
          maxLength={2000}
          rows={4}
        />
        <label className="flex items-center gap-2 text-sm cursor-pointer w-fit select-none">
          <input
            type="checkbox"
            name="done"
            defaultChecked={activeTodo.done}
            disabled={isDemo}
            className="size-4 accent-primary cursor-pointer"
          />
          Afgerond
        </label>
        {typeof editState?.error === 'string' && (
          <p className="text-xs text-error">{editState.error}</p>
        )}
        <div className="flex items-center gap-2">
          {!isDemo && (
            <>
              <Button type="button" variant="outline" size="sm" onClick={() => onPromotePbi(activeTodo)}>
                → PBI
              </Button>
              <Button type="button" variant="outline" size="sm" onClick={() => onPromoteStory(activeTodo)}>
                → Story
              </Button>
            </>
          )}
          <div className="flex-1" />
          <Button type="button" variant="ghost" size="sm" onClick={onSuccess}>Annuleren</Button>
          <SaveButton />
        </div>
      </form>
    </div>
  )
}

// --- Main component ---
export function TodoList({ todos, products, isDemo }: TodoListProps) {
  const [isPending, startTransition] = useTransition()
  const [selectedProductId, setSelectedProductId] = useState('all')
  const [rowSelection, setRowSelection] = useState<RowSelectionState>({})
  const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, pageSize: 10 })
  const [activeRowId, setActiveRowId] = useState<string | null>(null)
  const [mode, setMode] = useState<'idle' | 'create'>('idle')
  const [promotePbi, setPromotePbi] = useState<Todo | null>(null)
  const [promoteStory, setPromoteStory] = useState<Todo | null>(null)

  const filtered = useMemo(() => {
    if (selectedProductId === 'all') return todos
    if (selectedProductId === '') return todos.filter(t => t.product_id === null)
    return todos.filter(t => t.product_id === selectedProductId)
  }, [todos, selectedProductId])

  useEffect(() => {
    setPagination(p => ({ ...p, pageIndex: 0 }))
    setRowSelection({})
  }, [selectedProductId])

  const columns = useMemo<ColumnDef<Todo>[]>(() => [
    {
      id: 'select',
      header: ({ table }) => (
        <IndeterminateCheckbox
          checked={table.getIsAllPageRowsSelected()}
          indeterminate={table.getIsSomePageRowsSelected() && !table.getIsAllPageRowsSelected()}
          onChange={e => table.toggleAllPageRowsSelected(e.target.checked)}
        />
      ),
      cell: ({ row }) => (
        <IndeterminateCheckbox
          checked={row.getIsSelected()}
          disabled={!row.getCanSelect()}
          onChange={e => row.toggleSelected(e.target.checked)}
          onClick={e => e.stopPropagation()}
        />
      ),
    },
    {
      accessorKey: 'title',
      header: 'Titel',
      cell: ({ row }) => (
        <p className={cn(
          'line-clamp-2 text-sm leading-snug',
          row.original.done && 'line-through text-muted-foreground'
        )}>
          {row.original.title}
        </p>
      ),
    },
    {
      accessorKey: 'product_name',
      header: 'Product',
      cell: ({ row }) => row.original.product_name ? (
        <Badge variant="outline" className="text-xs font-normal">{row.original.product_name}</Badge>
      ) : (
        <span className="text-xs text-muted-foreground">—</span>
      ),
    },
    {
      accessorKey: 'created_at',
      header: 'Datum',
      cell: ({ row }) => (
        <span className="text-xs text-muted-foreground whitespace-nowrap">
          {new Date(row.original.created_at).toLocaleDateString('nl-NL')}
        </span>
      ),
    },
  ], [])

  const table = useReactTable({
    data: filtered,
    columns,
    state: { rowSelection, pagination },
    enableRowSelection: true,
    onRowSelectionChange: setRowSelection,
    onPaginationChange: setPagination,
    getCoreRowModel: getCoreRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
  })

  const selectedRows = table.getSelectedRowModel().rows
  const selectedCount = selectedRows.length
  const { pageIndex, pageSize } = table.getState().pagination
  const totalRows = filtered.length
  const start = totalRows === 0 ? 0 : pageIndex * pageSize + 1
  const end = Math.min((pageIndex + 1) * pageSize, totalRows)

  const activeTodo = todos.find(t => t.id === activeRowId) ?? null
  const cardMode = mode === 'create' ? 'create' : activeTodo ? 'edit' : 'idle'
  const defaultProductId = selectedProductId !== 'all' ? selectedProductId : ''

  const handleCancel = useCallback(() => {
    setActiveRowId(null)
    setMode('idle')
  }, [])

  function handleRowClick(todo: Todo) {
    setActiveRowId(prev => prev === todo.id ? null : todo.id)
    setMode('idle')
  }

  function handleNew() {
    setActiveRowId(null)
    setRowSelection({})
    setMode('create')
  }

  function handleBulkArchive() {
    const ids = selectedRows.map(r => r.original.id)
    startTransition(async () => {
      const result = await archiveSelectedTodosAction(ids)
      if (result?.error) {
        toast.error(typeof result.error === 'string' ? result.error : 'Archiveren mislukt')
      } else {
        const n = ids.length
        toast.success(`${n} todo${n === 1 ? '' : "'s"} gearchiveerd`)
        setRowSelection({})
        setActiveRowId(null)
        setMode('idle')
      }
    })
  }

  return (
    <div className="space-y-4">
      {/* Toolbar */}
      <div className="flex items-center gap-3 flex-wrap">
        <select
          value={selectedProductId}
          onChange={e => setSelectedProductId(e.target.value)}
          className="border border-border rounded-lg px-3 py-1.5 text-sm bg-input-background"
        >
          <option value="all">Alles</option>
          <option value="">Geen product</option>
          {products.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
        </select>

        <div className="flex-1" />

        {selectedCount > 0 && !isDemo && (
          <Button variant="outline" size="sm" onClick={handleBulkArchive} disabled={isPending}>
            Archiveer geselecteerde ({selectedCount})
          </Button>
        )}

        <DemoTooltip show={isDemo}>
          <Button size="sm" onClick={handleNew} disabled={isDemo}>+</Button>
        </DemoTooltip>
      </div>

      {/* Table */}
      <div className="rounded-xl border border-border overflow-hidden">
        <Table>
          <TableHeader>
            {table.getHeaderGroups().map(hg => (
              <TableRow key={hg.id} className="hover:bg-transparent">
                {hg.headers.map(header => (
                  <TableHead key={header.id}>
                    {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
                  </TableHead>
                ))}
              </TableRow>
            ))}
          </TableHeader>
          <TableBody>
            {table.getRowModel().rows.length > 0 ? (
              table.getRowModel().rows.map(row => (
                <TableRow
                  key={row.id}
                  className={cn(
                    'cursor-pointer hover:bg-surface-container-low',
                    activeRowId === row.original.id
                      ? 'bg-primary/5'
                      : row.getIsSelected()
                      ? 'bg-primary/10'
                      : ''
                  )}
                  onClick={() => handleRowClick(row.original)}
                >
                  {row.getVisibleCells().map(cell => (
                    <TableCell key={cell.id}>
                      {flexRender(cell.column.columnDef.cell, cell.getContext())}
                    </TableCell>
                  ))}
                </TableRow>
              ))
            ) : (
              <TableRow>
                <TableCell colSpan={4} className="h-32 text-center text-sm text-muted-foreground">
                  {todos.length === 0
                    ? "Nog geen todo's. Gebruik + om er een aan te maken."
                    : "Geen todo's voor deze selectie."}
                </TableCell>
              </TableRow>
            )}
          </TableBody>
        </Table>
      </div>

      {/* Pagination */}
      {totalRows > pageSize && (
        <div className="flex items-center justify-between">
          <span className="text-xs text-muted-foreground">{start}–{end} van {totalRows}</span>
          <div className="flex gap-1">
            <Button variant="outline" size="sm" onClick={() => table.previousPage()} disabled={!table.getCanPreviousPage()}>‹</Button>
            <Button variant="outline" size="sm" onClick={() => table.nextPage()} disabled={!table.getCanNextPage()}>›</Button>
          </div>
        </div>
      )}

      {/* Detail card */}
      <TodoCard
        key={activeRowId ?? (mode === 'create' ? 'create' : 'idle')}
        mode={cardMode}
        activeTodo={activeTodo}
        products={products}
        isDemo={isDemo}
        defaultProductId={defaultProductId}
        onSuccess={handleCancel}
        onPromotePbi={setPromotePbi}
        onPromoteStory={setPromoteStory}
      />

      {promotePbi && (
        <PromotePbiDialog todo={promotePbi} products={products} onClose={() => setPromotePbi(null)} />
      )}
      {promoteStory && (
        <PromoteStoryDialog todo={promoteStory} products={products} onClose={() => setPromoteStory(null)} />
      )}
    </div>
  )
}
