import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import {
  Alert, Box, Button, Card, CardActionArea, CardContent, Chip, CircularProgress, Container,
  Dialog, DialogActions, DialogContent, DialogTitle, Stack, TextField, Typography,
} from '@mui/material';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import PlaylistAddCheckIcon from '@mui/icons-material/PlaylistAddCheck';
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
import RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked';

import { examRepository } from '../../services/exam/examRepository';
import type { BankQuestion, BankResponse } from '../../types/exam.types';

const QuestionBankPage: React.FC = () => {
  const navigate = useNavigate();
  const [bank, setBank] = useState<BankResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [specRef, setSpecRef] = useState<string | null>(null);
  const [subject, setSubject] = useState<string | null>(null);
  const [selected, setSelected] = useState<Set<string>>(new Set());
  const [dialogOpen, setDialogOpen] = useState(false);
  const [title, setTitle] = useState('');
  const [creating, setCreating] = useState(false);

  const load = useCallback(async () => {
    setLoading(true); setError(null);
    try {
      setBank(await examRepository.getBank({ specRef: specRef ?? undefined, subject: subject ?? undefined }));
    } catch (e) {
      setError(e instanceof Error ? e.message : String(e));
    } finally {
      setLoading(false);
    }
  }, [specRef, subject]);

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

  const toggle = (id: string) => setSelected((prev) => {
    const next = new Set(prev);
    if (next.has(id)) next.delete(id); else next.add(id);
    return next;
  });

  const selectedList = useMemo(() => Array.from(selected), [selected]);
  const selectedQuestions = useMemo(
    () => (bank?.questions ?? []).filter((q) => selected.has(q.id)),
    [bank, selected],
  );
  const totalMarks = selectedQuestions.reduce((s, q) => s + (q.max_marks ?? 0), 0);

  // facet lists (sorted) with counts
  const specFacets = Object.entries(bank?.facets.spec_ref ?? {}).sort((a, b) => (a[0] < b[0] ? -1 : 1));
  const subjectFacets = Object.entries(bank?.facets.subject ?? {}).sort((a, b) => (a[0] < b[0] ? -1 : 1));

  const create = async () => {
    setCreating(true); setError(null);
    try {
      const subj = subject ?? selectedQuestions[0]?.paper.subject ?? undefined;
      const res = await examRepository.createCustomPaper({
        title: title.trim() || `Custom paper — ${new Date().toISOString().slice(0, 10)}`,
        subject: subj ?? undefined,
        question_ids: selectedList,
      });
      navigate(`/exam-marker/${res.id}/setup`);
    } catch (e) {
      setError(e instanceof Error ? e.message : String(e));
      setCreating(false);
      setDialogOpen(false);
    }
  };

  return (
    <Container maxWidth="lg" sx={{ py: 4 }}>
      <Button size="small" startIcon={<ArrowBackIcon />} onClick={() => navigate('/exam-marker')} sx={{ mb: 1 }}>
        Exam Marker
      </Button>
      <Box sx={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 2, flexWrap: 'wrap', mb: 2 }}>
        <Box>
          <Typography variant="h4" component="h1" fontWeight={700}>Question bank</Typography>
          <Typography variant="body2" color="text.secondary">
            Plan by spec point, then assemble a custom paper from questions across your papers.
          </Typography>
        </Box>
        <Button
          variant="contained"
          startIcon={<PlaylistAddCheckIcon />}
          disabled={selected.size === 0}
          onClick={() => setDialogOpen(true)}
        >
          Create paper ({selected.size}{totalMarks ? ` · ${totalMarks}m` : ''})
        </Button>
      </Box>

      {error && <Alert severity="error" sx={{ mb: 2 }} onClose={() => setError(null)}>{error}</Alert>}

      {/* Filters */}
      <Stack spacing={1} sx={{ mb: 2 }}>
        <Stack direction="row" spacing={0.75} alignItems="center" flexWrap="wrap" useFlexGap>
          <Typography variant="caption" color="text.secondary" sx={{ mr: 0.5 }}>Spec point:</Typography>
          <Chip size="small" label="all" color={specRef ? 'default' : 'primary'} onClick={() => setSpecRef(null)} variant={specRef ? 'outlined' : 'filled'} />
          {specFacets.map(([ref, count]) => (
            <Chip key={ref} size="small" label={`${ref} · ${count}`} color={specRef === ref ? 'primary' : 'default'} variant={specRef === ref ? 'filled' : 'outlined'} onClick={() => setSpecRef(ref)} />
          ))}
        </Stack>
        {subjectFacets.length > 1 && (
          <Stack direction="row" spacing={0.75} alignItems="center" flexWrap="wrap" useFlexGap>
            <Typography variant="caption" color="text.secondary" sx={{ mr: 0.5 }}>Subject:</Typography>
            <Chip size="small" label="all" color={subject ? 'default' : 'secondary'} onClick={() => setSubject(null)} variant={subject ? 'outlined' : 'filled'} />
            {subjectFacets.map(([s, count]) => (
              <Chip key={s} size="small" label={`${s} · ${count}`} color={subject === s ? 'secondary' : 'default'} variant={subject === s ? 'filled' : 'outlined'} onClick={() => setSubject(s)} sx={{ textTransform: 'capitalize' }} />
            ))}
          </Stack>
        )}
      </Stack>

      {loading ? (
        <Box sx={{ display: 'flex', justifyContent: 'center', py: 6 }}><CircularProgress /></Box>
      ) : (bank?.questions.length ?? 0) === 0 ? (
        <Alert severity="info">
          No questions match yet. Questions appear here once your templates have parts with spec points
          (set them in the mark-scheme editor). Auto-map + confirm on a paper to populate it.
        </Alert>
      ) : (
        <>
          <Typography variant="body2" color="text.secondary" sx={{ mb: 1 }}>
            {bank?.n} question{bank?.n === 1 ? '' : 's'} · click to add to your paper
          </Typography>
          <Box sx={{ display: 'grid', gridTemplateColumns: { xs: '1fr', sm: '1fr 1fr', md: '1fr 1fr 1fr' }, gap: 1.5 }}>
            {(bank?.questions ?? []).map((q: BankQuestion) => {
              const on = selected.has(q.id);
              return (
                <Card key={q.id} variant="outlined" sx={{ borderColor: on ? 'primary.main' : 'divider', borderWidth: on ? 2 : 1 }}>
                  <CardActionArea onClick={() => toggle(q.id)}>
                    <CardContent sx={{ pb: 1.5 }}>
                      <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 0.5 }}>
                        <Typography variant="subtitle2" fontWeight={700}>Q{q.label ?? '?'}</Typography>
                        {on ? <CheckCircleIcon color="primary" fontSize="small" /> : <RadioButtonUncheckedIcon color="disabled" fontSize="small" />}
                      </Box>
                      <Stack direction="row" spacing={0.5} flexWrap="wrap" useFlexGap sx={{ mb: 0.75 }}>
                        <Chip size="small" label={`${q.max_marks ?? 0} marks`} />
                        {q.answer_type && <Chip size="small" variant="outlined" label={q.answer_type} />}
                        {q.spec_ref && <Chip size="small" color="info" label={q.spec_ref} />}
                      </Stack>
                      <Typography variant="caption" color="text.secondary" noWrap sx={{ display: 'block', textTransform: 'capitalize' }}>
                        {[q.paper.subject, q.paper.title].filter(Boolean).join(' · ') || 'Untitled paper'}
                      </Typography>
                    </CardContent>
                  </CardActionArea>
                </Card>
              );
            })}
          </Box>
        </>
      )}

      <Dialog open={dialogOpen} onClose={() => !creating && setDialogOpen(false)} fullWidth maxWidth="sm">
        <DialogTitle>Create custom paper</DialogTitle>
        <DialogContent>
          <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
            {selected.size} question{selected.size === 1 ? '' : 's'} · {totalMarks} marks. This creates a new
            template you can open in setup and use for marking.
          </Typography>
          <TextField
            autoFocus
            fullWidth
            label="Paper title"
            value={title}
            onChange={(e) => setTitle(e.target.value)}
            placeholder={`Custom paper — ${new Date().toISOString().slice(0, 10)}`}
          />
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setDialogOpen(false)} disabled={creating}>Cancel</Button>
          <Button variant="contained" onClick={create} disabled={creating} startIcon={creating ? <CircularProgress size={16} color="inherit" /> : undefined}>
            {creating ? 'Creating…' : 'Create & open'}
          </Button>
        </DialogActions>
      </Dialog>
    </Container>
  );
};

export default QuestionBankPage;
