import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import {
  Alert,
  Box,
  Button,
  Chip,
  CircularProgress,
  Container,
  Paper,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Typography,
} from '@mui/material';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import DownloadIcon from '@mui/icons-material/Download';
import EditIcon from '@mui/icons-material/Edit';

import { examRepository } from '../../services/exam/examRepository';
import type { BatchResultsResponse } from '../../types/exam.types';

function formatMark(value: number | null | undefined) {
  return value === null || value === undefined ? '' : String(value);
}

const ExamResultsPage: React.FC = () => {
  const { batchId } = useParams<{ batchId: string }>();
  const navigate = useNavigate();
  const [data, setData] = useState<BatchResultsResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [downloading, setDownloading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const load = useCallback(async () => {
    if (!batchId) return;
    setLoading(true);
    setError(null);
    try {
      setData(await examRepository.getBatchResults(batchId));
    } catch (e) {
      setError(e instanceof Error ? e.message : String(e));
    } finally {
      setLoading(false);
    }
  }, [batchId]);

  useEffect(() => {
    void load();
  }, [load]);

  const summary = useMemo(() => {
    const rows = data?.results ?? [];
    const presentTotals = rows
      .map((r) => r.total)
      .filter((v): v is number => typeof v === 'number');
    const average = presentTotals.length
      ? presentTotals.reduce((sum, v) => sum + v, 0) / presentTotals.length
      : null;
    return {
      total: rows.length,
      absent: rows.filter((r) => r.status === 'absent' && r.total === null).length,
      marked: rows.filter((r) => r.total !== null).length,
      average,
    };
  }, [data]);

  const downloadCsv = async () => {
    if (!batchId) return;
    setDownloading(true);
    setError(null);
    try {
      const csv = await examRepository.getBatchCsv(batchId);
      const blob = new Blob([csv], { type: 'text/csv;charset=utf-8' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `batch-${batchId}.csv`;
      document.body.appendChild(a);
      a.click();
      a.remove();
      URL.revokeObjectURL(url);
    } catch (e) {
      setError(e instanceof Error ? e.message : String(e));
    } finally {
      setDownloading(false);
    }
  };

  if (loading) {
    return <Box sx={{ display: 'flex', justifyContent: 'center', py: 8 }}><CircularProgress /></Box>;
  }

  if (error || !data) {
    return (
      <Container maxWidth="lg" sx={{ py: 4 }}>
        <Alert severity="error">{error || 'Results not found'}</Alert>
        <Button sx={{ mt: 2 }} startIcon={<ArrowBackIcon />} onClick={() => navigate('/exam-marker')}>
          Back to Exam Marker
        </Button>
      </Container>
    );
  }

  return (
    <Container maxWidth="xl" sx={{ py: 4 }}>
      <Stack spacing={3}>
        <Box sx={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 2, flexWrap: 'wrap' }}>
          <Box>
            <Button size="small" startIcon={<ArrowBackIcon />} onClick={() => navigate('/exam-marker')} sx={{ mb: 1 }}>
              Exam Marker
            </Button>
            <Typography variant="h4" component="h1" fontWeight={700}>
              {data.batch.title || 'Exam results'}
            </Typography>
            <Typography variant="body2" color="text.secondary">
              Batch {data.batch.id} · created {new Date(data.batch.created_at).toLocaleDateString('en-GB')}
            </Typography>
          </Box>
          <Stack direction="row" spacing={1}>
            <Button variant="outlined" startIcon={<EditIcon />} onClick={() => navigate(`/exam-marker/${data.batch.id}/mark`)}>
              Mark
            </Button>
            <Button variant="contained" startIcon={<DownloadIcon />} onClick={downloadCsv} disabled={downloading}>
              {downloading ? 'Preparing…' : 'Download CSV'}
            </Button>
          </Stack>
        </Box>

        <Stack direction="row" spacing={1} flexWrap="wrap" useFlexGap>
          <Chip label={`${summary.total} students`} />
          <Chip label={`${summary.marked} with marks`} color="success" variant="outlined" />
          <Chip label={`${summary.absent} absent/no scan`} color="warning" variant="outlined" />
          <Chip label={`Class average ${summary.average === null ? '—' : summary.average.toFixed(1)}`} color="primary" />
        </Stack>

        <TableContainer component={Paper} variant="outlined">
          <Table size="small" stickyHeader>
            <TableHead>
              <TableRow>
                <TableCell>Student</TableCell>
                <TableCell>Status</TableCell>
                {data.questions.map((q) => (
                  <TableCell key={q.id} align="right">{q.label} / {q.max_marks}</TableCell>
                ))}
                <TableCell align="right">Total</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {data.results.map((row) => (
                <TableRow key={row.submission_id} sx={row.status === 'absent' && row.total === null ? { opacity: 0.72 } : undefined}>
                  <TableCell>
                    <Typography variant="body2" fontWeight={600}>{row.student_name || row.student_id || 'Unknown student'}</Typography>
                    {row.student_id && <Typography variant="caption" color="text.secondary">{row.student_id}</Typography>}
                  </TableCell>
                  <TableCell>
                    <Chip size="small" label={row.status || 'unknown'} color={row.status === 'absent' ? 'warning' : 'default'} variant="outlined" />
                  </TableCell>
                  {data.questions.map((q) => (
                    <TableCell key={q.id} align="right">{formatMark(row.marks[q.id])}</TableCell>
                  ))}
                  <TableCell align="right"><strong>{formatMark(row.total)}</strong></TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </TableContainer>
      </Stack>
    </Container>
  );
};

export default ExamResultsPage;
