import React, { useMemo, useState } from 'react';
import {
  Autocomplete,
  Avatar,
  Box,
  Button,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  Grid,
  IconButton,
  InputLabel,
  MenuItem,
  Paper,
  Select,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  TextField,
  Tooltip,
  Typography,
  useMediaQuery,
  useTheme
} from '@mui/material';
import { MdWarningAmber, MdAdd, MdCheckCircleOutline } from 'react-icons/md';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';

import Loader from 'components/Loader';
import DebounceSearchBar from 'components/nearle_components/DebounceSearchBar';
import PageHeader from 'components/nearle_components/PageHeader';
import StatCard from 'components/nearle_components/StatCard';
import { OrdersTableSkeleton } from '../orders/OrdersTableSkeleton';
import { getExceptions, createException, updateExceptionStatus, getHubs } from 'pages/api/doormileApi';
import { enqueueSnackbar } from 'notistack';

const DT = {
  radiusCard: 14,
  radiusField: 10,
  textPrimary: '#0f172a',
  textSecondary: '#64748b',
  textMuted: '#94a3b8',
  borderSubtle: '#e2e8f0',
  borderHover: '#cbd5e1',
  divider: '#f1f5f9',
  surface: '#ffffff',
  surfaceAlt: '#f8fafc'
};
const a = (c, suffix) => `${c}${suffix}`;
const soft = (c) => a(c, '18');
const ring = (c) => a(c, '26');
const BRAND = '#C01227';

const EXCEPTION_TYPES = ['Lost', 'Damaged', 'Misrouted', 'Receiver_Refused', 'Missing_Contents', 'Undeliverable'];
const SEVERITIES = ['Low', 'Medium', 'High', 'Critical'];
const SEVERITY_COLOR = { Low: '#94a3b8', Medium: '#f59e0b', High: '#ef4444', Critical: '#7f1d1d' };

const emptyForm = { consignmentid: '', tripsheetid: '', hub: null, exceptiontype: 'Damaged', severity: 'Medium', description: '' };

const Exceptions = () => {
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down('md'));
  const queryClient = useQueryClient();
  const [searchword, setSearchword] = useState('');
  const [debouncedSearch, setDebouncedSearch] = useState('');
  const [dialogOpen, setDialogOpen] = useState(false);
  const [form, setForm] = useState(emptyForm);
  const [resolveRow, setResolveRow] = useState(null);
  const [resolution, setResolution] = useState('');
  const [resolveStatus, setResolveStatus] = useState('Resolved');

  const { data: exceptions = [], isLoading } = useQuery({ queryKey: ['admin-exceptions'], queryFn: getExceptions });
  const { data: hubs = [] } = useQuery({ queryKey: ['admin-hubs'], queryFn: getHubs });
  const hubMap = useMemo(() => new Map((hubs || []).map((h) => [h.hubid, h])), [hubs]);

  const rows = useMemo(() => {
    if (!debouncedSearch) return exceptions;
    const q = debouncedSearch.toLowerCase().trim();
    return exceptions.filter((row) =>
      [row.exceptiontype, row.severity, row.description, row.status].filter(Boolean).some((f) => String(f).toLowerCase().includes(q))
    );
  }, [exceptions, debouncedSearch]);

  const stats = useMemo(() => {
    const total = exceptions.length;
    const open = exceptions.filter((e) => !['Resolved', 'Closed'].includes(e.status)).length;
    const critical = exceptions.filter((e) => e.severity === 'Critical').length;
    return { total, open, critical };
  }, [exceptions]);

  const opentoast = (message, variant = 'error') =>
    enqueueSnackbar(message, { variant, anchorOrigin: { vertical: 'top', horizontal: 'right' }, autoHideDuration: 2000 });

  const createMutation = useMutation({
    mutationFn: (data) => createException(data),
    onSuccess: (res) => {
      if (res.success) {
        opentoast('Exception logged', 'success');
        queryClient.invalidateQueries({ queryKey: ['admin-exceptions'] });
        setDialogOpen(false);
        setForm(emptyForm);
      } else {
        opentoast(res.message || 'Failed to log exception');
      }
    },
    onError: (err) => opentoast(err.response?.data?.message || err.message || 'Failed to log exception')
  });

  const resolveMutation = useMutation({
    mutationFn: () => updateExceptionStatus(resolveRow.exceptionid, resolveStatus, resolution),
    onSuccess: (res) => {
      if (res.success) {
        opentoast('Exception updated', 'success');
        queryClient.invalidateQueries({ queryKey: ['admin-exceptions'] });
        setResolveRow(null);
        setResolution('');
      } else {
        opentoast(res.message || 'Failed to update exception');
      }
    },
    onError: (err) => opentoast(err.response?.data?.message || err.message || 'Failed to update exception')
  });

  const handleCreate = () => {
    if (!form.consignmentid || !form.description) {
      opentoast('Fill Consignment ID and Description');
      return;
    }
    createMutation.mutate({
      consignmentid: form.consignmentid,
      tripsheetid: form.tripsheetid || undefined,
      hubid: form.hub?.hubid,
      exceptiontype: form.exceptiontype,
      severity: form.severity,
      description: form.description
    });
  };

  return (
    <>
      {(isLoading || createMutation.isPending || resolveMutation.isPending) && <Loader />}

      <PageHeader
        title="Exceptions"
        subtitle="Live · Lost / Damaged / Misrouted Parcels"
        live
        action={
          <Button variant="contained" startIcon={<MdAdd size={16} />} onClick={() => setDialogOpen(true)} sx={{ bgcolor: BRAND, whiteSpace: 'nowrap' }}>
            Log Exception
          </Button>
        }
      />

      <Grid container spacing={{ xs: 2, md: 2.5 }} sx={{ mb: { xs: 1.5, md: 2 } }}>
        <Grid item xs={4}>
          <StatCard title="Total" value={stats.total} icon={<MdWarningAmber size={20} />} color={BRAND} />
        </Grid>
        <Grid item xs={4}>
          <StatCard title="Open" value={stats.open} icon={<MdWarningAmber size={20} />} color="#f59e0b" />
        </Grid>
        <Grid item xs={4}>
          <StatCard title="Critical" value={stats.critical} icon={<MdWarningAmber size={20} />} color="#ef4444" />
        </Grid>
      </Grid>

      <Paper
        elevation={0}
        sx={{ mt: { xs: 1.5, md: 2 }, p: { xs: 1, md: 1.5 }, borderTopLeftRadius: DT.radiusCard / 8, borderTopRightRadius: DT.radiusCard / 8, border: '1px solid', borderColor: DT.borderSubtle, borderBottom: 0, background: '#fff' }}
      >
        <Stack direction={{ xs: 'column', sm: 'row' }} alignItems={{ xs: 'stretch', sm: 'center' }} justifyContent="space-between" spacing={1.25}>
          <Typography variant="body2" sx={{ color: DT.textPrimary, fontWeight: 700 }}>
            {exceptions.length} total · {rows.length} shown
          </Typography>
          <Box sx={{ width: { xs: '100%', sm: 280 } }}>
            <DebounceSearchBar
              value={searchword}
              onChange={setSearchword}
              onDebouncedChange={setDebouncedSearch}
              placeholder="Search exceptions (ctrl+k)"
              sx={{
                m: 0,
                width: '100%',
                borderRadius: DT.radiusField + 'px',
                bgcolor: DT.surface,
                '& fieldset': { borderColor: DT.borderSubtle, borderWidth: 1 },
                '&:hover fieldset': { borderColor: DT.borderHover },
                '&.Mui-focused fieldset': { borderColor: BRAND, borderWidth: 1.5 },
                '&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(BRAND)}` }
              }}
            />
          </Box>
        </Stack>
      </Paper>

      <Paper elevation={0} sx={{ borderBottomLeftRadius: DT.radiusCard / 8, borderBottomRightRadius: DT.radiusCard / 8, border: '1px solid', borderColor: DT.borderSubtle, overflow: 'hidden', background: '#fff' }}>
        <TableContainer sx={{ maxHeight: { xs: 'calc(100vh - 260px)', md: 'calc(100vh - 190px)' } }}>
          <Table stickyHeader sx={{ minWidth: isMobile ? 960 : 1020 }}>
            <TableHead>
              <TableRow sx={{ '& th': { backgroundColor: DT.surfaceAlt, color: DT.textSecondary, fontSize: 11, fontWeight: 800, letterSpacing: 0.6, textTransform: 'uppercase', whiteSpace: 'nowrap', borderBottom: `1px solid ${DT.borderSubtle}` } }}>
                <TableCell>#</TableCell>
                <TableCell>Consignment</TableCell>
                <TableCell>Hub</TableCell>
                <TableCell>Type</TableCell>
                <TableCell>Severity</TableCell>
                <TableCell>Description</TableCell>
                <TableCell>Status</TableCell>
                <TableCell align="right">Actions</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {isLoading && <OrdersTableSkeleton col={6} />}
              {rows.length === 0 && !isLoading ? (
                <TableRow>
                  <TableCell colSpan={8} sx={{ py: 6 }}>
                    <Stack alignItems="center" spacing={1.5}>
                      <Avatar sx={{ width: 64, height: 64, bgcolor: soft('#94a3b8'), color: DT.textMuted }}>
                        <MdWarningAmber size={28} />
                      </Avatar>
                      <Typography variant="subtitle1" sx={{ fontWeight: 700 }}>
                        No exceptions logged
                      </Typography>
                    </Stack>
                  </TableCell>
                </TableRow>
              ) : (
                rows.map((row, index) => (
                  <TableRow key={row.exceptionid || index} sx={{ '& td': { borderBottom: `1px solid ${DT.divider}` }, '&:hover': { backgroundColor: DT.surfaceAlt } }}>
                    <TableCell>{index + 1}</TableCell>
                    <TableCell>{row.consignmentid}</TableCell>
                    <TableCell>{hubMap.get(row.hubid)?.hubname || (row.hubid ? `Hub #${row.hubid}` : '—')}</TableCell>
                    <TableCell>{row.exceptiontype}</TableCell>
                    <TableCell>
                      <Box
                        sx={{
                          display: 'inline-flex',
                          px: 1,
                          py: 0.375,
                          borderRadius: 999,
                          bgcolor: soft(SEVERITY_COLOR[row.severity] || '#94a3b8'),
                          color: SEVERITY_COLOR[row.severity] || '#94a3b8',
                          fontSize: 11,
                          fontWeight: 800
                        }}
                      >
                        {row.severity}
                      </Box>
                    </TableCell>
                    <TableCell sx={{ maxWidth: 220 }}>
                      <Typography variant="body2" noWrap title={row.description}>
                        {row.description}
                      </Typography>
                    </TableCell>
                    <TableCell>{row.status || 'Open'}</TableCell>
                    <TableCell align="right">
                      {!['Resolved', 'Closed'].includes(row.status) && (
                        <Tooltip title="Resolve / Close">
                          <IconButton size="small" onClick={() => setResolveRow(row)} sx={{ color: '#10b981' }}>
                            <MdCheckCircleOutline size={16} />
                          </IconButton>
                        </Tooltip>
                      )}
                    </TableCell>
                  </TableRow>
                ))
              )}
            </TableBody>
          </Table>
        </TableContainer>
      </Paper>

      <Dialog open={dialogOpen} onClose={() => setDialogOpen(false)} maxWidth="sm" fullWidth>
        <DialogTitle sx={{ fontWeight: 700 }}>Log Exception</DialogTitle>
        <DialogContent>
          <Grid container spacing={2} sx={{ mt: 0.5 }}>
            <Grid item xs={12} sm={6}>
              <Stack spacing={1}>
                <InputLabel>Consignment ID</InputLabel>
                <TextField value={form.consignmentid} onChange={(e) => setForm((f) => ({ ...f, consignmentid: e.target.value }))} />
              </Stack>
            </Grid>
            <Grid item xs={12} sm={6}>
              <Stack spacing={1}>
                <InputLabel>Tripsheet ID (optional)</InputLabel>
                <TextField value={form.tripsheetid} onChange={(e) => setForm((f) => ({ ...f, tripsheetid: e.target.value }))} />
              </Stack>
            </Grid>
            <Grid item xs={12} sm={6}>
              <Stack spacing={1}>
                <InputLabel>Hub (optional)</InputLabel>
                <Autocomplete
                  options={hubs || []}
                  getOptionLabel={(option) => option.hubname || ''}
                  value={form.hub}
                  onChange={(e, value) => setForm((f) => ({ ...f, hub: value }))}
                  renderInput={(params) => <TextField {...params} placeholder="Choose hub" />}
                />
              </Stack>
            </Grid>
            <Grid item xs={12} sm={6}>
              <Stack spacing={1}>
                <InputLabel>Type</InputLabel>
                <Select fullWidth value={form.exceptiontype} onChange={(e) => setForm((f) => ({ ...f, exceptiontype: e.target.value }))}>
                  {EXCEPTION_TYPES.map((t) => (
                    <MenuItem key={t} value={t}>
                      {t.replace(/_/g, ' ')}
                    </MenuItem>
                  ))}
                </Select>
              </Stack>
            </Grid>
            <Grid item xs={12} sm={6}>
              <Stack spacing={1}>
                <InputLabel>Severity</InputLabel>
                <Select fullWidth value={form.severity} onChange={(e) => setForm((f) => ({ ...f, severity: e.target.value }))}>
                  {SEVERITIES.map((s) => (
                    <MenuItem key={s} value={s}>
                      {s}
                    </MenuItem>
                  ))}
                </Select>
              </Stack>
            </Grid>
            <Grid item xs={12}>
              <Stack spacing={1}>
                <InputLabel>Description</InputLabel>
                <TextField multiline minRows={2} value={form.description} onChange={(e) => setForm((f) => ({ ...f, description: e.target.value }))} />
              </Stack>
            </Grid>
          </Grid>
        </DialogContent>
        <DialogActions sx={{ px: 3, pb: 2 }}>
          <Button onClick={() => setDialogOpen(false)}>Cancel</Button>
          <Button variant="contained" onClick={handleCreate} sx={{ bgcolor: BRAND }}>
            Log Exception
          </Button>
        </DialogActions>
      </Dialog>

      <Dialog open={!!resolveRow} onClose={() => setResolveRow(null)} maxWidth="xs" fullWidth>
        <DialogTitle sx={{ fontWeight: 700 }}>Resolve Exception</DialogTitle>
        <DialogContent>
          <Stack spacing={2} sx={{ mt: 1 }}>
            <Stack spacing={1}>
              <InputLabel>Status</InputLabel>
              <Select fullWidth value={resolveStatus} onChange={(e) => setResolveStatus(e.target.value)}>
                <MenuItem value="Resolved">Resolved</MenuItem>
                <MenuItem value="Closed">Closed</MenuItem>
              </Select>
            </Stack>
            <Stack spacing={1}>
              <InputLabel>Resolution Notes</InputLabel>
              <TextField multiline minRows={2} value={resolution} onChange={(e) => setResolution(e.target.value)} />
            </Stack>
          </Stack>
        </DialogContent>
        <DialogActions sx={{ px: 3, pb: 2 }}>
          <Button onClick={() => setResolveRow(null)}>Cancel</Button>
          <Button variant="contained" onClick={() => resolveMutation.mutate()} sx={{ bgcolor: BRAND }}>
            Save
          </Button>
        </DialogActions>
      </Dialog>
    </>
  );
};

export default Exceptions;
