import React, { useState, useEffect, useMemo, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import {
    Box, Typography, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow,
    CircularProgress, Alert, Button, TextField, TableSortLabel, Select, MenuItem, FormControl,
    InputLabel, Chip, OutlinedInput, IconButton
} from '@mui/material';
import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline';
import DeleteIcon from '@mui/icons-material/Delete';
import { getMeetings, updateMeeting, deleteMeeting, createMeeting } from '../services/api';
import { useAuth } from '../contexts/AuthContext';
import NewMeetingDialog from '../components/NewMeetingDialog';

// Helper function for sorting
function descendingComparator(a, b, orderBy) {
    if (b[orderBy] < a[orderBy]) return -1;
    if (b[orderBy] > a[orderBy]) return 1;
    return 0;
}

function getComparator(order, orderBy) {
    return order === 'desc'
        ? (a, b) => descendingComparator(a, b, orderBy)
        : (a, b) => -descendingComparator(a, b, orderBy);
}

const DashboardPage = () => {
    const navigate = useNavigate();
    const { user } = useAuth();
    const [meetings, setMeetings] = useState([]);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState('');
    const [deletingIds, setDeletingIds] = useState(new Set());
    const [isModalOpen, setIsModalOpen] = useState(false);

    // State for filtering and searching
    const [topicSearch, setTopicSearch] = useState('');
    const [ownerSearch, setOwnerSearch] = useState('');
    const [statusFilter, setStatusFilter] = useState([]);

    // State for sorting
    const [order, setOrder] = useState('asc');
    const [orderBy, setOrderBy] = useState('meeting_date');

    const fetchMeetings = useCallback(async () => {
        try {
            const data = await getMeetings();
            setMeetings(data);
        } catch (err) {
            setError('Could not fetch meetings.');
        } finally {
            setLoading(false);
        }
    }, []);

    useEffect(() => {
        fetchMeetings();
    }, [fetchMeetings]);

    const handleCreateMeeting = async (topic, meetingDate) => {
        try {
            const newMeeting = await createMeeting(topic, new Date(meetingDate).toISOString());
            setIsModalOpen(false);
            navigate(`/meeting/${newMeeting.id}`);
        } catch (err) {
            throw new Error(err.response?.data?.error || "Failed to create meeting.");
        }
    };

    const handleSortRequest = (property) => {
        const isAsc = orderBy === property && order === 'asc';
        setOrder(isAsc ? 'desc' : 'asc');
        setOrderBy(property);
    };

    const handleStatusChange = async (meetingId, newStatus) => {
        try {
            await updateMeeting(meetingId, { status: newStatus });
            fetchMeetings();
        } catch (err) {
            setError(`Failed to update status for meeting ${meetingId}.`);
        }
    };

    const handleDelete = async (meetingId) => {
        if (window.confirm('Are you sure you want to delete this meeting?')) {
            setDeletingIds(prev => new Set(prev).add(meetingId));
            try {
                await deleteMeeting(meetingId);
                fetchMeetings();
            } catch (err) {
                setError(`Failed to delete meeting ${meetingId}.`);
            } finally {
                setDeletingIds(prev => {
                    const newSet = new Set(prev);
                    newSet.delete(meetingId);
                    return newSet;
                });
            }
        }
    };

    const uniqueStatuses = useMemo(() => {
        const statuses = new Set(meetings.map(m => m.status));
        return Array.from(statuses);
    }, [meetings]);

    const filteredAndSortedMeetings = useMemo(() => {
        let filtered = meetings.filter(meeting => {
            const topicMatch = meeting.topic.toLowerCase().includes(topicSearch.toLowerCase());
            const ownerMatch = meeting.owner_name ? meeting.owner_name.toLowerCase().includes(ownerSearch.toLowerCase()) : ownerSearch === '';
            const statusMatch = statusFilter.length === 0 || statusFilter.includes(meeting.status);
            return topicMatch && ownerMatch && statusMatch;
        });

        return filtered.sort(getComparator(order, orderBy));
    }, [meetings, topicSearch, ownerSearch, statusFilter, order, orderBy]);

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

    const headCells = [
        { id: 'topic', label: 'Topic' },
        { id: 'owner_name', label: 'Owner' },
        { id: 'meeting_date', label: 'Meeting Date' },
        { id: 'status', label: 'Status' },
        { id: 'action_item_count', label: 'Action Items' },
        { id: 'created_at', label: 'Created At' },
    ];

    const statusColorMap = {
        'Completed': 'success',
        'In Progress': 'info',
        'To Do': 'warning',
        'Failed': 'error',
    };
    
    const allPossibleStatuses = ['To Do', 'In Progress', 'Completed', 'Failed'];

    return (
        <Box>
            <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
                <Typography variant="h4" gutterBottom>Dashboard</Typography>
                <Button variant="contained" startIcon={<AddCircleOutlineIcon />} onClick={() => setIsModalOpen(true)}>
                    New Meeting
                </Button>
            </Box>

            <NewMeetingDialog
                open={isModalOpen}
                onClose={() => setIsModalOpen(false)}
                onCreate={handleCreateMeeting}
            />

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

            <Paper sx={{ p: 2, mb: 2 }}>
                <Box sx={{ display: 'flex', gap: 2, flexDirection: { xs: 'column', md: 'row' } }}>
                    <TextField
                        label="Search by Topic"
                        variant="outlined"
                        value={topicSearch}
                        onChange={(e) => setTopicSearch(e.target.value)}
                        sx={{ flex: '1 1 40%' }}
                    />
                    <TextField
                        label="Search by Owner"
                        variant="outlined"
                        value={ownerSearch}
                        onChange={(e) => setOwnerSearch(e.target.value)}
                        sx={{ flex: '1 1 30%' }}
                    />
                    <FormControl sx={{ flex: '1 1 30%' }}>
                        <InputLabel>Filter by Status</InputLabel>
                        <Select
                            multiple
                            value={statusFilter}
                            onChange={(e) => setStatusFilter(e.target.value)}
                            input={<OutlinedInput label="Filter by Status" />}
                            renderValue={(selected) => (
                                <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
                                    {selected.map((value) => <Chip key={value} label={value} />)}
                                </Box>
                            )}
                        >
                            {uniqueStatuses.map((status) => (
                                <MenuItem key={status} value={status}>{status}</MenuItem>
                            ))}
                        </Select>
                    </FormControl>
                </Box>
            </Paper>

            <TableContainer component={Paper}>
                <Table>
                    <TableHead>
                        <TableRow>
                            {headCells.map((headCell) => (
                                <TableCell key={headCell.id} sortDirection={orderBy === headCell.id ? order : false}>
                                    <TableSortLabel
                                        active={orderBy === headCell.id}
                                        direction={orderBy === headCell.id ? order : 'asc'}
                                        onClick={() => handleSortRequest(headCell.id)}
                                    >
                                        {headCell.label}
                                    </TableSortLabel>
                                </TableCell>
                            ))}
                            <TableCell align="center">Actions</TableCell>
                        </TableRow>
                    </TableHead>
                    <TableBody>
                        {filteredAndSortedMeetings.map((meeting) => {
                            const isOwnerOrAdmin = user && (user.role === 'admin' || String(user.id) === String(meeting.created_by_id));
                            const isDeleting = deletingIds.has(meeting.id);
                            
                            let taipeiTime = 'N/A';
                            if (meeting.created_at) {
                                taipeiTime = new Date(meeting.created_at).toLocaleString('zh-TW', {
                                    timeZone: 'Asia/Taipei',
                                    year: 'numeric',
                                    month: '2-digit',
                                    day: '2-digit',
                                    hour: '2-digit',
                                    minute: '2-digit',
                                    second: '2-digit',
                                    hour12: false
                                });
                            }

                            return (
                                <TableRow key={meeting.id} hover>
                                    <TableCell>{meeting.topic}</TableCell>
                                    <TableCell>{meeting.owner_name || 'N/A'}</TableCell>
                                    <TableCell>{meeting.meeting_date ? new Date(meeting.meeting_date).toLocaleDateString() : 'N/A'}</TableCell>
                                    <TableCell>
                                        <FormControl size="small" sx={{ minWidth: 120 }}>
                                            <Select
                                                value={meeting.status}
                                                onChange={(e) => handleStatusChange(meeting.id, e.target.value)}
                                                readOnly={!isOwnerOrAdmin}
                                                IconComponent={!isOwnerOrAdmin ? () => null : undefined}
                                                renderValue={(selected) => (
                                                    <Chip
                                                        label={selected}
                                                        color={statusColorMap[selected] || 'default'}
                                                        size="small"
                                                    />
                                                )}
                                                sx={{ 
                                                    '& .MuiOutlinedInput-notchedOutline': { border: 'none' },
                                                    backgroundColor: 'transparent', 
                                                }}
                                            >
                                                {allPossibleStatuses.map(status => (
                                                    <MenuItem key={status} value={status}>
                                                        {status}
                                                    </MenuItem>
                                                ))}
                                            </Select>
                                        </FormControl>
                                    </TableCell>
                                    <TableCell>{meeting.action_item_count}</TableCell>
                                    <TableCell>{taipeiTime}</TableCell>
                                    <TableCell align="center">
                                        <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
                                            <Button size="small" onClick={() => navigate(`/meeting/${meeting.id}`)}>
                                                View Details
                                            </Button>
                                            {isOwnerOrAdmin ? (
                                                <IconButton size="small" onClick={() => handleDelete(meeting.id)} color="error" disabled={isDeleting}>
                                                    {isDeleting ? <CircularProgress size={20} /> : <DeleteIcon />}
                                                </IconButton>
                                            ) : (
                                                // Invisible placeholder to maintain alignment
                                                <Box sx={{ width: 34, height: 34 }} />
                                            )}
                                        </Box>
                                    </TableCell>
                                </TableRow>
                            );
                        })}
                    </TableBody>
                </Table>
            </TableContainer>
        </Box>
    );
};

export default DashboardPage;
