import React, {useEffect, useState} from "react";
import {
    TableContainer,
    Table,
    TableHead,
    TableSortLabel,
    TableBody,
    TableRow,
    TableCell,
    Paper,
    Box,
    Typography,
    IconButton,
    TextField,
    InputAdornment,
    FormControl,
    Button,
    CircularProgress,
    Autocomplete,
    ThemeProvider,
    Switch,
    Tooltip,
    Alert,
} from "@mui/material";
import {Clear as ClearIcon, ReportProblem, Search as SearchIcon} from "@mui/icons-material";
import CustomDialog from "./CustomDialog";
import QualificationDetails from "./QualificationDetails";
import SelectUnits from "./SelectUnits";
import CustomPagination from "../../Common/CustomPagination";
import getIconComponent from "../../Common/CustomSortIcon";
import theme from "../../Common/Theme";
import CheckIcon from "@mui/icons-material/Check";

type ShowMessage = {
    message: string;
    severity: 'success' | 'error';
};

type Part = {
    id: number;
    name: string;
    reference: string;
}

type qualification = {
    part: Part;
    type: string;
    awardingBody: string;
}

export const Qualification = ({baseUrl, defaultRowPerPageOptions, moduleId, vocabCourse}: {
    baseUrl: string,
    defaultRowPerPageOptions: any,
    moduleId: number,
    vocabCourse: string,
}) => {
    const [search, setSearch] = useState<string>("");
    const [searchInput, setSearchInput] = useState<string>("");
    const [titleType, setTitleType] = useState<string>("");
    const [titleProvider, setTitleProvider] = useState<string>("");
    const [page, setPage] = useState(1);
    const [rowsPerPage, setRowsPerPage] = useState(30);
    const [totalRecords, setTotalRecords] = useState<number>(0);

    const [qualificationId, setQualificationId] = useState<number | null>(null);
    const [trackerId, setTrackerId] = useState<number | null>(null);
    const [qualificationList, setQualificationList] = useState([]);
    const [visibleQualificationList, setVisibleQualificationList] = useState([]);
    const [moduleQualifications, setModuleQualifications] = useState([]);
    const [types, setTypes] = useState([]);
    const [providers, setProviders] = useState([]);
    const [units, setUnits] = useState([]);

    const [openQualificationDialog, setOpenQualificationDialog] = useState(false);
    const [open, setOpen] = useState(false);
    const [openConfirmDialog, setOpenConfirmDialog] = useState(false);
    const [disabledCloseButtons, setDisabledCloseButtons] = useState(false);

    const [loadingQualifications, setLoadingQualifications] = useState<boolean>(false);
    const [loadingTracked, setLoadingTracked] = useState<boolean>(false);

    const [selectedQualification, setSelectedQualification] = useState<number | null>(null);
    const [removeQualificationId, setRemoveQualificationId] = useState<number | null>(null);
    const [sortBy, setSortBy] = useState<string>('type');
    const [sortDirection, setSortDirection] = useState<string>('asc');
    const [selectedUnitIds, setSelectedUnitIds] = useState<number[]>([]);

    const [showMessage, setShowMessage] = useState<ShowMessage>({message: "", severity: 'success'});

    const handleSort = (columnName: string, direction: string) => {
        let adjustSortDirection = 'asc';
        if(columnName === sortBy) {
            adjustSortDirection = direction === "asc" ? "desc" : "asc";
        }
        setSortBy(columnName);
        setSortDirection(adjustSortDirection);
    }

    const handleTrackQualification = (id: number) => {
        setSelectedQualification(id);

        fetch(`${baseUrl}/modules/${moduleId}/track`, {
            method: 'POST',
            headers: {
                'X-Requested-With': 'XMLHttpRequest',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({qualificationId: id}),
        })
            .then((resp) => {
                if (resp?.status === 200 && resp?.redirected) {
                    window.location.reload();
                    return null;
                }

                return resp.json();
            })
            .then((respJSON) => {
                if (respJSON === null) {
                    return;
                }

                if (respJSON?.status == 'success') {
                    loadTrackedQualifications();
                    loadTrackNewQualifications();
                    setSelectedQualification(null);

                    return;
                } else if (respJSON.status == 'error') {
                    console.error(respJSON.message);
                    return;
                }

                setUnits(respJSON);
                setOpen(true);

                console.log(respJSON);
            }).catch((error) => {
            setShowMessage({
                message: 'Failed to track qualification',
                severity: 'error'
            });
            console.log(error);
        });
    }

    const handleQualificationVisibility = (trackerId: number, visible: boolean) => {
        fetch(`${baseUrl}pt/trackers/${trackerId}/visibility`, {
            method: 'POST',
            headers: {
                'X-Requested-With': 'XMLHttpRequest',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({visible: visible})
        })
            .then((resp) => resp.json())
            .then((respJSON) => {
                if (respJSON.status == 'error') {
                    console.error(respJSON.message);
                    return;
                }

                window.location.reload();
            });
    }

    const handleRemoveQualification = () => {
        setDisabledCloseButtons(true);
        fetch(`${baseUrl}modules/${moduleId}/removeQualification`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({trackerId: removeQualificationId})
        })
            .then((resp) => resp.json())
            .then((respJSON) => {
                if (respJSON.status == 'error') {
                    setOpenConfirmDialog(false);
                    setShowMessage({
                        message: respJSON.message,
                        severity: respJSON.status,
                    });
                    setDisabledCloseButtons(false);
                    return;
                }
                setDisabledCloseButtons(false);
                setOpenConfirmDialog(false);
                setRemoveQualificationId(null);
                setDisabledCloseButtons(false);
                window.location.reload();
            });
    }

    const handleUnitSelectChange = (id: number, checked: boolean) => {
        setSelectedUnitIds(prev =>
            checked ? [...prev, id] : prev.filter(unitId => unitId !== id)
        );
    };

    const handleClose = () => {
        setSelectedQualification(null);
        setSelectedUnitIds([]);
        setOpen(false);
        setOpenQualificationDialog(false);
        setOpenConfirmDialog(false);
    };

    const handleConfirm = () => {
        fetch(`${baseUrl}/modules/${moduleId}/trackQualification`, {
            method: 'POST',
            headers: {
                'X-Requested-With': 'XMLHttpRequest',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({qualificationId: selectedQualification, unitIds: selectedUnitIds}),
        })
            .then((resp) => resp.json())
            .then((respJSON) => {
                if (respJSON.status == 'error') {
                    console.error(respJSON.message);
                    return;
                }

                setSelectedQualification(null);
                setOpen(false);
                setSelectedUnitIds([]);
                loadTrackedQualifications();
                loadTrackNewQualifications();
            }).catch((error) => {
            setShowMessage({
                message: 'Failed to track qualification',
                severity: 'error'
            });
            console.log(error);
        });
    };

    const loadTrackNewQualifications = () => {
        setLoadingQualifications(true);
        fetch(baseUrl + 'modules/' + moduleId + '/getUnlinkedAvailable', {
            method: 'GET',
            headers: {
                'X-Requested-With': 'XMLHttpRequest',
                'Content-Type': 'application/json'
            }
        })
            .then((resp) => {
                if (resp?.status === 200 && resp?.redirected) {
                    window.location.reload();
                    return null;
                }

                return resp.json();
            })
            .then((respJSON) => {
                if (respJSON === null) {
                    return;
                }

                if (respJSON?.status === 'error') {
                    console.log(respJSON.message);
                    return;
                }

                setQualificationList(respJSON?.data ?? []);
                setProviders(respJSON?.providers ?? []);
                setTypes(respJSON?.types ?? []);
                setLoadingQualifications(false);
            }).catch((error) => {
            setShowMessage({
                message: 'Failed to load available qualifications',
                severity: 'error'
            });
            console.error(error);
        });
    }

    const loadTrackedQualifications = () => {
        setLoadingTracked(true);

        fetch(baseUrl + 'modules/' + moduleId + '/qualifications', {
            method: 'GET',
            headers: {
                'X-Requested-With': 'XMLHttpRequest',
                'Content-Type': 'application/json'
            }
        })
            .then((resp) => {
                if (resp?.status === 200 && resp?.redirected) {
                    window.location.reload();
                    return null;
                }

                return resp.json();
            })
            .then((respJSON) => {
                if (respJSON === null) {
                    return;
                }

                if (respJSON?.status === 'error') {
                    console.log(respJSON.message);
                    return;
                }

                setModuleQualifications(respJSON);
                setLoadingTracked(false);
                loadTrackNewQualifications();
            }).catch((error) => {
            setShowMessage({
                message: 'Failed to load tracked qualifications',
                severity: 'error'
            });
            console.error(error);
        });
    }

    const getMessageIcon = (severity: 'success' | 'error') => {
        switch (severity) {
            case 'error':
                return <ReportProblem fontSize="inherit"/>

            case 'success':
                return <CheckIcon fontSize="inherit"/>
        }
    };

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

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

    useEffect(() => {
        setVisibleQualificationList([]);
        if (qualificationList.length > 0) {
            setTotalRecords(qualificationList.length);

            let filtered = qualificationList.filter((q: qualification) => {
                const matchesSearch = q.part.name.toLowerCase().includes(search.toLowerCase()) ||
                    q.part.reference.toLowerCase().includes(search.toLowerCase());

                const matchesType = titleType ? q.type === titleType : true;
                const matchesProvider = titleProvider ? q.awardingBody === titleProvider : true;

                return matchesSearch && matchesType && matchesProvider;
            });

            filtered = filtered.sort((a: qualification, b: qualification) => {
                let valA: string = '';
                let valB: string = '';

                switch (sortBy) {
                    case 'name':
                        valA = a.part.name?.toLowerCase() ?? '';
                        valB = b.part.name?.toLowerCase() ?? '';
                        break;
                    case 'reference':
                        valA = a.part.reference?.toLowerCase() ?? '';
                        valB = b.part.reference?.toLowerCase() ?? '';
                        break;
                    case 'type':
                        valA = a.type?.toLowerCase() ?? '';
                        valB = b.type?.toLowerCase() ?? '';
                        break;
                    case 'provider':
                        valA = a.awardingBody?.toLowerCase() ?? '';
                        valB = b.awardingBody?.toLowerCase() ?? '';
                        break;
                    default:
                        break;
                }

                if (valA < valB) return sortDirection === 'asc' ? -1 : 1;
                if (valA > valB) return sortDirection === 'asc' ? 1 : -1;
                return 0;
            });

            const startIdx = (page - 1) * rowsPerPage;
            const paginated = filtered.slice(startIdx, startIdx + rowsPerPage);

            setVisibleQualificationList(paginated ?? []);
        }
    }, [qualificationList, search, titleType, titleProvider, page, rowsPerPage, sortBy, sortDirection]);

    return (
        <ThemeProvider theme={theme}>

            {showMessage && showMessage.message && (
                <Box sx={{textAlign: 'center', mb: 1}}>
                    <Alert
                        icon={getMessageIcon(showMessage.severity)}
                        variant="filled"
                        severity={showMessage.severity}
                        sx={{
                            display: 'inline-flex',  // fits content only
                            alignItems: 'center',    // vertically centers icon + text
                            px: 2,                   // padding X if you want more space
                            py: 1,                   // padding Y
                        }}
                    >
                        {showMessage.message}
                    </Alert>
                </Box>
            )}

            <Box sx={{p: 3, boxShadow: 3, borderRadius: 2}}>
                <Typography variant="h2" gutterBottom sx={{
                    'font-size': '1.5rem',
                    'text-transform': 'math-auto !important'
                }}>
                    Tracked Qualifications
                </Typography>
                <form>
                    <TableContainer component={Paper} sx={{mb: 2, maxHeight: 300, overflow: "auto"}}>
                        <Table stickyHeader>
                            <TableHead>
                                <TableRow>
                                    <TableCell>Qualification</TableCell>
                                    <TableCell>View</TableCell>
                                    <TableCell>Visibility</TableCell>
                                    <TableCell>Remove</TableCell>
                                </TableRow>
                            </TableHead>
                            <TableBody>
                                {loadingTracked ? (
                                    <TableRow>
                                        <TableCell colSpan={4}>
                                            <Box display="flex" justifyContent="center" p={2}>
                                                <CircularProgress/>
                                            </Box>
                                        </TableCell>
                                    </TableRow>
                                ) : moduleQualifications.length ? (moduleQualifications.map((tracker: any) => (
                                        <TableRow key={tracker.id}>
                                            <TableCell>
                                                <Typography variant="body1">{tracker.part.name}</Typography>
                                                <Typography variant="caption" sx={{display: 'block'}}>
                                                    {tracker.part.category}
                                                </Typography>
                                                <Typography variant="caption" sx={{display: 'block'}}>
                                                    {tracker.part.reference}
                                                </Typography>
                                            </TableCell>
                                            <TableCell align="center" sx={{width: 200, minWidth: 100, maxWidth: 250}}>
                                                <Button type="button"
                                                        variant="outlined"
                                                        size="small"
                                                        onClick={() => {
                                                            setQualificationId(tracker.part.id);
                                                            setTrackerId(tracker.id);
                                                            setOpenQualificationDialog(true);
                                                        }}>
                                                    View
                                                </Button>
                                            </TableCell>
                                            <TableCell align="center" sx={{width: 200, minWidth: 100, maxWidth: 250}}>
                                                <Tooltip
                                                    title={`${tracker.visible ? 'Visible in' : 'Hidden from'} relevant sections`}>
                                                    <Switch
                                                        checked={!!tracker.visible}
                                                        onChange={() => handleQualificationVisibility(tracker.id, !tracker.visible)}
                                                        inputProps={{'aria-label': 'Show/ Hide the qualification'}}
                                                    />
                                                </Tooltip>
                                            </TableCell>
                                            <TableCell size="small" align="center"
                                                       sx={{width: 200, minWidth: 100, maxWidth: 250}}>
                                                <Button
                                                    type="button"
                                                    variant="outlined"
                                                    aria-label="Remove Qualification"
                                                    size="small"
                                                    onClick={() => {
                                                        setOpenConfirmDialog(true);
                                                        setRemoveQualificationId(tracker.id);
                                                    }}
                                                >
                                                    Remove Qualification
                                                </Button>
                                            </TableCell>
                                        </TableRow>
                                    ))
                                ) : (
                                    <TableRow>
                                        <TableCell colSpan={4}>
                                            <Box textAlign="center" p={2}>
                                                <Typography variant="body1" color="textSecondary">
                                                    No qualifications are currently being tracked.
                                                </Typography>
                                            </Box>
                                        </TableCell>
                                    </TableRow>
                                )}
                            </TableBody>
                        </Table>
                    </TableContainer>
                </form>
                <CustomDialog
                    open={openConfirmDialog}
                    onClose={disabledCloseButtons ? () => {
                    } : handleClose}
                    title="Confirm Removal"
                    onConfirm={() => handleRemoveQualification()}
                    confirmText="Yes"
                    cancelText="No"
                    showTitle={true}
                    showContent={true}
                    showActions={true}
                    disabledCloseButtons={disabledCloseButtons}
                > Are you sure you wish to remove this Qualification? Removing it will unlink the Qualification from
                    the {vocabCourse}.</CustomDialog>
            </Box>

            <Box sx={{'margin-top': "25px", p: 3, boxShadow: 3, borderRadius: 2}}>
                <Typography variant="h2" gutterBottom sx={{
                    'font-size': '1.5rem',
                    'text-transform': 'math-auto !important'
                }}>
                    Track New Qualification(s)
                </Typography>
                <form style={{overflow: "unset", position: "relative"}}>
                    {selectedQualification !== null &&
                        <Box sx={{
                            position: 'absolute',
                            'width': '100%',
                            height: '100%',
                            backgroundColor: 'rgba(255,255,255, 0.5)',
                            'z-index': '5'
                        }}>
                            <Box display="flex" justifyContent="center" alignItems="center" p={2} sx={{height: '100%'}}>
                                <CircularProgress/>
                            </Box>
                        </Box>}

                    <Box sx={{display: "flex", gap: 2, mb: 2}}>
                        <TextField
                            fullWidth
                            variant="outlined"
                            label="Search"
                            placeholder="Search..."
                            value={searchInput}
                            InputProps={{
                                'aria-label': 'Search qualifications',
                                'endAdornment': (
                                    <InputAdornment position="end">
                                        {searchInput && (
                                            <IconButton
                                                aria-label="Clear search"
                                                onClick={() => {
                                                    setSearchInput('');
                                                    setSearch('');
                                                    setPage(1);
                                                }}
                                                edge="end"
                                                size="small"
                                            >
                                                <ClearIcon fontSize="small"/>
                                            </IconButton>
                                        )}
                                        <IconButton
                                            aria-label="Search"
                                            onClick={() => setSearch(searchInput)}>
                                            <SearchIcon/>
                                        </IconButton>
                                    </InputAdornment>
                                ),
                            }}
                            sx={{
                                "& .MuiInputBase-input": {
                                    padding: "16.5px 14px !important",
                                    border: "none",
                                },
                                "& .MuiInputBase-input:focus": {
                                    outline: "unset !important",
                                }
                            }}
                            onChange={(e: {
                                target: { value: React.SetStateAction<string>; };
                            }) => {
                                setSearchInput(e.target.value);
                                setSearch(e.target.value);
                            }}
                            onKeyDown={(e) => {
                                if (e.key === 'Enter') {
                                    setSearch(searchInput)
                                }
                            }}
                        />
                        <FormControl fullWidth>
                            <Autocomplete
                                disablePortal
                                options={types ?? []}
                                onChange={(_event, newValue) => setTitleType(newValue ?? '')}
                                renderInput={(params) => <TextField {...params} label="Type"/>}
                            />
                        </FormControl>
                        <FormControl fullWidth>
                            <Autocomplete
                                disablePortal
                                options={providers ?? []}
                                onChange={(_event, newValue) => setTitleProvider(newValue ?? '')}
                                renderInput={(params) => <TextField {...params} label="Provider"/>}
                            />
                        </FormControl>
                    </Box>

                    <TableContainer component={Paper} sx={{mb: 2, maxHeight: 300, overflow: "auto"}}>
                        <Table stickyHeader>
                            <TableHead>
                                <TableRow>
                                    <TableCell>
                                        <TableSortLabel
                                            active={sortBy === 'type'}
                                            direction={sortDirection === 'desc' ? 'desc' : 'asc'}
                                            onClick={() => handleSort('type', sortDirection)}
                                            IconComponent={getIconComponent(sortBy === 'type', sortDirection === 'desc' ? 'desc' : 'asc')}
                                        >
                                            Type
                                        </TableSortLabel>
                                    </TableCell>
                                    <TableCell>
                                        <TableSortLabel
                                            active={sortBy === 'name'}
                                            direction={sortDirection === 'desc' ? 'desc' : 'asc'}
                                            onClick={() => handleSort('name', sortDirection)}
                                            IconComponent={getIconComponent(sortBy === 'name', sortDirection === 'desc' ? 'desc' : 'asc')}
                                        >
                                            Qualification
                                        </TableSortLabel>
                                    </TableCell>
                                    <TableCell>
                                        <TableSortLabel
                                            active={sortBy === 'reference'}
                                            direction={sortDirection === 'desc' ? 'desc' : 'asc'}
                                            onClick={() => handleSort('reference', sortDirection)}
                                            IconComponent={getIconComponent(sortBy === 'reference', sortDirection === 'desc' ? 'desc' : 'asc')}
                                        >
                                            Reference
                                        </TableSortLabel>
                                    </TableCell>
                                    <TableCell>
                                        <TableSortLabel
                                            active={sortBy === 'provider'}
                                            direction={sortDirection === 'desc' ? 'desc' : 'asc'}
                                            onClick={() => handleSort('provider', sortDirection)}
                                            IconComponent={getIconComponent(sortBy === 'provider', sortDirection === 'desc' ? 'desc' : 'asc')}
                                        >
                                            Provider
                                        </TableSortLabel>
                                    </TableCell>
                                    <TableCell>
                                        View
                                    </TableCell>
                                    <TableCell>
                                        Track
                                    </TableCell>
                                </TableRow>
                            </TableHead>
                            <TableBody>
                                {loadingQualifications ? (
                                    <TableRow>
                                        <TableCell colSpan={6}>
                                            <Box display="flex" justifyContent="center" p={2}>
                                                <CircularProgress/>
                                            </Box>
                                        </TableCell>
                                    </TableRow>
                                ) : visibleQualificationList.length > 0
                                    ? visibleQualificationList.map((qualification: qualification) => (
                                        <TableRow key={qualification.part.id}>
                                            <TableCell>{qualification.type}</TableCell>
                                            <TableCell>{qualification.part.name}</TableCell>
                                            <TableCell>{qualification.part.reference}</TableCell>
                                            <TableCell>{qualification.awardingBody}</TableCell>
                                            <TableCell align="center" size="small"
                                                       sx={{width: 100, minWidth: 60, maxWidth: 120}}>
                                                <Button type="button"
                                                        variant="outlined"
                                                        size="small"
                                                        aria-label={`View ${qualification.part.name}`}
                                                        onClick={() => {
                                                            setQualificationId(qualification.part.id);
                                                            setTrackerId(null);
                                                            setOpenQualificationDialog(true);
                                                        }}>
                                                    View
                                                </Button>
                                            </TableCell>
                                            <TableCell align="center" size="small"
                                                       sx={{width: 80, minWidth: 50, maxWidth: 100}}>
                                                <Button type="button"
                                                        variant="outlined"
                                                        size="small"
                                                        aria-label={`Track ${qualification.part.name}`}
                                                        onClick={() => handleTrackQualification(qualification.part.id)}
                                                        disabled={selectedQualification === qualification.part.id} // Disable button while loading
                                                        startIcon={selectedQualification === qualification.part.id &&
                                                            <CircularProgress size={20} color="inherit"/>}
                                                >
                                                    Track
                                                </Button>
                                            </TableCell>
                                        </TableRow>
                                    ))
                                    : <TableRow>
                                        <TableCell colSpan={6}>
                                            <Box textAlign="center" p={2}>
                                                <Typography variant="body1" color="textSecondary">
                                                    No qualifications are available.
                                                </Typography>
                                            </Box>
                                        </TableCell>
                                    </TableRow>}
                            </TableBody>
                        </Table>
                    </TableContainer>

                    <CustomPagination
                        totalRecords={totalRecords}
                        page={page}
                        rowsPerPage={rowsPerPage}
                        onPageChange={(newPage: number) => setPage(newPage)}
                        onRowsPerPageChange={(newRows: number) => {
                            setPage(1);
                            setRowsPerPage(newRows);
                        }}
                        rowsPerPageOptions={defaultRowPerPageOptions}
                    />

                    <CustomDialog
                        open={openQualificationDialog}
                        onClose={handleClose}
                        title="Qualification details"
                        cancelText="Close"
                        showTitle={true}
                        showContent={true}
                        showActions={true}
                        dialogSize="lg">
                        <QualificationDetails baseUrl={baseUrl} qualificationId={qualificationId}
                                              trackerId={trackerId} getMessageIcon={getMessageIcon}/>
                    </CustomDialog>

                    <CustomDialog
                        open={open}
                        onClose={handleClose}
                        title="Select the Optional Units for this Qualification"
                        onConfirm={handleConfirm}
                        confirmText="Confirm"
                        cancelText="Cancel"
                        showTitle={true}
                        showContent={true}
                        showActions={true}>
                        <SelectUnits units={units} onUnitChange={handleUnitSelectChange}/>
                    </CustomDialog>
                </form>
            </Box>
        </ThemeProvider>
    );
};
