'use client'

import { useState } from 'react'
import Link from 'next/link'
import { usePathname, useSearchParams, useRouter } from 'next/navigation'
import {
  Table, TableBody, TableCell, TableHead, TableHeader, TableRow,
} from '@/components/ui/table'
import { Pencil, ChevronLeft, ChevronRight, Trash2, Tag, StickyNote, X, ArrowLeftRight } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog'
import { Textarea } from '@/components/ui/textarea'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { formatCents } from '@/lib/utils/currency'
import { EditTransactionDialog } from './EditTransactionDialog'
import { cn } from '@/lib/utils'

export type TransactionRow = {
  id: string
  date: string
  description: string
  amountCents: number
  type: string
  category: string | null
  notes: string | null
  accountId: string
  budgetId: string | null
  account: { name: string; type: string }
  budget: { id: string; name: string; color: string | null } | null
}

type BudgetOption = { id: string; name: string; color: string | null }

interface Props {
  transactions: TransactionRow[]
  total: number
  page: number
  limit: number
  showAccount?: boolean
  budgets: BudgetOption[]
}

export function TransactionTable({
  transactions,
  total,
  page,
  limit,
  showAccount = true,
  budgets,
}: Props) {
  const pathname = usePathname()
  const searchParams = useSearchParams()
  const router = useRouter()
  const [editing, setEditing] = useState<TransactionRow | null>(null)
  const [selected, setSelected] = useState<Set<string>>(new Set())
  const [bulkDialog, setBulkDialog] = useState<'delete' | 'budget' | 'notes' | 'transfer' | null>(null)
  const [budgetTarget, setBudgetTarget] = useState<string>('__none__')
  const [notesValue, setNotesValue] = useState('')
  const [working, setWorking] = useState(false)
  const totalPages = Math.ceil(total / limit)

  const allIds = transactions.map((t) => t.id)
  const allSelected = allIds.length > 0 && allIds.every((id) => selected.has(id))
  const someSelected = selected.size > 0

  function toggleAll() {
    if (allSelected) {
      setSelected((prev) => {
        const next = new Set(prev)
        allIds.forEach((id) => next.delete(id))
        return next
      })
    } else {
      setSelected((prev) => new Set([...prev, ...allIds]))
    }
  }

  function toggleOne(id: string) {
    setSelected((prev) => {
      const next = new Set(prev)
      if (next.has(id)) next.delete(id)
      else next.add(id)
      return next
    })
  }

  function clearSelection() {
    setSelected(new Set())
  }

  function pageHref(p: number) {
    const params = new URLSearchParams(searchParams.toString())
    params.set('page', String(p))
    return `${pathname}?${params.toString()}`
  }

  async function bulkPost(body: object) {
    setWorking(true)
    const res = await fetch('/api/transactions/bulk', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body),
    })
    setWorking(false)
    if (res.ok) {
      clearSelection()
      setBulkDialog(null)
      router.refresh()
    }
  }

  async function handleDelete() {
    await bulkPost({ action: 'delete', ids: [...selected] })
  }

  async function handleAssignBudget() {
    await bulkPost({
      action: 'assignBudget',
      ids: [...selected],
      budgetId: budgetTarget === '__none__' ? null : budgetTarget,
    })
  }

  async function handleAddNotes() {
    await bulkPost({ action: 'addNotes', ids: [...selected], notes: notesValue })
  }

  async function handleMarkTransfer() {
    await bulkPost({ action: 'markTransfer', ids: [...selected] })
  }

  if (transactions.length === 0 && !someSelected) {
    return (
      <div className="rounded-lg border border-dashed p-12 text-center text-muted-foreground">
        No transactions found.
      </div>
    )
  }

  const colSpan = showAccount ? 8 : 7

  return (
    <>
      {/* Bulk action bar */}
      {someSelected && (
        <div className="flex items-center gap-3 rounded-md border bg-muted/50 px-4 py-2 mb-2">
          <span className="text-sm font-medium">{selected.size} selected</span>
          <div className="flex items-center gap-2 ml-auto">
            <Button
              size="sm"
              variant="outline"
              onClick={() => { setNotesValue(''); setBulkDialog('notes') }}
            >
              <StickyNote className="h-3.5 w-3.5 mr-1.5" />Notes
            </Button>
            <Button
              size="sm"
              variant="outline"
              onClick={() => { setBudgetTarget('__none__'); setBulkDialog('budget') }}
            >
              <Tag className="h-3.5 w-3.5 mr-1.5" />Budget
            </Button>
            <Button
              size="sm"
              variant="outline"
              onClick={() => setBulkDialog('transfer')}
            >
              <ArrowLeftRight className="h-3.5 w-3.5 mr-1.5" />Transfer
            </Button>
            <Button
              size="sm"
              variant="destructive"
              onClick={() => setBulkDialog('delete')}
            >
              <Trash2 className="h-3.5 w-3.5 mr-1.5" />Delete
            </Button>
            <Button size="sm" variant="ghost" onClick={clearSelection}>
              <X className="h-3.5 w-3.5" />
            </Button>
          </div>
        </div>
      )}

      <div className="rounded-md border overflow-hidden">
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead className="w-8 px-3">
                <input
                  type="checkbox"
                  className="h-4 w-4 rounded border"
                  checked={allSelected}
                  onChange={toggleAll}
                  aria-label="Select all"
                />
              </TableHead>
              <TableHead className="w-28">Date</TableHead>
              <TableHead>Description</TableHead>
              {showAccount && <TableHead className="w-36">Account</TableHead>}
              <TableHead className="w-32 text-right">Amount</TableHead>
              <TableHead className="w-32">Category</TableHead>
              <TableHead className="w-32">Budget</TableHead>
              <TableHead className="w-10" />
            </TableRow>
          </TableHeader>
          <TableBody>
            {transactions.map((tx) => {
              const isCredit = tx.type === 'CREDIT'
              const isTransfer = tx.type === 'TRANSFER'
              const isSelected = selected.has(tx.id)
              const dateStr = new Date(tx.date).toLocaleDateString('en-US', {
                month: 'short', day: 'numeric', year: 'numeric',
              })
              return (
                <TableRow key={tx.id} className={isSelected ? 'bg-muted/40' : undefined}>
                  <TableCell className="px-3">
                    <input
                      type="checkbox"
                      className="h-4 w-4 rounded border"
                      checked={isSelected}
                      onChange={() => toggleOne(tx.id)}
                      aria-label="Select transaction"
                    />
                  </TableCell>
                  <TableCell className="text-sm text-muted-foreground whitespace-nowrap">
                    {dateStr}
                  </TableCell>
                  <TableCell className="max-w-xs">
                    <div className="truncate text-sm">{tx.description}</div>
                    {tx.notes && (
                      <div className="truncate text-xs text-muted-foreground">{tx.notes}</div>
                    )}
                  </TableCell>
                  {showAccount && (
                    <TableCell className="text-sm text-muted-foreground">
                      {tx.account.name}
                    </TableCell>
                  )}
                  <TableCell className="text-right tabular-nums font-medium">
                    <span className={cn('text-sm', isTransfer ? 'text-muted-foreground' : isCredit ? 'text-green-600' : '')}>
                      {isTransfer ? '⇄ ' : isCredit ? '+' : '-'}{formatCents(tx.amountCents)}
                    </span>
                  </TableCell>
                  <TableCell className="text-sm text-muted-foreground">
                    {tx.category ?? '—'}
                  </TableCell>
                  <TableCell>
                    {tx.budget ? (
                      <span className="flex items-center gap-1.5 text-sm">
                        {tx.budget.color && (
                          <span
                            className="inline-block h-2 w-2 rounded-full shrink-0"
                            style={{ backgroundColor: tx.budget.color }}
                          />
                        )}
                        {tx.budget.name}
                      </span>
                    ) : (
                      <span className="text-sm text-muted-foreground">—</span>
                    )}
                  </TableCell>
                  <TableCell>
                    <button
                      onClick={() => setEditing(tx)}
                      className="inline-flex h-7 w-7 items-center justify-center rounded-md hover:bg-accent transition-colors"
                    >
                      <Pencil className="h-3.5 w-3.5 text-muted-foreground" />
                      <span className="sr-only">Edit</span>
                    </button>
                  </TableCell>
                </TableRow>
              )
            })}
          </TableBody>
        </Table>
      </div>

      {/* Pagination */}
      <div className="flex items-center justify-between py-3">
        <p className="text-sm text-muted-foreground">
          {total.toLocaleString()} transaction{total !== 1 ? 's' : ''}
          {totalPages > 1 && ` · page ${page} of ${totalPages}`}
        </p>
        {totalPages > 1 && (
          <div className="flex items-center gap-1">
            {page > 1 ? (
              <Link
                href={pageHref(page - 1)}
                className="inline-flex items-center gap-1 rounded-md border px-3 py-1.5 text-sm font-medium hover:bg-accent transition-colors"
              >
                <ChevronLeft className="h-4 w-4" />Prev
              </Link>
            ) : (
              <span className="inline-flex items-center gap-1 rounded-md border px-3 py-1.5 text-sm font-medium opacity-50 cursor-not-allowed">
                <ChevronLeft className="h-4 w-4" />Prev
              </span>
            )}
            {page < totalPages ? (
              <Link
                href={pageHref(page + 1)}
                className="inline-flex items-center gap-1 rounded-md border px-3 py-1.5 text-sm font-medium hover:bg-accent transition-colors"
              >
                Next<ChevronRight className="h-4 w-4" />
              </Link>
            ) : (
              <span className="inline-flex items-center gap-1 rounded-md border px-3 py-1.5 text-sm font-medium opacity-50 cursor-not-allowed">
                Next<ChevronRight className="h-4 w-4" />
              </span>
            )}
          </div>
        )}
      </div>

      <EditTransactionDialog
        transaction={editing}
        onOpenChange={(open) => { if (!open) setEditing(null) }}
        budgets={budgets}
      />

      {/* Delete confirm dialog */}
      <Dialog open={bulkDialog === 'delete'} onOpenChange={(o) => { if (!o) setBulkDialog(null) }}>
        <DialogContent className="max-w-sm">
          <DialogHeader>
            <DialogTitle>Delete {selected.size} transaction{selected.size !== 1 ? 's' : ''}?</DialogTitle>
          </DialogHeader>
          <p className="text-sm text-muted-foreground">This cannot be undone.</p>
          <DialogFooter>
            <Button variant="outline" onClick={() => setBulkDialog(null)}>Cancel</Button>
            <Button variant="destructive" onClick={handleDelete} disabled={working}>
              {working ? 'Deleting…' : 'Delete'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Assign budget dialog */}
      <Dialog open={bulkDialog === 'budget'} onOpenChange={(o) => { if (!o) setBulkDialog(null) }}>
        <DialogContent className="max-w-sm">
          <DialogHeader>
            <DialogTitle>Assign budget</DialogTitle>
          </DialogHeader>
          <p className="text-sm text-muted-foreground">
            Apply to {selected.size} selected transaction{selected.size !== 1 ? 's' : ''}.
          </p>
          <Select value={budgetTarget} onValueChange={(v) => setBudgetTarget(v ?? '__none__')}>
            <SelectTrigger>
              <SelectValue>
                {budgetTarget === '__none__'
                  ? 'No budget'
                  : (budgets.find((b) => b.id === budgetTarget)?.name ?? 'No budget')}
              </SelectValue>
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="__none__">No budget</SelectItem>
              {budgets.map((b) => (
                <SelectItem key={b.id} value={b.id}>
                  {b.name}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <DialogFooter>
            <Button variant="outline" onClick={() => setBulkDialog(null)}>Cancel</Button>
            <Button onClick={handleAssignBudget} disabled={working}>
              {working ? 'Saving…' : 'Apply'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Mark as transfer dialog */}
      <Dialog open={bulkDialog === 'transfer'} onOpenChange={(o) => { if (!o) setBulkDialog(null) }}>
        <DialogContent className="max-w-sm">
          <DialogHeader>
            <DialogTitle>Mark as transfer?</DialogTitle>
          </DialogHeader>
          <p className="text-sm text-muted-foreground">
            {selected.size} transaction{selected.size !== 1 ? 's' : ''} will be marked as transfers
            and excluded from cash flow calculations.
          </p>
          <DialogFooter>
            <Button variant="outline" onClick={() => setBulkDialog(null)}>Cancel</Button>
            <Button onClick={handleMarkTransfer} disabled={working}>
              {working ? 'Saving…' : 'Mark as transfer'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Add notes dialog */}
      <Dialog open={bulkDialog === 'notes'} onOpenChange={(o) => { if (!o) setBulkDialog(null) }}>
        <DialogContent className="max-w-sm">
          <DialogHeader>
            <DialogTitle>Set notes</DialogTitle>
          </DialogHeader>
          <p className="text-sm text-muted-foreground">
            Apply to {selected.size} selected transaction{selected.size !== 1 ? 's' : ''}. Leave blank to clear.
          </p>
          <Textarea
            placeholder="Add a note…"
            value={notesValue}
            onChange={(e) => setNotesValue(e.target.value)}
            maxLength={500}
            rows={3}
          />
          <DialogFooter>
            <Button variant="outline" onClick={() => setBulkDialog(null)}>Cancel</Button>
            <Button onClick={handleAddNotes} disabled={working}>
              {working ? 'Saving…' : 'Apply'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  )
}
