import { CloseOutlined } from '@ant-design/icons';
import {
    Button,
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    FormControl,
    IconButton,
    OutlinedInput,
    Stack,
    Typography,
    Chip,
    Box,
    FormHelperText,
    InputAdornment,
    Autocomplete,
    Avatar
} from '@mui/material';
import React, { useState, useEffect, useCallback } from 'react';
import DatePicker from 'react-datepicker';
import Image from 'next/image';
import { getAgencyList } from 'services/authService';
import { errorSnackbar } from 'api/snackbar';

interface FilterDialogProps {
    open: boolean;
    onClose: () => void;
    initialFilters: {
        agencies: any[];
        startDate: Date | null;
        endDate: Date | null;
        status: number[];
    };
    onApply: (filters: { agencies: any[]; startDate: Date | null; endDate: Date | null; status: number[] }) => void;
    hasActiveFilters: boolean;
}

const statusOptions = [
    { value: 1, label: 'Under-Review' },
    { value: 2, label: 'Accepted' },
    { value: 3, label: 'Live' },
    { value: 4, label: 'Rejected' },
    { value: 5, label: 'Expired' },
    { value: 6, label: 'Paused' },
    { value: 7, label: 'Draft' }
];

interface Agency {
    id: number;
    agency_name: string;
    agency_logo: string;
    role: number;
    location_name?: string;
    profile_picture?: string;
}

const AdvertisementFilterDialog: React.FC<FilterDialogProps> = ({ open, onClose, initialFilters, onApply, hasActiveFilters }) => {
    const [selectedAgencies, setSelectedAgencies] = useState<any[]>([]);
    const [agencies, setAgencies] = useState<Agency[]>([]);
    const [agencyLoading, setAgencyLoading] = useState(false);

    const [startDate, setStartDate] = useState<Date | null>(null);
    const [endDate, setEndDate] = useState<Date | null>(null);
    const [dateError, setDateError] = useState<string>('');

    const [selectedStatuses, setSelectedStatuses] = useState<number[]>([]);

    const today = new Date();
    today.setHours(0, 0, 0, 0);

    const localHasFilters = selectedAgencies.length > 0 || startDate !== null || endDate !== null || selectedStatuses.length > 0;

    const fetchAgencies = useCallback(async (search: string, page = 1) => {
        try {
            setAgencyLoading(true);
            const response = await getAgencyList({
                type: '2',
                page: 1,
                limit: 1000,
                search
            });

            if (response.success) {
                const newAgencies = response.data.data.agencies || [];
                setAgencies((prev) => (page === 1 ? newAgencies : [...prev, ...newAgencies]));
            } else {
                errorSnackbar(response.message);
            }
        } catch (error) {
            errorSnackbar('Failed to fetch agencies');
        } finally {
            setAgencyLoading(false);
        }
    }, []);

    useEffect(() => {
        if (open && agencies.length === 0) {
            fetchAgencies('');
        }
    }, [open, fetchAgencies, agencies.length]);

    const validateDates = (start: Date | null, end: Date | null): string => {
        if (start && !end && endDate) {
            return 'End date is required when start date is selected';
        }
        if (!start && end && startDate) {
            return 'Start date is required when end date is selected';
        }
        if (start && end) {
            if (end < start) {
                return 'End date cannot be before start date';
            }
        }
        return '';
    };

    const handleStartDateChange = (date: Date | null) => {
        setStartDate(date);
        const error = validateDates(date, endDate);
        setDateError(error);
    };

    const handleEndDateChange = (date: Date | null) => {
        setEndDate(date);
        const error = validateDates(startDate, date);
        setDateError(error);
    };

    useEffect(() => {
        if (open) {
            setSelectedAgencies(initialFilters.agencies || []);
            setSelectedStatuses(initialFilters.status || []);
            setStartDate(initialFilters.startDate);
            setEndDate(initialFilters.endDate);
            setDateError('');
        }
    }, [open, initialFilters]);

    const handleRemoveAgency = (id: number) => {
        setSelectedAgencies((prev) => prev.filter((agency: any) => agency.id !== id));
    };

    const handleRemoveStatus = (event: React.MouseEvent, statusToRemove: number) => {
        event.stopPropagation();
        setSelectedStatuses((prev) => prev.filter((s) => s !== statusToRemove));
    };

    const handleApply = () => {
        const error = validateDates(startDate, endDate);
        if (error) {
            setDateError(error);
            return;
        }

        const filters = {
            agencies: selectedAgencies,
            startDate,
            endDate,
            status: selectedStatuses
        };
        onApply(filters);
        onClose();
    };

    const handleClearAll = () => {
        setSelectedAgencies([]);
        setStartDate(null);
        setEndDate(null);
        setSelectedStatuses([]);
        setDateError('');
    };

    const hasChanges =
        JSON.stringify(selectedAgencies.map((a) => a.id).sort()) !== JSON.stringify((initialFilters.agencies || []).map((a) => a.id).sort()) ||
        JSON.stringify([...selectedStatuses].sort()) !== JSON.stringify([...(initialFilters.status || [])].sort()) ||
        (startDate?.toISOString() || null) !== (initialFilters.startDate ? initialFilters.startDate.toISOString() : null) ||
        (endDate?.toISOString() || null) !== (initialFilters.endDate ? initialFilters.endDate.toISOString() : null);

    const isApplyDisabled = dateError !== '' || ((startDate || endDate) && (!startDate || !endDate)) || !hasChanges;

    return (
        <Dialog
            open={open}
            onClose={(_, reason) => {
                if (reason !== 'backdropClick') {
                    onClose();
                }
            }}
            fullWidth
            maxWidth="sm"
            PaperProps={{
                sx: {
                    width: 471,
                    borderRadius: 2
                }
            }}
        >
            <DialogTitle
                sx={{
                    boxShadow: '0px -1px 0px 0px #F0F0F0 inset',
                    display: 'flex',
                    justifyContent: 'space-between',
                    alignItems: 'center'
                }}
            >
                <Typography fontSize={16} fontWeight={500}>
                    Sort & Filter Advertisements
                </Typography>
                <IconButton aria-label="close" onClick={onClose} sx={{ color: (theme) => theme.palette.grey[500] }}>
                    <CloseOutlined />
                </IconButton>
            </DialogTitle>

            <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: '15px', padding: '20px 16px' }}>
                <FormControl sx={{ width: '100%', pt: '16px' }}>
                    <Typography fontSize={14} sx={{ mb: 1 }}>
                        Select Organisations
                    </Typography>
                    <Autocomplete
                        ListboxProps={{
                            style: { maxHeight: '200px', overflowY: 'auto' }
                        }}
                        loading={agencyLoading}
                        multiple
                        disableCloseOnSelect
                        options={agencies}
                        value={selectedAgencies}
                        getOptionLabel={(option) => option.agency_name || option.location_name || ''}
                        isOptionEqualToValue={(option, value) => option.id === value.id}
                        onChange={(event, newValue) => setSelectedAgencies(newValue)}
                        renderOption={(props, option) => {
                            return (
                                <Box component="li" {...props}>
                                    <Stack direction="row" alignItems="center" spacing={1}>
                                        {option.role === 1 ? (
                                            <>
                                                <Avatar src={option.agency_logo} alt={option.agency_name} sx={{ width: 24, height: 24 }} />
                                                <Typography>{option.agency_name}</Typography>
                                            </>
                                        ) : (
                                            <>
                                                <Avatar
                                                    src={option.profile_picture}
                                                    alt={`${option.location_name}`}
                                                    sx={{ width: 24, height: 24 }}
                                                />
                                                <Typography>
                                                    {option.location_name ? `${option.location_name} (${option.agency_name})` : option.agency_name}
                                                </Typography>
                                            </>
                                        )}
                                    </Stack>
                                </Box>
                            );
                        }}
                        renderTags={(value, getTagProps) =>
                            value.map((option, index) => (
                                <Chip
                                    {...getTagProps({ index })}
                                    key={option.id}
                                    label={option.role === 1 ? option.agency_name : option.location_name ? `${option.location_name} (${option.agency_name})` : option.agency_name}
                                    size="small"
                                    onDelete={() => handleRemoveAgency(option.id)}
                                    deleteIcon={<CloseOutlined />}
                                />
                            ))
                        }
                        renderInput={(params) => (
                            <OutlinedInput
                                {...params.InputProps}
                                fullWidth
                                inputProps={params.inputProps}
                                placeholder={selectedAgencies.length === 0 ? 'Select Organisations (Multiple)' : ''}
                                sx={{ border: '1px solid #D9D9D9' }}
                                endAdornment={params.InputProps.endAdornment}
                            />
                        )}
                    />
                </FormControl>

                <Stack direction="row" spacing={2} sx={{ width: '100%' }}>
                    <FormControl sx={{ flex: 1 }} error={!!dateError}>
                        <Typography fontSize={14} sx={{ mb: 1 }}>
                            Start Date
                        </Typography>
                        <DatePicker
                            selected={startDate}
                            onChange={(date) => {
                                if (date) {
                                    const localDate = new Date(date.getTime() - date.getTimezoneOffset() * 60000);
                                    handleStartDateChange(localDate);
                                } else {
                                    handleStartDateChange(null);
                                }
                            }}
                            dateFormat="dd-MMM-yyyy"
                            maxDate={today}
                            withPortal
                            showMonthDropdown
                            showYearDropdown
                            dropdownMode="select"
                            scrollableYearDropdown
                            yearDropdownItemNumber={100}
                            placeholderText="Select Start Date"
                            popperPlacement="bottom-start"
                            customInput={
                                <OutlinedInput
                                    value={
                                        startDate
                                            ? startDate.toLocaleDateString('en-GB', {
                                                day: '2-digit',
                                                month: 'short',
                                                year: 'numeric'
                                            })
                                            : ''
                                    }
                                    fullWidth
                                    readOnly
                                    placeholder="Select Start Date"
                                    error={!!dateError}
                                    endAdornment={
                                        <InputAdornment position="end">
                                            <IconButton edge="end">
                                                <Image src="/assets/images/icons/calendar.svg" alt="calendar" width={24} height={24} />
                                            </IconButton>
                                        </InputAdornment>
                                    }
                                    sx={{
                                        position: 'relative',
                                        border: '1px solid #D9D9D9',
                                        cursor: 'pointer',
                                        '& input': { cursor: 'pointer' }
                                    }}
                                />
                            }
                        />
                    </FormControl>

                    <FormControl sx={{ flex: 1 }} error={!!dateError}>
                        <Typography fontSize={14} sx={{ mb: 1 }}>
                            End Date
                        </Typography>
                        <DatePicker
                            selected={endDate}
                            onChange={(date) => {
                                if (date) {
                                    const localDate = new Date(date.getTime() - date.getTimezoneOffset() * 60000);
                                    handleEndDateChange(localDate);
                                } else {
                                    handleEndDateChange(null);
                                }
                            }}
                            dateFormat="dd-MMM-yyyy"
                            minDate={startDate || undefined}
                            withPortal
                            showMonthDropdown
                            showYearDropdown
                            dropdownMode="select"
                            scrollableYearDropdown
                            yearDropdownItemNumber={100}
                            placeholderText="Select End Date"
                            popperPlacement="bottom-start"
                            customInput={
                                <OutlinedInput
                                    value={
                                        endDate
                                            ? endDate.toLocaleDateString('en-GB', {
                                                day: '2-digit',
                                                month: 'short',
                                                year: 'numeric',
                                                timeZone: 'UTC'
                                            })
                                            : ''
                                    }
                                    fullWidth
                                    readOnly
                                    placeholder="Select End Date"
                                    error={!!dateError}
                                    endAdornment={
                                        <InputAdornment position="end">
                                            <IconButton edge="end">
                                                <Image src="/assets/images/icons/calendar.svg" alt="calendar" width={24} height={24} />
                                            </IconButton>
                                        </InputAdornment>
                                    }
                                    sx={{
                                        position: 'relative',
                                        border: '1px solid #D9D9D9',
                                        cursor: 'pointer',
                                        '& input': { cursor: 'pointer' }
                                    }}
                                />
                            }
                        />
                    </FormControl>
                </Stack>

                {dateError && (
                    <FormHelperText error sx={{ mt: -1 }}>
                        {dateError}
                    </FormHelperText>
                )}

                <FormControl sx={{ width: '100%' }}>
                    <Typography fontSize={14} sx={{ mb: 1 }}>
                        Filter By Status
                    </Typography>
                    <Autocomplete
                        ListboxProps={{
                            style: { maxHeight: '200px', overflowY: 'auto' }
                        }}
                        multiple
                        disableCloseOnSelect
                        options={statusOptions}
                        value={statusOptions.filter((option) => selectedStatuses.includes(option.value))}
                        getOptionLabel={(option) => option.label}
                        onChange={(event, newValue) => {
                            const selectedValues = newValue.map((option) => option.value);
                            setSelectedStatuses(selectedValues);
                        }}
                        renderOption={(props, option) => (
                            <Box component="li" {...props}>
                                <Typography>{option.label}</Typography>
                            </Box>
                        )}
                        renderTags={(value, getTagProps) =>
                            value.map((option, index) => (
                                <Chip
                                    {...getTagProps({ index })}
                                    key={option.value}
                                    label={option.label}
                                    size="small"
                                    onDelete={(e) => handleRemoveStatus(e, option.value)}
                                    deleteIcon={<CloseOutlined />}
                                />
                            ))
                        }
                        renderInput={(params) => (
                            <OutlinedInput
                                {...params.InputProps}
                                fullWidth
                                inputProps={params.inputProps}
                                placeholder={selectedStatuses.length === 0 ? 'Select Status (Multiple)' : ''}
                                sx={{ border: '1px solid #D9D9D9' }}
                                endAdornment={params.InputProps.endAdornment}
                            />
                        )}
                    />
                </FormControl>
            </DialogContent>

            <DialogActions
                sx={{
                    boxShadow: '0px 1px 0px 0px #F0F0F0 inset',
                    padding: '20px',
                    justifyContent: 'space-between'
                }}
            >
                <Button variant="text" sx={{ color: 'black' }} onClick={handleClearAll} disabled={!localHasFilters}>
                    Clear All
                </Button>
                <Stack direction="row" gap="20px">
                    <Button sx={{ color: 'error.main' }} onClick={onClose}>
                        Cancel
                    </Button>
                    <Button sx={{ fontSize: '16px' }} color="primary" variant="contained" onClick={handleApply} disabled={isApplyDisabled}>
                        Apply
                    </Button>
                </Stack>
            </DialogActions>
        </Dialog>
    );
};

export default AdvertisementFilterDialog;
