import React, { useState, useEffect } from 'react';
import {
  Box,
  Card,
  CardContent,
  Typography,
  Grid,
  Divider,
  Chip,
  Stack,
  Pagination,
  CircularProgress,
  Select,
  MenuItem,
  FormControl,
  InputLabel,
  TextField,
  Button,
  IconButton,
  SelectChangeEvent,
  Alert,
} from '@mui/material';
import FilterListIcon from '@mui/icons-material/FilterList';
import VisibilityIcon from '@mui/icons-material/Visibility';
import { subYears, getYear } from 'date-fns';
import { Leave, LeaveStatus } from '../../types/Leave';
import LeaveCard from './LeaveCard';
import LeaveDetail from './LeaveDetail';
import LeaveStatusUpdate from './LeaveStatusUpdate';

// Extend the Leave type to include additional properties needed
interface ExtendedLeave extends Leave {
  employeeName?: string;
  leaveMasterId?: number;
  appliedOn?: string; // To match with imported type
}

export interface LeaveListProps {
  leaves: ExtendedLeave[];
  isLoading?: boolean;
  error?: string | null;
  onStatusUpdate?: (leaveId: string, status: LeaveStatus, comment?: string) => Promise<void>;
  canApprove?: boolean;
  title?: string;
  showFilters?: boolean;
  leaveTypes?: string[];
  employees?: { id: string; firstName: string; lastName: string }[];
  getLeaveTypeName?: (id?: number) => string;
}

const LeaveList: React.FC<LeaveListProps> = ({
  leaves,
  isLoading = false,
  error = null,
  onStatusUpdate,
  canApprove = false,
  title = "Leave Requests",
  showFilters = true,
  leaveTypes = [],
  employees = [],
  getLeaveTypeName,
}) => {
  const [filteredLeaves, setFilteredLeaves] = useState<ExtendedLeave[]>(leaves);
  const [statusFilter, setStatusFilter] = useState<string>("All");
  const [typeFilter, setTypeFilter] = useState<string>("All");
  const [employeeFilter, setEmployeeFilter] = useState<string>("All");
  const [yearFilter, setYearFilter] = useState<number>(getYear(new Date()));
  const [searchTerm, setSearchTerm] = useState<string>("");
  const [displayFilters, setDisplayFilters] = useState<boolean>(false);
  const [page, setPage] = useState<number>(1);
  const [selectedLeave, setSelectedLeave] = useState<ExtendedLeave | null>(null);
  const [showDetailDialog, setShowDetailDialog] = useState<boolean>(false);
  const [showApproveDialog, setShowApproveDialog] = useState<boolean>(false);
  const [showRejectDialog, setShowRejectDialog] = useState<boolean>(false);
  const [isSubmitting, setIsSubmitting] = useState<boolean>(false);

  const itemsPerPage = 6;
  const years = Array.from({ length: 5 }, (_, i) => getYear(subYears(new Date(), i)));

  // Apply filters whenever filter values change
  useEffect(() => {
    if (!leaves) return;
    
    let filtered = [...leaves];
    
    // Filter by year
    filtered = filtered.filter(leave => {
      const leaveYear = getYear(new Date(leave.startDate));
      return leaveYear === yearFilter;
    });
    
    // Filter by status if not "All"
    if (statusFilter !== "All") {
      filtered = filtered.filter(leave => leave.status === statusFilter);
    }
    
    // Filter by type if not "All"
    if (typeFilter !== "All") {
      filtered = filtered.filter(leave => {
        if (leave.type) return leave.type === typeFilter;
        return false;
      });
    }
    
    // Filter by employee if not "All"
    if (employeeFilter !== "All") {
      filtered = filtered.filter(leave => leave.employeeId === employeeFilter);
    }
    
    // Filter by search term
    if (searchTerm) {
      filtered = filtered.filter(leave => 
        leave.reason.toLowerCase().includes(searchTerm.toLowerCase()) ||
        leave.employeeName?.toLowerCase().includes(searchTerm.toLowerCase())
      );
    }
    
    setFilteredLeaves(filtered);
    setPage(1); // Reset to first page whenever filters change
  }, [leaves, statusFilter, typeFilter, employeeFilter, yearFilter, searchTerm]);

  const handlePageChange = (event: React.ChangeEvent<unknown>, value: number) => {
    setPage(value);
  };

  const handleStatusFilterChange = (event: SelectChangeEvent) => {
    setStatusFilter(event.target.value);
  };

  const handleTypeFilterChange = (event: SelectChangeEvent) => {
    setTypeFilter(event.target.value);
  };

  const handleEmployeeFilterChange = (event: SelectChangeEvent) => {
    setEmployeeFilter(event.target.value);
  };

  const handleYearFilterChange = (event: SelectChangeEvent) => {
    setYearFilter(Number(event.target.value));
  };

  const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setSearchTerm(event.target.value);
  };

  const handleViewLeave = (leave: ExtendedLeave) => {
    setSelectedLeave(leave);
    setShowDetailDialog(true);
  };

  const handleApproveLeave = (leave: ExtendedLeave) => {
    setSelectedLeave(leave);
    setShowApproveDialog(true);
  };

  const handleRejectLeave = (leave: ExtendedLeave) => {
    setSelectedLeave(leave);
    setShowRejectDialog(true);
  };

  const handleSubmitStatusUpdate = async (status: LeaveStatus, comment?: string) => {
    if (!selectedLeave || !onStatusUpdate) return;
    
    setIsSubmitting(true);
    try {
      await onStatusUpdate(selectedLeave.id, status, comment);
      // Close dialogs
      setShowApproveDialog(false);
      setShowRejectDialog(false);
      setSelectedLeave(null);
    } catch (error) {
      console.error("Error in status update:", error);
    } finally {
      setIsSubmitting(false);
    }
  };

  const paginatedLeaves = filteredLeaves.slice(
    (page - 1) * itemsPerPage,
    page * itemsPerPage
  );

  // Helper function to get leave type name if getLeaveTypeName is not provided
  const getLeaveTypeDisplay = (leave: ExtendedLeave): string => {
    if (getLeaveTypeName && leave.leaveMasterId) {
      return getLeaveTypeName(leave.leaveMasterId);
    }
    return leave.type;
  };

  return (
    <Card>
      <CardContent>
        <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
          <Typography variant="h6" component="h2">
            {title} {filteredLeaves.length > 0 && `(${filteredLeaves.length})`}
          </Typography>
          {showFilters && (
            <IconButton 
              onClick={() => setDisplayFilters(!displayFilters)} 
              color={displayFilters ? "primary" : "default"}
            >
              <FilterListIcon />
            </IconButton>
          )}
        </Box>

        {displayFilters && (
          <Box sx={{ mb: 2 }}>
            <Grid container spacing={2}>
              <Grid item xs={12} sm={6} md={2}>
                <FormControl fullWidth size="small">
                  <InputLabel>Status</InputLabel>
                  <Select
                    value={statusFilter}
                    label="Status"
                    onChange={handleStatusFilterChange}
                  >
                    <MenuItem value="All">All</MenuItem>
                    <MenuItem value="Pending">Pending</MenuItem>
                    <MenuItem value="Approved">Approved</MenuItem>
                    <MenuItem value="Rejected">Rejected</MenuItem>
                    <MenuItem value="Cancelled">Cancelled</MenuItem>
                  </Select>
                </FormControl>
              </Grid>

              <Grid item xs={12} sm={6} md={2}>
                <FormControl fullWidth size="small">
                  <InputLabel>Year</InputLabel>
                  <Select
                    value={yearFilter.toString()}
                    label="Year"
                    onChange={handleYearFilterChange}
                  >
                    {years.map(year => (
                      <MenuItem key={year} value={year}>{year}</MenuItem>
                    ))}
                  </Select>
                </FormControl>
              </Grid>

              {leaveTypes.length > 0 && (
                <Grid item xs={12} sm={6} md={2}>
                  <FormControl fullWidth size="small">
                    <InputLabel>Type</InputLabel>
                    <Select
                      value={typeFilter}
                      label="Type"
                      onChange={handleTypeFilterChange}
                    >
                      <MenuItem value="All">All</MenuItem>
                      {leaveTypes.map(type => (
                        <MenuItem key={type} value={type}>{type}</MenuItem>
                      ))}
                    </Select>
                  </FormControl>
                </Grid>
              )}

              {employees.length > 0 && (
                <Grid item xs={12} sm={6} md={2}>
                  <FormControl fullWidth size="small">
                    <InputLabel>Employee</InputLabel>
                    <Select
                      value={employeeFilter}
                      label="Employee"
                      onChange={handleEmployeeFilterChange}
                    >
                      <MenuItem value="All">All</MenuItem>
                      {employees.map(emp => (
                        <MenuItem key={emp.id} value={emp.id}>
                          {`${emp.firstName} ${emp.lastName}`.trim()}
                        </MenuItem>
                      ))}
                    </Select>
                  </FormControl>
                </Grid>
              )}

              <Grid item xs={12} sm={6} md={4}>
                <TextField
                  fullWidth
                  size="small"
                  label="Search"
                  variant="outlined"
                  value={searchTerm}
                  onChange={handleSearchChange}
                  placeholder="Search by reason or employee name"
                />
              </Grid>
            </Grid>
          </Box>
        )}

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

        {isLoading ? (
          <Box sx={{ display: 'flex', justifyContent: 'center', p: 4 }}>
            <CircularProgress />
          </Box>
        ) : filteredLeaves.length === 0 ? (
          <Box sx={{ p: 4, textAlign: 'center' }}>
            <Typography variant="body1" color="textSecondary">
              No leave requests found
            </Typography>
          </Box>
        ) : (
          <>
            <Grid container spacing={2}>
              {paginatedLeaves.map(leave => (
                <Grid item xs={12} sm={6} md={4} key={leave.id}>
                  <LeaveCard 
                    leave={leave} 
                    employeeName={leave.employeeName || 'Unknown'}
                    leaveType={getLeaveTypeDisplay(leave)}
                    onView={() => handleViewLeave(leave)}
                    onApprove={canApprove && leave.status === 'Pending' ? () => handleApproveLeave(leave) : undefined}
                    onReject={canApprove && leave.status === 'Pending' ? () => handleRejectLeave(leave) : undefined}
                  />
                </Grid>
              ))}
            </Grid>

            <Box sx={{ display: 'flex', justifyContent: 'center', mt: 3 }}>
              <Pagination
                count={Math.ceil(filteredLeaves.length / itemsPerPage)}
                page={page}
                onChange={handlePageChange}
                color="primary"
              />
            </Box>
          </>
        )}
      </CardContent>

      {selectedLeave && (
        <>
          <LeaveDetail 
            open={showDetailDialog}
            leave={selectedLeave}
            onClose={() => setShowDetailDialog(false)}
          />

          {canApprove && (
            <>
              <LeaveStatusUpdate
                open={showApproveDialog}
                leave={selectedLeave}
                onClose={() => setShowApproveDialog(false)}
                onSubmit={(comment) => handleSubmitStatusUpdate("Approved", comment)}
                isSubmitting={isSubmitting}
                title="Approve Leave Request"
                actionLabel="Approve"
              />

              <LeaveStatusUpdate
                open={showRejectDialog}
                leave={selectedLeave}
                onClose={() => setShowRejectDialog(false)}
                onSubmit={(comment) => handleSubmitStatusUpdate("Rejected", comment)}
                isSubmitting={isSubmitting}
                title="Reject Leave Request"
                actionLabel="Reject"
              />
            </>
          )}
        </>
      )}
    </Card>
  );
};

export default LeaveList; 