import { useState, useMemo } from 'react'
import {
  type ColumnDef,
  flexRender,
  getCoreRowModel,
  getSortedRowModel,
  getFilteredRowModel,
  useReactTable,
  type SortingState,
} from '@tanstack/react-table'
import { 
  Copy, 
  Shield, 
  Pencil, 
  Trash2, 
  Search, 
  ArrowUpDown,
  ArrowUp,
  ArrowDown,
  MoreHorizontal,
  Globe
} from 'lucide-react'
import { toast } from 'sonner'
import type { VaultEntry } from '@/services/api'
import { PasswordCell } from './password-cell'
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table'
import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'

interface EntriesTableProps {
  entries: VaultEntry[]
  isOwner?: boolean
  onEdit: (entry: VaultEntry) => void
  onDelete: (entry: VaultEntry) => void
  onGrant: (entry: VaultEntry) => void
}

function ActionMenu({ 
  entry, 
  onEdit, 
  onDelete, 
  onGrant 
}: { 
  entry: VaultEntry; 
  onEdit: (e: VaultEntry) => void; 
  onDelete: (e: VaultEntry) => void; 
  onGrant: (e: VaultEntry) => void; 
}) {
  const [open, setOpen] = useState(false)

  return (
    <div className='relative flex justify-end'>
      <Button 
        variant="ghost" 
        size="icon" 
        onClick={(e) => { e.stopPropagation(); setOpen(!open) }}
        className='h-8 w-8'
      >
        <MoreHorizontal className='h-4 w-4' />
      </Button>
      
      {open && (
        <>
          <div className='fixed inset-0 z-10' onClick={(e) => { e.stopPropagation(); setOpen(false) }} />
          <div className='absolute right-0 top-9 z-20 w-40 rounded-lg border bg-popover shadow-lg py-1.5 overflow-hidden animate-in fade-in zoom-in-95 duration-100'>
            <button 
              onClick={(e) => { e.stopPropagation(); setOpen(false); onGrant(entry) }} 
              className='w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-muted text-left transition-colors'
            >
              <Shield className='h-4 w-4 text-muted-foreground' /> 
              <span>Manage</span>
            </button>
            <button 
              onClick={(e) => { e.stopPropagation(); setOpen(false); onEdit(entry) }} 
              className='w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-muted text-left transition-colors'
            >
              <Pencil className='h-4 w-4 text-muted-foreground' /> 
              <span>Edit</span>
            </button>
            <div className='h-px bg-border my-1' />
            <button 
              onClick={(e) => { e.stopPropagation(); setOpen(false); onDelete(entry) }} 
              className='w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-muted text-left text-destructive transition-colors'
            >
              <Trash2 className='h-4 w-4' /> 
              <span>Delete</span>
            </button>
          </div>
        </>
      )}
    </div>
  )
}

export function EntriesTable({ entries, isOwner, onEdit, onDelete, onGrant }: EntriesTableProps) {
  const [sorting, setSorting] = useState<SortingState>([])
  const [globalFilter, setGlobalFilter] = useState('')
  const [domainFilter, setDomainFilter] = useState('')

  const filteredEntries = useMemo(() => {
    if (!domainFilter) return entries
    return entries.filter(e => (e.domain || '').toLowerCase().includes(domainFilter.toLowerCase()))
  }, [entries, domainFilter])

  const columns = useMemo<ColumnDef<VaultEntry>[]>(
    () => {
      const cols: ColumnDef<VaultEntry>[] = [
        {
          accessorKey: 'domain',
          header: () => <div className="font-semibold text-foreground px-4">Domain</div>,
          cell: ({ row }) => (
            <div className='flex items-center gap-2 text-xs text-muted-foreground px-4'>
              <span className='truncate max-w-[180px]'>{row.original.domain || '—'}</span>
            </div>
          ),
        },
        {
          accessorKey: 'username',
          header: () => <div className="font-semibold text-foreground">Username</div>,
          cell: ({ row }) => (
            <div className='flex items-center gap-1.5 font-mono text-xs text-muted-foreground'>
              <span className='truncate max-w-[150px]'>{row.original.username || '—'}</span>
              {row.original.username && (
                <button 
                  onClick={(e) => { 
                    e.stopPropagation();
                    navigator.clipboard.writeText(row.original.username); 
                    toast.success('Username copied') 
                  }} 
                  className='p-1 hover:bg-muted rounded text-muted-foreground hover:text-foreground transition-colors'
                  title='Copy username'
                >
                  <Copy className='h-3.5 w-3.5' />
                </button>
              )}
            </div>
          ),
        },
        {
          accessorKey: 'has_password',
          header: () => <div className="font-semibold text-foreground">Password</div>,
          cell: ({ row }) => <PasswordCell vaultId={row.original.vault_id} entryId={row.original.id} hasPassword={row.original.has_password || false} />,
        },
        {
          accessorKey: 'alias',
          header: ({ column }) => {
            return (
              <Button
                variant="ghost"
                onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
                className="-ml-4 h-8 font-semibold text-foreground"
              >
                Alias
                {column.getIsSorted() === "asc" ? (
                  <ArrowUp className="ml-2 h-4 w-4" />
                ) : column.getIsSorted() === "desc" ? (
                  <ArrowDown className="ml-2 h-4 w-4" />
                ) : (
                  <ArrowUpDown className="ml-2 h-4 w-4" />
                )}
              </Button>
            )
          },
          cell: ({ row }) => (
            <div className='flex items-center gap-2 font-medium '>
              <span className='truncate max-w-[150px]'>{row.original.alias || '—'}</span>
            </div>
          ),
        },
      ]

      if (isOwner) {
        cols.push({
          id: 'actions',
          header: () => <div className="text-right font-semibold text-foreground pr-4">Actions</div>,
          cell: ({ row }) => (
            <ActionMenu 
              entry={row.original} 
              onEdit={onEdit} 
              onDelete={onDelete} 
              onGrant={onGrant} 
            />
          ),
        })
      }

      return cols
    },
    [onEdit, onDelete, onGrant, isOwner]
  )

  const table = useReactTable({
    data: filteredEntries,
    columns,
    state: {
      sorting,
      globalFilter,
    },
    onSortingChange: setSorting,
    onGlobalFilterChange: setGlobalFilter,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
  })

  return (
    <div className='space-y-4'>
      <div className='flex items-center gap-4'>
        <div className='relative flex-1 max-w-sm'>
          <Search className='absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground' />
          <Input
            placeholder='Search entries...'
            value={globalFilter ?? ''}
            onChange={(e) => setGlobalFilter(e.target.value)}
            className='pl-9'
          />
        </div>
        <div className='relative flex-1 max-w-[200px]'>
          <Globe className='absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground' />
          <Input
            placeholder='Filter domain...'
            value={domainFilter}
            onChange={(e) => setDomainFilter(e.target.value)}
            className='pl-9'
          />
        </div>
      </div>

      <div className='rounded-xl border bg-card'>
        <Table>
          <TableHeader>
            {table.getHeaderGroups().map((headerGroup) => (
              <TableRow key={headerGroup.id}>
                {headerGroup.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 ? (
              table.getRowModel().rows.map((row) => (
                <TableRow key={row.id}>
                  {row.getVisibleCells().map((cell) => (
                    <TableCell key={cell.id}>
                      {flexRender(
                        cell.column.columnDef.cell,
                        cell.getContext()
                      )}
                    </TableCell>
                  ))}
                </TableRow>
              ))
            ) : (
              <TableRow>
                <TableCell
                  colSpan={columns.length}
                  className="h-24 text-center text-muted-foreground"
                >
                  No entries found.
                </TableCell>
              </TableRow>
            )}
          </TableBody>
        </Table>
      </div>
    </div>
  )
}
 