import React, { useEffect, useState, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import {
    Box, Typography, Button, CircularProgress, Alert, Chip,
    Dialog, DialogTitle, DialogContent, DialogActions,
    TextField, Select, MenuItem, FormControl, InputLabel,
    Divider, IconButton, Tooltip, List, ListItemButton, ListItemText,
    InputAdornment,
} from '@mui/material';
import {
    ChevronLeft, ChevronRight, Today, EditNote, LibraryAdd, Search, OpenInNew,
} from '@mui/icons-material';
import { useAuth } from '../../contexts/AuthContext';

const API_BASE = import.meta.env.VITE_API_URL || 'http://localhost:8000';

// ─── Types ────────────────────────────────────────────────────────────────────

interface Lesson {
    id: string;
    date: string;
    period_code: string;
    period_name: string;
    start_time: string | null;
    end_time: string | null;
    class_name: string | null;
    subject: string | null;
    year_group: string | null;
    week_cycle: string;
    day_of_week: string;
    status: string;
    lesson_plan: Record<string, any>;
    notes: string | null;
    whiteboard_room_id: string | null;
}

interface DayEntry {
    date: string;
    day_of_week: string;
    is_today: boolean;
    lessons: Lesson[];
}

// ─── Helpers ──────────────────────────────────────────────────────────────────

function toMonday(d: Date): string {
    const day = d.getDay();
    const diff = day === 0 ? -6 : 1 - day;
    const monday = new Date(d);
    monday.setDate(d.getDate() + diff);
    return monday.toISOString().slice(0, 10);
}

function addWeeks(isoDate: string, n: number): string {
    const d = new Date(isoDate + 'T00:00:00');
    d.setDate(d.getDate() + n * 7);
    return d.toISOString().slice(0, 10);
}

function formatDate(isoDate: string): string {
    return new Date(isoDate + 'T00:00:00').toLocaleDateString('en-GB', {
        day: 'numeric', month: 'short',
    });
}

const STATUS_COLORS: Record<string, 'default' | 'primary' | 'success' | 'error' | 'warning'> = {
    planned: 'default',
    in_progress: 'primary',
    completed: 'success',
    cancelled: 'error',
    substituted: 'warning',
};

// ─── Lesson edit dialog ───────────────────────────────────────────────────────

interface EditDialogProps {
    lesson: Lesson | null;
    onClose: () => void;
    onSave: (id: string, updates: { notes?: string; status?: string }) => Promise<void>;
}

function LessonEditDialog({ lesson, onClose, onSave }: EditDialogProps) {
    const [notes, setNotes] = useState('');
    const [status, setStatus] = useState('planned');
    const [saving, setSaving] = useState(false);

    useEffect(() => {
        if (lesson) {
            setNotes(lesson.notes || '');
            setStatus(lesson.status || 'planned');
        }
    }, [lesson]);

    const handleSave = async () => {
        if (!lesson) return;
        setSaving(true);
        await onSave(lesson.id, { notes, status });
        setSaving(false);
        onClose();
    };

    if (!lesson) return null;

    return (
        <Dialog open={!!lesson} onClose={onClose} maxWidth="sm" fullWidth>
            <DialogTitle sx={{ pb: 1 }}>
                <Box>
                    <Typography variant="h6">
                        {lesson.class_name || lesson.period_code}
                    </Typography>
                    <Typography variant="caption" sx={{ color: 'text.secondary' }}>
                        {lesson.date} · {lesson.period_name}
                        {lesson.start_time && ` · ${lesson.start_time}–${lesson.end_time}`}
                        {lesson.week_cycle && ` · Week ${lesson.week_cycle}`}
                    </Typography>
                </Box>
            </DialogTitle>
            <DialogContent>
                <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, pt: 1 }}>
                    <FormControl size="small" fullWidth>
                        <InputLabel>Status</InputLabel>
                        <Select label="Status" value={status} onChange={e => setStatus(e.target.value)}>
                            <MenuItem value="planned">Planned</MenuItem>
                            <MenuItem value="in_progress">In Progress</MenuItem>
                            <MenuItem value="completed">Completed</MenuItem>
                            <MenuItem value="cancelled">Cancelled</MenuItem>
                            <MenuItem value="substituted">Substituted</MenuItem>
                        </Select>
                    </FormControl>
                    <TextField
                        label="Notes"
                        value={notes}
                        onChange={e => setNotes(e.target.value)}
                        multiline
                        minRows={3}
                        fullWidth
                        size="small"
                        placeholder="Lesson notes, objectives, reminders…"
                    />
                </Box>
            </DialogContent>
            <DialogActions sx={{ px: 3, pb: 2 }}>
                <Button onClick={onClose} disabled={saving}>Cancel</Button>
                <Button onClick={handleSave} variant="contained" disabled={saving}>
                    {saving ? <CircularProgress size={18} /> : 'Save'}
                </Button>
            </DialogActions>
        </Dialog>
    );
}

// ─── Lesson card ──────────────────────────────────────────────────────────────

interface LessonCardProps {
    lesson: Lesson;
    onEdit: (l: Lesson) => void;
    onAssignPlan: (l: Lesson) => void;
}

function LessonCard({ lesson, onEdit, onAssignPlan }: LessonCardProps) {
    return (
        <Box
            sx={{
                p: 1.25,
                mb: 0.75,
                border: '1px solid',
                borderColor: 'divider',
                borderRadius: 1,
                bgcolor: lesson.status === 'completed' ? 'action.hover' : 'background.paper',
                opacity: lesson.status === 'cancelled' ? 0.5 : 1,
                display: 'flex',
                flexDirection: 'column',
                gap: 0.5,
            }}
        >
            <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
                <Typography variant="caption" sx={{ fontWeight: 700, lineHeight: 1.2 }}>
                    {lesson.class_name || lesson.period_code}
                </Typography>
                <Box sx={{ display: 'flex', gap: 0 }}>
                    <Tooltip title="Assign lesson plan">
                        <IconButton size="small" onClick={() => onAssignPlan(lesson)} sx={{ p: 0.25 }}>
                            <LibraryAdd fontSize="inherit" />
                        </IconButton>
                    </Tooltip>
                    <Tooltip title="Edit lesson">
                        <IconButton size="small" onClick={() => onEdit(lesson)} sx={{ p: 0.25 }}>
                            <EditNote fontSize="inherit" />
                        </IconButton>
                    </Tooltip>
                </Box>
            </Box>
            {lesson.subject && (
                <Typography variant="caption" sx={{ color: 'text.secondary', fontSize: '0.7rem' }}>
                    {lesson.subject}{lesson.year_group ? ` · Y${lesson.year_group}` : ''}
                </Typography>
            )}
            <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5, flexWrap: 'wrap' }}>
                <Typography variant="caption" sx={{ color: 'text.secondary', fontSize: '0.7rem' }}>
                    {lesson.start_time ? `${lesson.start_time}–${lesson.end_time}` : lesson.period_name}
                </Typography>
                {lesson.week_cycle && (
                    <Chip label={`W${lesson.week_cycle}`} size="small" sx={{ height: 16, fontSize: '0.65rem' }} />
                )}
                <Chip
                    label={lesson.status}
                    size="small"
                    color={STATUS_COLORS[lesson.status] ?? 'default'}
                    sx={{ height: 16, fontSize: '0.65rem' }}
                />
            </Box>
            {lesson.notes && (
                <Typography variant="caption" sx={{ color: 'text.secondary', fontSize: '0.68rem', fontStyle: 'italic', mt: 0.25 }}>
                    {lesson.notes.length > 80 ? lesson.notes.slice(0, 80) + '…' : lesson.notes}
                </Typography>
            )}
        </Box>
    );
}

// ─── Main page ────────────────────────────────────────────────────────────────

const TaughtLessonsPage: React.FC = () => {
    const { accessToken } = useAuth();
    const navigate = useNavigate();
    const [weekStart, setWeekStart] = useState<string>(toMonday(new Date()));
    const [days, setDays] = useState<DayEntry[]>([]);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const [materializing, setMaterializing] = useState(false);
    const [materializeResult, setMaterializeResult] = useState<string | null>(null);
    const [editingLesson, setEditingLesson] = useState<Lesson | null>(null);
    const [assigningLesson, setAssigningLesson] = useState<Lesson | null>(null);
    const [plans, setPlans] = useState<{ id: string; title: string; subject: string | null }[]>([]);
    const [planSearch, setPlanSearch] = useState('');
    const [assignSaving, setAssignSaving] = useState(false);
    const [assignResult, setAssignResult] = useState<string | null>(null);

    const loadLessons = useCallback(async (ws: string) => {
        if (!accessToken) return;
        setLoading(true);
        setError(null);
        try {
            const res = await fetch(
                `${API_BASE}/timetable/lessons?week_start=${ws}&weeks=1`,
                { headers: { Authorization: `Bearer ${accessToken}` } }
            );
            const data = await res.json();
            if (data.status === 'ok') {
                setDays(data.days);
            } else {
                setError(data.message || 'Failed to load lessons');
            }
        } catch (e: any) {
            setError(e.message);
        } finally {
            setLoading(false);
        }
    }, [accessToken]);

    useEffect(() => { loadLessons(weekStart); }, [weekStart, loadLessons]);

    const goThisWeek = () => setWeekStart(toMonday(new Date()));
    const prevWeek = () => setWeekStart(ws => addWeeks(ws, -1));
    const nextWeek = () => setWeekStart(ws => addWeeks(ws, 1));

    const handleMaterialize = async () => {
        if (!accessToken) return;
        setMaterializing(true);
        setMaterializeResult(null);
        try {
            const res = await fetch(`${API_BASE}/timetable/materialize`, {
                method: 'POST',
                headers: { Authorization: `Bearer ${accessToken}` },
            });
            const data = await res.json();
            if (data.status === 'ok') {
                setMaterializeResult(`Created ${data.lessons_upserted} lessons, ${data.whiteboard_rooms_created} rooms`);
                loadLessons(weekStart);
            } else {
                setMaterializeResult(`Error: ${data.message}`);
            }
        } catch (e: any) {
            setMaterializeResult(`Error: ${e.message}`);
        } finally {
            setMaterializing(false);
        }
    };

    const handleSaveLesson = async (id: string, updates: { notes?: string; status?: string }) => {
        if (!accessToken) return;
        await fetch(`${API_BASE}/timetable/lessons/${id}`, {
            method: 'PATCH',
            headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' },
            body: JSON.stringify(updates),
        });
        loadLessons(weekStart);
    };

    const openAssignDialog = async (lesson: Lesson) => {
        setAssigningLesson(lesson);
        setPlanSearch('');
        setAssignResult(null);
        if (plans.length === 0) {
            try {
                const res = await fetch(`${API_BASE}/lessons/plans`, {
                    headers: { Authorization: `Bearer ${accessToken}` },
                });
                const data = await res.json();
                if (Array.isArray(data)) setPlans(data);
            } catch { /* silently ignore */ }
        }
    };

    const handleAssignPlan = async (planId: string) => {
        if (!assigningLesson) return;
        setAssignSaving(true);
        try {
            const res = await fetch(`${API_BASE}/lessons/plans/${planId}/deliver`, {
                method: 'POST',
                headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' },
                body: JSON.stringify({ taught_lesson_id: assigningLesson.id }),
            });
            const data = await res.json();
            if (data.id) {
                setAssignResult('Plan linked ✓');
                setTimeout(() => { setAssigningLesson(null); setAssignResult(null); }, 1200);
            } else {
                setAssignResult(data.detail || 'Failed to link plan');
            }
        } catch (e: any) {
            setAssignResult(e.message);
        } finally {
            setAssignSaving(false);
        }
    };

    const filteredPlans = plans.filter(p =>
        !planSearch || p.title.toLowerCase().includes(planSearch.toLowerCase())
            || (p.subject || '').toLowerCase().includes(planSearch.toLowerCase())
    );

    const totalLessons = days.reduce((sum, d) => sum + d.lessons.length, 0);

    const weekLabel = days.length > 0
        ? `${formatDate(days[0].date)} – ${formatDate(days[days.length - 1].date)}`
        : '';

    return (
        <Box sx={{ p: 3, maxWidth: 1000, mx: 'auto' }}>
            {/* Header */}
            <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 2 }}>
                <Box>
                    <Typography variant="h5" sx={{ fontWeight: 700 }}>My Lessons</Typography>
                    <Typography variant="caption" sx={{ color: 'text.secondary' }}>
                        {weekLabel} · {totalLessons} lesson{totalLessons !== 1 ? 's' : ''}
                    </Typography>
                </Box>
                <Box sx={{ display: 'flex', gap: 1, alignItems: 'center' }}>
                    <Button
                        size="small"
                        variant="outlined"
                        onClick={handleMaterialize}
                        disabled={materializing}
                        sx={{ whiteSpace: 'nowrap' }}
                    >
                        {materializing ? <CircularProgress size={14} sx={{ mr: 1 }} /> : null}
                        Generate Lessons
                    </Button>
                    <Tooltip title="Go to this week">
                        <IconButton size="small" onClick={goThisWeek}><Today fontSize="small" /></IconButton>
                    </Tooltip>
                    <IconButton size="small" onClick={prevWeek}><ChevronLeft /></IconButton>
                    <IconButton size="small" onClick={nextWeek}><ChevronRight /></IconButton>
                </Box>
            </Box>

            {materializeResult && (
                <Alert
                    severity={materializeResult.startsWith('Error') ? 'error' : 'success'}
                    onClose={() => setMaterializeResult(null)}
                    sx={{ mb: 2 }}
                >
                    {materializeResult}
                </Alert>
            )}

            {error && <Alert severity="error" sx={{ mb: 2 }}>{error}</Alert>}

            {/* Week grid */}
            {loading ? (
                <Box sx={{ display: 'flex', justifyContent: 'center', py: 6 }}>
                    <CircularProgress />
                </Box>
            ) : (
                <Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', gap: 1.5 }}>
                    {days.map(day => (
                        <Box key={day.date}>
                            {/* Day header */}
                            <Box
                                sx={{
                                    p: 1,
                                    mb: 0.75,
                                    borderRadius: 1,
                                    bgcolor: day.is_today ? 'primary.main' : 'action.hover',
                                    color: day.is_today ? 'primary.contrastText' : 'text.primary',
                                    textAlign: 'center',
                                }}
                            >
                                <Typography variant="caption" sx={{ fontWeight: 700, display: 'block' }}>
                                    {day.day_of_week.slice(0, 3)}
                                </Typography>
                                <Typography variant="caption" sx={{ fontSize: '0.7rem', opacity: 0.85 }}>
                                    {formatDate(day.date)}
                                </Typography>
                            </Box>

                            {/* Lesson cards */}
                            {day.lessons.length === 0 ? (
                                <Typography variant="caption" sx={{ color: 'text.disabled', fontSize: '0.7rem', px: 0.5 }}>
                                    No lessons
                                </Typography>
                            ) : (
                                day.lessons.map(lesson => (
                                    <LessonCard
                                        key={lesson.id}
                                        lesson={lesson}
                                        onEdit={setEditingLesson}
                                        onAssignPlan={openAssignDialog}
                                    />
                                ))
                            )}
                        </Box>
                    ))}
                </Box>
            )}

            <LessonEditDialog
                lesson={editingLesson}
                onClose={() => setEditingLesson(null)}
                onSave={handleSaveLesson}
            />

            {/* Assign Plan dialog */}
            <Dialog open={!!assigningLesson} onClose={() => setAssigningLesson(null)} maxWidth="sm" fullWidth>
                <DialogTitle sx={{ pb: 1 }}>
                    <Typography variant="h6">Assign Lesson Plan</Typography>
                    {assigningLesson && (
                        <Typography variant="caption" color="text.secondary">
                            {assigningLesson.class_name || assigningLesson.period_code} · {assigningLesson.date}
                        </Typography>
                    )}
                </DialogTitle>
                <DialogContent sx={{ pt: 1 }}>
                    {assignResult ? (
                        <Alert severity={assignResult.includes('✓') ? 'success' : 'error'} sx={{ mb: 1 }}>
                            {assignResult}
                        </Alert>
                    ) : null}
                    <TextField
                        size="small"
                        fullWidth
                        placeholder="Search plans…"
                        value={planSearch}
                        onChange={e => setPlanSearch(e.target.value)}
                        InputProps={{
                            startAdornment: <InputAdornment position="start"><Search fontSize="small" /></InputAdornment>,
                        }}
                        sx={{ mb: 1 }}
                    />
                    {plans.length === 0 ? (
                        <Typography variant="body2" color="text.secondary" sx={{ py: 2, textAlign: 'center' }}>
                            No lesson plans yet.{' '}
                            <Button size="small" endIcon={<OpenInNew fontSize="small" />}
                                onClick={() => { setAssigningLesson(null); navigate('/lesson-plans'); }}>
                                Create one
                            </Button>
                        </Typography>
                    ) : (
                        <List dense disablePadding sx={{ maxHeight: 300, overflow: 'auto' }}>
                            {filteredPlans.map(p => (
                                <ListItemButton
                                    key={p.id}
                                    onClick={() => handleAssignPlan(p.id)}
                                    disabled={assignSaving}
                                    sx={{ borderRadius: 1, mb: 0.25 }}
                                >
                                    <ListItemText
                                        primary={p.title}
                                        secondary={p.subject || undefined}
                                        primaryTypographyProps={{ variant: 'body2' }}
                                        secondaryTypographyProps={{ variant: 'caption' }}
                                    />
                                    {assignSaving && <CircularProgress size={16} sx={{ ml: 1 }} />}
                                </ListItemButton>
                            ))}
                        </List>
                    )}
                </DialogContent>
                <DialogActions sx={{ px: 3, pb: 2 }}>
                    <Button onClick={() => setAssigningLesson(null)}>Close</Button>
                    <Button size="small" endIcon={<OpenInNew fontSize="small" />}
                        onClick={() => { setAssigningLesson(null); navigate('/lesson-plans'); }}>
                        Manage Plans
                    </Button>
                </DialogActions>
            </Dialog>
        </Box>
    );
};

export default TaughtLessonsPage;
