import React, { useEffect, useState, useCallback } from 'react';
import {
  Box, Table, TableBody, TableCell, TableContainer, TableHead, TableRow,
  Paper, FormControl, InputLabel, Select, MenuItem, ToggleButtonGroup,
  ToggleButton, CircularProgress, Typography, TextField, Chip, TablePagination,
  Tooltip,
} from '@mui/material';
import { adminService } from '../../api/adminService';
import type { AuditHistoryUserCount, AuditHistoryRecord } from '../../api/adminService';
import { accountService } from '../../api/accountService';
import { useToastStore } from '../../store/toastStore';

interface Organization {
  org_id: string;
  org_name: string;
  db_name: string;
}

type Preset = 'today' | 'overall' | 'custom_day' | 'custom_range';

const startOfDay = (dateStr: string) => `${dateStr}T00:00:00`;
const endOfDay = (dateStr: string) => `${dateStr}T23:59:59`;
const todayStr = () => new Date().toISOString().split('T')[0];
const RECORDS_PAGE_SIZE = 25;

const efficiencyColor = (value: number): 'success' | 'warning' | 'error' => {
  if (value >= 75) return 'success';
  if (value >= 40) return 'warning';
  return 'error';
};

// "Assigned" is video_date-based (work whose video arrived in this window)
// and "Completed" is Audited_on-based (work actually finished in this
// window) - two independent measures, not two views of the same row set. A
// user can complete backlog items today with nothing newly assigned today.

const SummaryCard: React.FC<{ label: string; value: string; color?: string }> = ({ label, value, color }) => (
  <Paper sx={{ p: 2, minWidth: 160 }}>
    <Typography variant="caption" sx={{ color: 'text.secondary' }}>{label}</Typography>
    <Typography variant="h5" sx={{ fontWeight: 'bold', color }}>{value}</Typography>
  </Paper>
);

export const AuditHistory: React.FC = () => {
  const [organizations, setOrganizations] = useState<Organization[]>([]);
  const [dbName, setDbName] = useState('');
  const [type, setType] = useState<'audits' | 'rectification'>('audits');
  const [preset, setPreset] = useState<Preset>('today');
  const [customDay, setCustomDay] = useState(todayStr());
  const [rangeFrom, setRangeFrom] = useState(todayStr());
  const [rangeTo, setRangeTo] = useState(todayStr());

  const [total, setTotal] = useState(0);
  const [audited, setAudited] = useState(0);
  const [notAudited, setNotAudited] = useState(0);
  const [byUser, setByUser] = useState<AuditHistoryUserCount[]>([]);
  const [loading, setLoading] = useState(false);

  // Drill-down: which user's individual records are currently shown below.
  const [drillUser, setDrillUser] = useState<AuditHistoryUserCount | null>(null);
  const [drillRecords, setDrillRecords] = useState<AuditHistoryRecord[]>([]);
  const [drillTotal, setDrillTotal] = useState(0);
  const [drillPage, setDrillPage] = useState(0);
  const [drillLoading, setDrillLoading] = useState(false);

  useEffect(() => {
    (async () => {
      try {
        const orgsRes = await accountService.getOrganizations();
        const orgs = (orgsRes as any) || [];
        setOrganizations(orgs);
        if (orgs.length > 0) setDbName(orgs[0].db_name);
      } catch (err) {
        useToastStore.getState().showToast('Failed to load organizations.', 'error');
      }
    })();
  }, []);

  const { from, to } = (() => {
    switch (preset) {
      case 'today':
        return { from: startOfDay(todayStr()), to: endOfDay(todayStr()) };
      case 'custom_day':
        return { from: startOfDay(customDay), to: endOfDay(customDay) };
      case 'custom_range':
        // Both fields default to today, so it's easy to end up with an
        // inverted range while adjusting them one at a time (e.g. picking a
        // past "To" before touching "From") - that would silently match zero
        // rows instead of erroring, so normalize the order here.
        return rangeFrom <= rangeTo
          ? { from: startOfDay(rangeFrom), to: endOfDay(rangeTo) }
          : { from: startOfDay(rangeTo), to: endOfDay(rangeFrom) };
      case 'overall':
      default:
        return { from: undefined, to: undefined };
    }
  })();

  const load = useCallback(async () => {
    if (!dbName) return;
    setLoading(true);
    try {
      const result = await adminService.getAuditHistorySummary({ dbName, type, from, to });
      setTotal(result.total);
      setAudited(result.audited);
      setNotAudited(result.notAudited);
      setByUser(result.byUser);
    } catch (err) {
      useToastStore.getState().showToast('Failed to load audit history.', 'error');
    } finally {
      setLoading(false);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [dbName, type, from, to]);

  useEffect(() => {
    load();
    // Changing org/type/date invalidates whatever drill-down was open.
    setDrillUser(null);
  }, [load]);

  const loadDrillRecords = useCallback(async (user: AuditHistoryUserCount, pageIndex: number) => {
    setDrillLoading(true);
    try {
      const result = await adminService.getAuditHistoryUserRecords({
        dbName, type, userId: user.user_id, from, to,
        limit: RECORDS_PAGE_SIZE, offset: pageIndex * RECORDS_PAGE_SIZE,
      });
      setDrillRecords(result.records);
      setDrillTotal(result.total);
    } catch (err) {
      useToastStore.getState().showToast('Failed to load user records.', 'error');
    } finally {
      setDrillLoading(false);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [dbName, type, from, to]);

  const handleRowClick = (user: AuditHistoryUserCount) => {
    if (drillUser?.user_id === user.user_id) {
      setDrillUser(null);
      return;
    }
    setDrillUser(user);
    setDrillPage(0);
    loadDrillRecords(user, 0);
  };

  const handleDrillPageChange = (newPage: number) => {
    setDrillPage(newPage);
    if (drillUser) loadDrillRecords(drillUser, newPage);
  };

  const completionRate = total > 0 ? Math.round((audited / total) * 1000) / 10 : 0;

  return (
    <Box>
      <Box sx={{ display: 'flex', gap: 2, mb: 2, flexWrap: 'wrap', alignItems: 'center' }}>
        <FormControl size="small" sx={{ minWidth: 180 }}>
          <InputLabel>Organization</InputLabel>
          <Select label="Organization" value={dbName} onChange={(e) => setDbName(e.target.value)}>
            {organizations.map((o) => <MenuItem key={o.org_id} value={o.db_name}>{o.org_name}</MenuItem>)}
          </Select>
        </FormControl>

        <ToggleButtonGroup
          value={type}
          exclusive
          onChange={(_, value) => value && setType(value)}
          size="small"
        >
          <ToggleButton value="audits">Audits</ToggleButton>
          <ToggleButton value="rectification">Rectification</ToggleButton>
        </ToggleButtonGroup>

        <ToggleButtonGroup
          value={preset}
          exclusive
          onChange={(_, value) => value && setPreset(value)}
          size="small"
        >
          <ToggleButton value="today">Today</ToggleButton>
          <ToggleButton value="overall">Overall</ToggleButton>
          <ToggleButton value="custom_day">Custom day</ToggleButton>
          <ToggleButton value="custom_range">Custom range</ToggleButton>
        </ToggleButtonGroup>
      </Box>

      <Box sx={{ display: 'flex', gap: 2, mb: 3, alignItems: 'center' }}>
        {preset === 'custom_day' && (
          <TextField
            label="Day"
            type="date"
            size="small"
            value={customDay}
            onChange={(e) => setCustomDay(e.target.value)}
            slotProps={{ inputLabel: { shrink: true } }}
          />
        )}
        {preset === 'custom_range' && (
          <>
            <TextField
              label="From"
              type="date"
              size="small"
              value={rangeFrom}
              onChange={(e) => setRangeFrom(e.target.value)}
              slotProps={{ inputLabel: { shrink: true } }}
            />
            <TextField
              label="To"
              type="date"
              size="small"
              value={rangeTo}
              onChange={(e) => setRangeTo(e.target.value)}
              slotProps={{ inputLabel: { shrink: true } }}
            />
          </>
        )}
      </Box>

      {loading ? (
        <Box sx={{ display: 'flex', justifyContent: 'center', p: 4 }}><CircularProgress /></Box>
      ) : (
        <>
          <Box sx={{ display: 'flex', gap: 2, mb: 3, flexWrap: 'wrap' }}>
            <SummaryCard label="Total in range" value={total.toLocaleString()} />
            <SummaryCard label="Audited" value={audited.toLocaleString()} color="#22c55e" />
            <SummaryCard label="Not audited" value={notAudited.toLocaleString()} color="#f59e0b" />
            <SummaryCard label="Completion rate" value={`${completionRate}%`} />
          </Box>

          <Typography variant="subtitle1" sx={{ mb: 0.5 }}>
            Per-user activity — click a row for their individual records
          </Typography>
          <Typography variant="caption" sx={{ mb: 1, display: 'block', color: 'text.secondary' }}>
            Assigned = video arrived in this window · Completed = audited in this window (may include older backlog)
          </Typography>
          <TableContainer component={Paper} sx={{ mb: drillUser ? 3 : 0 }}>
            <Table size="small">
              <TableHead>
                <TableRow>
                  <TableCell>User</TableCell>
                  <TableCell align="right">
                    <Tooltip title="Records assigned to the user whose video date falls in the selected range">
                      <span>Assigned</span>
                    </Tooltip>
                  </TableCell>
                  <TableCell align="right">
                    <Tooltip title="Records the user completed within the selected range - includes backlog whose video arrived earlier, so this can exceed Assigned">
                      <span>Completed</span>
                    </Tooltip>
                  </TableCell>
                  <TableCell align="right">
                    <Tooltip title="Share of the user's own Assigned queue that is done - never exceeds 100%">
                      <span>Queue Done %</span>
                    </Tooltip>
                  </TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {byUser.length === 0 && (
                  <TableRow>
                    <TableCell colSpan={4} align="center" sx={{ color: 'text.secondary' }}>
                      No activity in this range.
                    </TableCell>
                  </TableRow>
                )}
                {byUser.map((u) => (
                  <TableRow
                    key={u.user_id}
                    hover
                    selected={drillUser?.user_id === u.user_id}
                    onClick={() => handleRowClick(u)}
                    sx={{ cursor: 'pointer' }}
                  >
                    <TableCell>{u.username}</TableCell>
                    <TableCell align="right">{u.assigned.toLocaleString()}</TableCell>
                    <TableCell align="right">{u.completed.toLocaleString()}</TableCell>
                    <TableCell align="right">
                      {u.efficiency === null ? (
                        <Chip size="small" label="N/A" variant="outlined" />
                      ) : (
                        <Chip size="small" label={`${u.efficiency}%`} color={efficiencyColor(u.efficiency)} />
                      )}
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </TableContainer>

          {drillUser && (
            <>
              <Typography variant="subtitle1" sx={{ mb: 1 }}>
                Records assigned to {drillUser.username}
              </Typography>
              {drillLoading ? (
                <Box sx={{ display: 'flex', justifyContent: 'center', p: 4 }}><CircularProgress /></Box>
              ) : (
                <TableContainer component={Paper}>
                  <Table size="small">
                    <TableHead>
                      <TableRow>
                        <TableCell>Anomaly ID</TableCell>
                        <TableCell>Asset</TableCell>
                        <TableCell>Plaza</TableCell>
                        <TableCell>Chainage</TableCell>
                        <TableCell>Video Date</TableCell>
                        <TableCell>Status</TableCell>
                        <TableCell>Audited On</TableCell>
                        <TableCell>Audited By</TableCell>
                      </TableRow>
                    </TableHead>
                    <TableBody>
                      {drillRecords.length === 0 && (
                        <TableRow>
                          <TableCell colSpan={8} align="center" sx={{ color: 'text.secondary' }}>
                            No records found.
                          </TableCell>
                        </TableRow>
                      )}
                      {drillRecords.map((r) => (
                        <TableRow key={r.id}>
                          <TableCell>{r.id}</TableCell>
                          <TableCell>{r.Asset || '—'}</TableCell>
                          <TableCell>{r.Plaza || '—'}</TableCell>
                          <TableCell>{r.Chainage || '—'}</TableCell>
                          <TableCell>{r.video_date ? new Date(r.video_date).toLocaleDateString() : '—'}</TableCell>
                          <TableCell>
                            {r.IsAudited ? (
                              <Chip size="small" label="Audited" color="success" />
                            ) : (
                              <Chip size="small" label="Pending" color="default" />
                            )}
                          </TableCell>
                          <TableCell>{r.Audited_on ? new Date(r.Audited_on).toLocaleString() : '—'}</TableCell>
                          <TableCell>
                            {r.audited_username
                              ? r.audited_username === drillUser.username
                                ? r.audited_username
                                : `${r.audited_username} (reassigned)`
                              : '—'}
                          </TableCell>
                        </TableRow>
                      ))}
                    </TableBody>
                  </Table>
                  <TablePagination
                    component="div"
                    count={drillTotal}
                    page={drillPage}
                    onPageChange={(_, newPage) => handleDrillPageChange(newPage)}
                    rowsPerPage={RECORDS_PAGE_SIZE}
                    rowsPerPageOptions={[RECORDS_PAGE_SIZE]}
                  />
                </TableContainer>
              )}
            </>
          )}
        </>
      )}
    </Box>
  );
};
