'use client'

import { useMemo, useState, useEffect, useCallback } from 'react'
import Card from '@mui/material/Card'
import Grid from '@mui/material/Grid2'
import Typography from '@mui/material/Typography'
import Chip from '@mui/material/Chip'
import IconButton from '@mui/material/IconButton'
import MenuItem from '@mui/material/MenuItem'
import Tooltip from '@mui/material/Tooltip'
import Divider from '@mui/material/Divider'
import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'
import ToggleButton from '@mui/material/ToggleButton'
import Switch from '@mui/material/Switch'
import Stack from '@mui/material/Stack'
import Avatar from '@mui/material/Avatar'
import Dialog from '@mui/material/Dialog'
import DialogTitle from '@mui/material/DialogTitle'
import DialogContent from '@mui/material/DialogContent'
import DialogActions from '@mui/material/DialogActions'
import CircularProgress from '@mui/material/CircularProgress'

import {
  createColumnHelper,
  flexRender,
  getCoreRowModel,
  useReactTable,
  getSortedRowModel
} from '@tanstack/react-table'
import type { ColumnDef, FilterFn } from '@tanstack/react-table'
import { rankItem } from '@tanstack/match-sorter-utils'
import type { RankingInfo } from '@tanstack/match-sorter-utils'
import { useLocale, useTranslations } from 'next-intl'
import { useRouter, useSearchParams } from 'next/navigation'
import { toast } from 'react-toastify'

import CustomTextField from '@core/components/mui/TextField'
import tableStyles from '@core/styles/table.module.css'
import CustomTablePaginationComponent from '@/components/CustomTablePaginationComponent'
import type { TPageSizeOption } from '@/@core/types/api'
import { useDeleteTable, useGetTablesList, useReleaseTable, useToggleTableActive } from '@/@core/hooks/data/table'
import type { ITable } from '@/types/data/table'
import TableFormDrawer from './TableFormDrawer'
import TableStatusDrawer from './TableStatusDrawer'
import Button from '@/@core/components/mui/Button'

declare module '@tanstack/table-core' {
  interface FilterFns {
    fuzzy: FilterFn<unknown>
  }
  interface FilterMeta {
    itemRank: RankingInfo
  }
}

type StatusFilter = 'all' | 'available' | 'occupied'
type ActiveFilter = 'all' | 'active' | 'inactive'
type SortField = 'table_number' | 'capacity' | 'location' | 'created_at'

const columnHelper = createColumnHelper<ITable>()

const TablesView = () => {
  const t = useTranslations('tables')
  const tableT = useTranslations('tables.table')
  const statsT = useTranslations('tables.stats')
  const router = useRouter()
  const searchParams = useSearchParams()
  const locale = useLocale()

  const [searchValue, setSearchValue] = useState(searchParams.get('search') || '')
  const [statusFilter, setStatusFilter] = useState<StatusFilter>((searchParams.get('status') as StatusFilter) || 'all')
  const initialActiveParam = searchParams.get('is_active')
  const [activeFilter, setActiveFilter] = useState<ActiveFilter>(
    initialActiveParam === '1' ? 'active' : initialActiveParam === '0' ? 'inactive' : 'all'
  )
  const [capacityFilter, setCapacityFilter] = useState(searchParams.get('capacity') || '')
  const [sortBy, setSortBy] = useState<SortField>((searchParams.get('sort_by') as SortField) || 'table_number')
  const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>(
    (searchParams.get('sort_as') as 'asc' | 'desc') || 'asc'
  )
  const [formMode, setFormMode] = useState<'create' | 'edit'>('create')
  const [formOpen, setFormOpen] = useState(false)
  const [statusDrawer, setStatusDrawer] = useState<{ open: boolean; table?: ITable | null }>({
    open: false,
    table: null
  })
  const [selectedTable, setSelectedTable] = useState<ITable | null>(null)
  const [deleteTarget, setDeleteTarget] = useState<ITable | null>(null)
  const [releaseTarget, setReleaseTarget] = useState<ITable | null>(null)
  const [toggleTargetId, setToggleTargetId] = useState<string | null>(null)
  const [infoTable, setInfoTable] = useState<ITable | null>(null)

  const page = Number(searchParams.get('page')) || 1
  const per_page = (Number(searchParams.get('per_page')) as TPageSizeOption) || 20

  const { data, isLoading, isFetching, refetch } = useGetTablesList(
    {
      page,
      per_page,
      search: searchValue.trim() || undefined,
      is_active: activeFilter === 'all' ? undefined : activeFilter === 'active' ? 1 : 0,
      capacity: capacityFilter ? Number(capacityFilter) : undefined,
      sort_by: sortBy,
      sort_as: sortDirection || undefined
    },
    {
      staleTime: 1000 * 30
    }
  )

  const deleteTable = useDeleteTable()
  const toggleTable = useToggleTableActive()
  const releaseTable = useReleaseTable()

  const fuzzyFilter: FilterFn<ITable> = (row, columnId, value, addMeta) => {
    const itemRank = rankItem(row.getValue(columnId) as string, value as string)

    // Store ranking info if you want to use it later
    addMeta?.({ itemRank })

    return itemRank.passed
  }

  const handleToggleActive = useCallback(
    async (table: ITable) => {
      setToggleTargetId(table.id)
      try {
        await toggleTable.mutateAsync(table.id)
        toast.success(tableT('toggleSuccess'))
      } catch (error) {
        console.error('Failed to toggle table active state', error)
        toast.error(tableT('toggleError'))
      } finally {
        setToggleTargetId(null)
      }
    },
    [toggleTable, tableT]
  )

  const applyFilters = useCallback(
    (updates: Record<string, string | number | undefined>) => {
      const params = new URLSearchParams(window.location.search)

      Object.entries(updates).forEach(([key, value]) => {
        if (value === undefined || value === null || value === '') {
          params.delete(key)
        } else {
          params.set(key, String(value))
        }
      })

      const queryString = params.toString()
      router.push(queryString ? `?${queryString}` : '', { scroll: false })
    },
    [router]
  )

  useEffect(() => {
    const timeout = setTimeout(() => {
      const trimmed = searchValue.trim()
      applyFilters({
        search: trimmed || undefined,
        page: 1
      })
    }, 500)

    return () => clearTimeout(timeout)
  }, [searchValue, applyFilters])

  useEffect(() => {
    const timeout = setTimeout(() => {
      applyFilters({
        capacity: capacityFilter ? Number(capacityFilter) : undefined,
        page: 1
      })
    }, 500)

    return () => clearTimeout(timeout)
  }, [capacityFilter, applyFilters])

  const rows = data?.data?.data || []
  const total = data?.data?.total || 0

  const filteredRows = useMemo(() => {
    return rows.filter(row => {
      if (statusFilter === 'occupied' && !row.is_occupied) return false
      if (statusFilter === 'available' && row.is_occupied) return false
      return true
    })
  }, [rows, statusFilter])

  const stats = useMemo(() => {
    const totalTables = rows.length
    const occupied = rows.filter(row => row.is_occupied).length
    const active = rows.filter(row => row.is_active).length
    return {
      total: totalTables,
      occupied,
      available: totalTables - occupied,
      active,
      utilization: totalTables ? Math.round((occupied / totalTables) * 100) : 0
    }
  }, [rows])

  const handleOpenReleaseDialog = useCallback((table: ITable) => setReleaseTarget(table), [])

  const columns = useMemo<ColumnDef<ITable, any>[]>(() => {
    return [
      columnHelper.accessor('table_number', {
        header: tableT('number'),
        cell: ({ row }) => (
          <div className='flex items-center gap-3'>
            <Avatar variant='rounded' sx={{ bgcolor: row.original.is_occupied ? 'warning.light' : 'success.light' }}>
              {row.original.table_number.slice(0, 3).toUpperCase()}
            </Avatar>
            <div className='flex flex-col'>
              <Typography fontWeight={600}>{row.original.table_number}</Typography>
              <Typography variant='body2' color='text.secondary'>
                {row.original.location || tableT('noLocation')}
              </Typography>
            </div>
          </div>
        )
      }),
      columnHelper.accessor('capacity', {
        header: tableT('capacity'),
        cell: ({ row }) => (
          <Typography>
            {row.original.capacity} {tableT('guests')}
          </Typography>
        )
      }),
      columnHelper.accessor('location', {
        header: tableT('location'),
        cell: ({ row }) => (
          <Typography color='text.secondary'>{row.original.location || tableT('noLocation')}</Typography>
        )
      }),
      columnHelper.accessor('is_occupied', {
        header: tableT('status'),
        cell: ({ row }) => (
          <Chip
            size='small'
            label={
              row.original.is_occupied
                ? locale === 'ar'
                  ? row.original.status_ar
                  : row.original.status_en
                : tableT('available')
            }
            color={row.original.is_occupied ? 'warning' : 'success'}
          />
        )
      }),
      columnHelper.accessor('is_active', {
        header: tableT('active'),
        cell: ({ row }) => {
          const isThisRowLoading = toggleTable.isPending && toggleTargetId === row.original.id

          return (
            <div className='flex items-center gap-2'>
              <Switch
                size='small'
                checked={row.original.is_active}
                onChange={() => handleToggleActive(row.original)}
                disabled={isThisRowLoading}
              />
              {isThisRowLoading && <CircularProgress size={16} />}
            </div>
          )
        }
      }),
      columnHelper.accessor('current_order', {
        header: tableT('currentOrder'),
        cell: ({ row }) =>
          row.original.is_occupied && row.original.current_order ? (
            <Typography>{`#${row.original.current_order?.order_number}`}</Typography>
          ) : (
            <Typography color='text.secondary'>{tableT('noOrder')}</Typography>
          )
      }),
      {
        id: 'actions',
        header: tableT('actions'),
        enableSorting: false,
        cell: ({ row }) => {
          const releaseDisabled = !row.original.is_occupied
          const releaseLoading = releaseTable.isPending && releaseTarget?.id === row.original.id

          return (
            <Stack direction='row' flexWrap='wrap' spacing={1} alignItems='center'>
              <Tooltip title={tableT('viewStatus')}>
                <IconButton
                  onClick={() => setStatusDrawer({ open: true, table: row.original })}
                  size='small'
                  color='primary'
                >
                  <i className='tabler-activity' />
                </IconButton>
              </Tooltip>

              <Tooltip title={tableT('edit')}>
                <IconButton
                  onClick={() => {
                    setSelectedTable(row.original)
                    setFormMode('edit')
                    setFormOpen(true)
                  }}
                  size='small'
                >
                  <i className='tabler-edit' />
                </IconButton>
              </Tooltip>

              <Button
                size='small'
                variant='outlined'
                className='w-fit'
                startIcon={<i className='tabler-info-circle' />}
                onClick={() => setInfoTable(row.original)}
              >
                {tableT('viewInfo')}
              </Button>

              <Button
                size='small'
                variant='outlined'
                color='warning'
                className='w-fit'
                startIcon={releaseLoading ? <CircularProgress size={14} /> : <i className='tabler-flag-checkered' />}
                onClick={() => handleOpenReleaseDialog(row.original)}
                disabled={releaseDisabled || releaseLoading}
              >
                {tableT('release')}
              </Button>

              <Tooltip title={tableT('delete')}>
                <IconButton onClick={() => setDeleteTarget(row.original)} size='small' color='error'>
                  <i className='tabler-trash' />
                </IconButton>
              </Tooltip>
            </Stack>
          )
        }
      }
    ]
  }, [
    tableT,
    locale,
    handleToggleActive,
    handleOpenReleaseDialog,
    toggleTable.isPending,
    releaseTable.isPending,
    toggleTargetId,
    releaseTarget
  ])

  const table = useReactTable({
    data: filteredRows,
    columns,
    manualPagination: true,
    pageCount: Math.max(1, Math.ceil(total / per_page)),
    state: {
      pagination: {
        pageIndex: page - 1,
        pageSize: per_page
      }
    },
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    filterFns: {
      fuzzy: fuzzyFilter
    },
    onPaginationChange: updater => {
      const newPagination = typeof updater === 'function' ? updater(table.getState().pagination) : updater
      applyFilters({
        page: newPagination.pageIndex + 1,
        per_page: newPagination.pageSize
      })
    }
  })

  const handleStatusFilterChange = (_: any, value: StatusFilter) => {
    if (!value) return
    setStatusFilter(value)
    applyFilters({
      page: 1,
      status: value !== 'all' ? value : undefined
    })
  }

  const handleActiveFilterChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value as ActiveFilter
    setActiveFilter(value)
    applyFilters({
      page: 1,
      is_active: value === 'all' ? undefined : value === 'active' ? 1 : 0
    })
  }

  const handleSortByChange = useCallback(
    (value: SortField) => {
      setSortBy(value)
      applyFilters({
        page: 1,
        sort_by: value
      })
    },
    [applyFilters]
  )

  const handleSortDirectionChange = useCallback(
    (value: 'asc' | 'desc') => {
      setSortDirection(value)
      applyFilters({
        page: 1,
        sort_as: value
      })
    },
    [applyFilters]
  )

  const handleDelete = async () => {
    if (!deleteTarget) return
    try {
      await deleteTable.mutateAsync(deleteTarget.id)
      toast.success(tableT('deleteSuccess'))
      setDeleteTarget(null)
      refetch()
    } catch (error) {
      console.error('Failed to delete table', error)
      toast.error(tableT('deleteError'))
    }
  }

  const handlePageSizeChange = useCallback(
    (event: React.ChangeEvent<HTMLInputElement>) => {
      const newSize = Number(event.target.value)
      applyFilters({
        page: 1,
        per_page: newSize
      })
    },
    [applyFilters]
  )

  const handleReleaseConfirm = useCallback(async () => {
    if (!releaseTarget) return
    try {
      await releaseTable.mutateAsync(releaseTarget.id)
      toast.success(tableT('releaseSuccess'))
      setReleaseTarget(null)
    } catch (error) {
      console.error('Failed to release table', error)
      toast.error(tableT('releaseError'))
    }
  }, [releaseTable, releaseTarget, tableT])

  const handleCloseReleaseDialog = useCallback(() => setReleaseTarget(null), [])
  const handleCloseInfoDialog = useCallback(() => setInfoTable(null), [])

  const renderStatsCard = (label: string, value: number, icon: string, color: string) => (
    <Card variant='outlined' className='p-4 flex flex-col gap-2 h-full'>
      <div className='flex items-center justify-between'>
        <Typography variant='body2' color='text.secondary'>
          {label}
        </Typography>
        <div className='rounded-full w-10 h-10 flex items-center justify-center' style={{ backgroundColor: color }}>
          <i className={`${icon} text-white`} />
        </div>
      </div>
      <Typography variant='h5'>{value}</Typography>
    </Card>
  )

  return (
    <>
      <Grid container spacing={6} mb={4}>
        <Grid size={{ xs: 12, md: 8 }}>
          <Card className='p-6 h-full flex flex-col gap-2'>
            <Typography variant='h6'>{t('title')}</Typography>
            <Typography variant='body2' color='text.secondary'>
              {t('subtitle')}
            </Typography>
            <div className='flex flex-wrap gap-4 items-end mt-4'>
              <CustomTextField
                placeholder={tableT('searchPlaceholder')}
                value={searchValue}
                onChange={e => setSearchValue(e.target.value)}
                className='min-w-[220px] max-w-sm flex-1'
              />

              <ToggleButtonGroup
                value={statusFilter}
                exclusive
                onChange={handleStatusFilterChange}
                size='small'
                color='primary'
              >
                <ToggleButton value='all'>{tableT('allStatus')}</ToggleButton>
                <ToggleButton value='available'>{tableT('available')}</ToggleButton>
                <ToggleButton value='occupied'>{tableT('occupied')}</ToggleButton>
              </ToggleButtonGroup>

              <CustomTextField select size='small' value={activeFilter} onChange={handleActiveFilterChange}>
                <MenuItem value='all'>{tableT('allTables')}</MenuItem>
                <MenuItem value='active'>{tableT('active')}</MenuItem>
                <MenuItem value='inactive'>{tableT('inactive')}</MenuItem>
              </CustomTextField>

              <CustomTextField
                type='number'
                size='small'
                label={tableT('minCapacity')}
                value={capacityFilter}
                onChange={e => setCapacityFilter(e.target.value)}
                className='w-32'
                inputProps={{ min: 1 }}
              />

              <CustomTextField
                select
                size='small'
                label={tableT('sortBy')}
                value={sortBy}
                onChange={e => handleSortByChange(e.target.value as SortField)}
                className='w-40'
              >
                <MenuItem value='table_number'>{tableT('number')}</MenuItem>
                <MenuItem value='capacity'>{tableT('capacity')}</MenuItem>
                <MenuItem value='location'>{tableT('location')}</MenuItem>
                <MenuItem value='created_at'>{tableT('createdAt')}</MenuItem>
              </CustomTextField>

              <CustomTextField
                select
                size='small'
                label={tableT('sortDirection')}
                value={sortDirection}
                onChange={e => handleSortDirectionChange(e.target.value as 'asc' | 'desc')}
                className='w-32'
              >
                <MenuItem value='asc'>{tableT('ascending')}</MenuItem>
                <MenuItem value='desc'>{tableT('descending')}</MenuItem>
              </CustomTextField>

              <Button
                variant='contained'
                startIcon={<i className='tabler-plus' />}
                onClick={() => {
                  setFormMode('create')
                  setSelectedTable(null)
                  setFormOpen(true)
                }}
              >
                {tableT('addTable')}
              </Button>
            </div>
          </Card>
        </Grid>

        <Grid size={{ xs: 12, md: 4 }}>
          <Grid container spacing={3}>
            <Grid size={{ xs: 6, md: 12 }}>
              {renderStatsCard(statsT('total'), stats.total, 'tabler-layout-grid', '#1e88e5')}
            </Grid>
            <Grid size={{ xs: 6, md: 6 }}>
              {renderStatsCard(statsT('occupied'), stats.occupied, 'tabler-flame', '#fb8c00')}
            </Grid>
            <Grid size={{ xs: 6, md: 6 }}>
              {renderStatsCard(statsT('available'), stats.available, 'tabler-circle-check', '#43a047')}
            </Grid>
          </Grid>
        </Grid>
      </Grid>

      <Card>
        <div className='flex items-center justify-between px-6 py-4 flex-wrap gap-3'>
          <Typography variant='subtitle1'>
            {tableT('listTitle')} {isFetching && <CircularProgress size={16} className='ml-2' />}
          </Typography>
          <Button variant='text' size='small' onClick={() => refetch()} startIcon={<i className='tabler-refresh' />}>
            {tableT('refresh')}
          </Button>
        </div>
        <Divider />

        <div className='overflow-x-auto'>
          <table className={tableStyles.table}>
            <thead>
              {table.getHeaderGroups().map(headerGroup => (
                <tr key={headerGroup.id}>
                  {headerGroup.headers.map(header => (
                    <th key={header.id}>{flexRender(header.column.columnDef.header, header.getContext())}</th>
                  ))}
                </tr>
              ))}
            </thead>
            <tbody>
              {isLoading ? (
                Array.from({ length: per_page }).map((_, i) => (
                  <tr key={`skeleton-${i}`}>
                    {table.getVisibleFlatColumns().map(column => (
                      <td key={`${column.id}-${i}`}>
                        <div className='h-4 w-full bg-gray-200 animate-pulse rounded' />
                      </td>
                    ))}
                  </tr>
                ))
              ) : table.getRowModel().rows.length === 0 ? (
                <tr>
                  <td colSpan={table.getVisibleFlatColumns().length} className='text-center py-8'>
                    {tableT('noData')}
                  </td>
                </tr>
              ) : (
                table.getRowModel().rows.map(row => (
                  <tr key={row.id}>
                    {row.getVisibleCells().map(cell => (
                      <td key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</td>
                    ))}
                  </tr>
                ))
              )}
            </tbody>
          </table>
        </div>

        <div className='flex flex-wrap items-center justify-between gap-4 px-6 py-4'>
          <CustomTextField select value={per_page} onChange={handlePageSizeChange} className='w-28'>
            <MenuItem value={5}>5</MenuItem>
            <MenuItem value={10}>10</MenuItem>
            <MenuItem value={15}>15</MenuItem>
            <MenuItem value={20}>20</MenuItem>
            <MenuItem value={30}>30</MenuItem>
          </CustomTextField>

          <CustomTablePaginationComponent table={table} totalItems={total} />
        </div>
      </Card>

      <TableFormDrawer
        open={formOpen}
        mode={formMode}
        initialTable={selectedTable}
        onClose={() => setFormOpen(false)}
        onSuccess={() => refetch()}
      />

      <TableStatusDrawer
        open={statusDrawer.open}
        tableId={statusDrawer.table?.id}
        tableLabel={statusDrawer.table?.table_number}
        onClose={() => setStatusDrawer({ open: false, table: null })}
      />

      <Dialog open={Boolean(releaseTarget)} onClose={handleCloseReleaseDialog} maxWidth='xs' fullWidth>
        <DialogTitle>{tableT('releaseConfirmTitle')}</DialogTitle>
        <DialogContent>
          <Typography variant='body2'>
            {tableT('releaseConfirmDescription', { table: releaseTarget?.table_number || '' })}
          </Typography>
        </DialogContent>
        <DialogActions>
          <Button onClick={handleCloseReleaseDialog} disabled={releaseTable.isPending}>
            {tableT('cancel')}
          </Button>
          <Button
            onClick={handleReleaseConfirm}
            color='warning'
            variant='contained'
            disabled={releaseTable.isPending}
            startIcon={
              releaseTable.isPending ? <CircularProgress size={16} /> : <i className='tabler-flag-checkered' />
            }
          >
            {tableT('release')}
          </Button>
        </DialogActions>
      </Dialog>

      <Dialog open={Boolean(infoTable)} onClose={handleCloseInfoDialog} maxWidth='sm' fullWidth>
        <DialogTitle>{tableT('infoTitle', { table: infoTable?.table_number ?? '' })}</DialogTitle>
        <DialogContent>
          <Stack spacing={2}>
            <div className='flex items-center justify-between'>
              <Typography color='text.secondary'>{tableT('capacity')}</Typography>
              <Typography fontWeight={600}>{infoTable?.capacity}</Typography>
            </div>
            <div className='flex items-center justify-between'>
              <Typography color='text.secondary'>{tableT('location')}</Typography>
              <Typography fontWeight={600}>{infoTable?.location || tableT('noLocation')}</Typography>
            </div>
            <div className='flex items-center justify-between'>
              <Typography color='text.secondary'>{tableT('status')}</Typography>
              <Typography fontWeight={600} color={infoTable?.is_occupied ? 'warning.main' : 'success.main'}>
                {infoTable?.is_occupied ? infoTable.status_en : tableT('available')}
              </Typography>
            </div>
            <div className='flex items-center justify-between'>
              <Typography color='text.secondary'>{tableT('ordersTotal')}</Typography>
              <Typography fontWeight={600}>{infoTable?.total_orders ?? 0}</Typography>
            </div>
            <div className='flex items-center justify-between'>
              <Typography color='text.secondary'>{tableT('ordersActive')}</Typography>
              <Typography fontWeight={600}>{infoTable?.active_orders ?? 0}</Typography>
            </div>
            <div className='flex items-center justify-between'>
              <Typography color='text.secondary'>{tableT('createdAt')}</Typography>
              <Typography fontWeight={600}>
                {infoTable?.created_at ? new Date(infoTable.created_at).toLocaleString(locale) : '--'}
              </Typography>
            </div>
          </Stack>
        </DialogContent>
        <DialogActions>
          <Button onClick={handleCloseInfoDialog}>{tableT('close')}</Button>
        </DialogActions>
      </Dialog>

      <Dialog open={Boolean(deleteTarget)} onClose={() => setDeleteTarget(null)} maxWidth='xs' fullWidth>
        <DialogTitle>{tableT('confirmDeleteTitle')}</DialogTitle>
        <DialogContent>
          <Typography variant='body2'>
            {tableT('confirmDeleteDescription', { table: deleteTarget?.table_number || '' })}
          </Typography>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setDeleteTarget(null)} disabled={deleteTable.isPending}>
            {tableT('cancel')}
          </Button>
          <Button
            onClick={handleDelete}
            color='error'
            variant='contained'
            disabled={deleteTable.isPending}
            startIcon={deleteTable.isPending ? <CircularProgress size={16} /> : <i className='tabler-trash' />}
          >
            {tableT('delete')}
          </Button>
        </DialogActions>
      </Dialog>
    </>
  )
}

export default TablesView
