import React, {useEffect, useRef, useState} from "react";
import {
    TableContainer,
    Table,
    TableHead,
    TableBody,
    TableRow,
    TableCell,
    Paper,
    Box,
    Typography,
    IconButton,
    TextField,
    InputAdornment,
    Button,
    CircularProgress,
    ThemeProvider,
    Alert,
    MenuItem,
    Checkbox,
    Divider
} from "@mui/material";
import {Clear as ClearIcon, ReportProblem, Search as SearchIcon} from "@mui/icons-material";
import TableSortLabel from '@mui/material/TableSortLabel';
import getIconComponent from '../Common/CustomSortIcon';
// Define the columns you want to allow sorting on
const sortableColumns = [
    { id: 'academicYear', label: 'Academic Year' },
    { id: 'studentFullName', label: 'Student Name' },
    { id: 'studentId', label: 'Student Reference' },
    { id: 'status', label: 'Status' },
    { id: 'adminSignedDate', label: 'Signed Date' },
    { id: 'objectedDate', label: 'Objected Date' },
];
import theme from "../Common/Theme";
import CheckIcon from "@mui/icons-material/Check";
import CustomPagination from "../Common/CustomPagination";
import AgreementView from "./AgreementView";
import CustomDialog from "../Qualification/Manage/CustomDialog";
import Tippy from "@tippyjs/react";

declare global {
    interface Window {
        $: any; // jQuery
    }
}

type LDAItem = {
    id: null | number;
    studentFullName: string;
    studentId: number;
    studentReference: string;
    adminSignedDate: null | string;
    academicYear: number | null;
    academicYearName: string | null;
    objectedDate: null | string;
    statementId: null | number;
    status: string;
    studentSignatureId: number | null;
}

type LDAList = {
    data: LDAItem[];
    rowsPerPage: number;
    page: number;
    totalRecords: number;
    readyToSignTotal?: number;
	objectedTotal?: number;
}

export const LearnerDataAgreement = ({
                                         baseUrl,
                                         defaultRowPerPageOptions,
                                         LDAVocab,
                                         LDAStatues,
                                         readyToSignStatus,
                                         notReadyToSignStatus,
                                         resetPossibleStatues,
                                         currentAcademicYear
                                     }: {
    baseUrl: string,
    defaultRowPerPageOptions: any,
    LDAVocab: string,
    LDAStatues: any,
    readyToSignStatus: string,
    notReadyToSignStatus: string,
    resetPossibleStatues: any,
    currentAcademicYear: number | null,
}) => {
    const [message, setMessage] = useState<string | null>(null);
    const [messageType, setMessageType] = useState<'success' | 'error'>("success");

    const [loading, setLoading] = useState(false);

    const [LDAList, setLDAList] = useState<LDAList>();

    const [searchInput, setSearchInput] = useState('');
    const [search, setSearch] = useState('');
    const [page, setPage] = useState(1);
    const [rowsPerPage, setRowsPerPage] = useState(defaultRowPerPageOptions[0]);
    const [fromDate, setFromDate] = useState('');
    const [tillDate, setTillDate] = useState('');
    const [statuses, setStatuses] = useState(readyToSignStatus);

    const [selectedLDAs, setSelectedLDAs] = useState<number[]>([]);
    const signatureRef = useRef(null);

    const [openAgreementView, setOpenAgreementView] = useState(false);
    const [selectedLDA, setSelectedLDA] = useState<number | null>(null);

    const [selectedStudentId, setSelectedStudentId] = useState<number | null>(null);
    const [isSigned, setIsSigned] = useState(false);

    // Sorting state
    const [sortBy, setSortBy] = useState<string>('');
    const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc');

    const [openConfirmReset, setOpenConfirmReset] = useState(false);
    const focusMessage = useRef<HTMLDivElement>(null);

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

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

    const resetFilters = () => {
        setSearchInput('');
        setSearch('');
        setFromDate('');
        setTillDate('');
        setStatuses(readyToSignStatus);
        setPage(1);
        setSortBy('');
        setSortDirection('asc');
        setSelectedLDAs([]);
    }

    const toggleSelect = () => {
        const readyIds = LDAList?.data
            ?.filter((row: any) => row.status === readyToSignStatus)
            .map((row: any) => row.id) ?? [];

        const allReadySelected = readyIds.every((id) => selectedLDAs.includes(id));

        if (allReadySelected) {
            // Deselect all "Ready to Sign" rows only
            const updatedSelection = selectedLDAs.filter(id => !readyIds.includes(id));
            setSelectedLDAs(updatedSelection);
        } else {
            // Keep existing selections, add missing "Ready to Sign" rows
            const updatedSelection = Array.from(new Set([...selectedLDAs, ...readyIds]));
            setSelectedLDAs(updatedSelection);
        }
    }

    const handleSelect = (ldaId: number) => {
        if (selectedLDAs.includes(ldaId)) {
            // Remove the ID (deselect)
            setSelectedLDAs(prev => prev.filter(id => id !== ldaId));
        } else {
            // Add the ID (select)
            setSelectedLDAs(prev => [...prev, ldaId]);
        }
    }
    const handleEnd = () => {
        if (signatureRef.current) {
            const data = window.$(signatureRef.current).jSignature('getData', 'native');
            setIsSigned(Array.isArray(data) && data.length > 0);
        }
    };

    const handleSubmit = () => {
        if (!selectedLDAs.length) {
            setValidationMessage(`Select at least one ${LDAVocab}`, 'error');
            return;
        }

        const data = window.$(signatureRef.current).jSignature('getData', 'native');
        if (Array.isArray(data) && data.length === 0) {
            setValidationMessage(`Signature is required`, 'error');
            return;
        }

        const signature = window.$(signatureRef.current).jSignature('getData', 'base30');

        fetch(baseUrl + 'v1/lda', {
            method: 'POST',
            headers: {
                'X-Requested-With': 'XMLHttpRequest',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ldaIds: selectedLDAs.join(','), signature: signature.join(',')})
        }).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') {
                setValidationMessage(respJSON.message, 'error');
                return;
            }

            setValidationMessage(respJSON.message);
            clearSignature();
            loadLDAList();

        }).catch((error) => {
            setValidationMessage(`Failed to sign ${LDAVocab}`, 'error');
            console.error(error);
        });
    };

    const handleClose = () => {
        setOpenAgreementView(false);
        setSelectedLDA(null);
        setSelectedStudentId(null);
        setOpenConfirmReset(false);
    }

    const clearSignature = () => {
        if (signatureRef.current) {
            window.$(signatureRef.current).jSignature('reset');
             setIsSigned(false);
        }
    };

    const loadLDAList = () => {
        setLoading(true);
        setSelectedLDAs([]);

        let params = new URLSearchParams();
        if (page) {
            params.set('page', `${page}`);
        }
        if (rowsPerPage) {
            params.set('rowsPerPage', `${rowsPerPage}`);
        }
        if (fromDate) {
            params.set('start', `${fromDate}`);
        }
        if (tillDate) {
            params.set('end', `${tillDate}`);
        }
        if (statuses && statuses !== 'All') {
            params.set('statuses', `${statuses}`);
        }
        if (search) {
            params.set('search', `${search}`);
        }
        if (sortBy) {
            params.set('sortBy', sortBy);
            params.set('sortDirection', sortDirection);
        }

        fetch(baseUrl + 'v1/lda?' + params.toString(), {
            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') {
                setValidationMessage(respJSON.message, 'error');
                return;
            }

            setLDAList(respJSON);
            setLoading(false);
        }).catch((error) => {
            setValidationMessage(`Failed to load ${LDAVocab}`, 'error');
            console.error(error);
        });
    };

    const setValidationMessage = (message: string, messageType: 'success' | 'error' = 'success') => {
        setMessage(message);
        setMessageType(messageType);
    }

    const handleReset = () => {
        fetch(baseUrl + 'v1/lda/' + selectedLDA, {
            method: 'PUT',
            headers: {
                'X-Requested-With': 'XMLHttpRequest',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({})
        }).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') {
                setValidationMessage(respJSON.message, 'error');
                return;
            }

            loadLDAList();
            setOpenConfirmReset(false);
            setSelectedLDA(null);
            setValidationMessage(respJSON.message);
        }).catch((error) => {
            setValidationMessage(`Failed to reset the ${LDAVocab}. Please try again later.`, 'error');
            console.error(error);
        });
    }

    useEffect(() => {
        loadLDAList();
    }, [page, rowsPerPage, search, fromDate, tillDate, statuses, sortBy, sortDirection]);

    useEffect(() => {
        if (window.$ && signatureRef.current) {
            window.$(signatureRef.current).jSignature({
                color: '#000',
                lineWidth: 2
            });
            window.$(signatureRef.current).bind('change', handleEnd);
        } else {
            console.error('jQuery or jSignature not available');
        }
    }, []);

    useEffect(() => {
        if(message) {
            focusMessage.current?.focus();
            setTimeout(() => {
                setMessage(null);
            }, 5000);
        }
    }, [message]);

    return (
        <ThemeProvider theme={theme}>
			<Box display="flex" gap={1} mb={2} alignItems="center">
				<Typography variant="subtitle1">
					Ready to Sign: {LDAList?.readyToSignTotal ?? 0}
				</Typography>
				<Typography variant="subtitle1">
					| Objected: {LDAList?.objectedTotal ?? 0}
				</Typography>
			</Box>
            {message && (
                <Box sx={{textAlign: 'center', mb: 1}} ref={focusMessage} tabIndex={-1}>
                    <Alert
                        icon={getMessageIcon(messageType)}
                        variant="filled"
                        severity={messageType}
                        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
                        }}
                    >
                        {message}
                    </Alert>
                </Box>
            )}

            <Paper sx={{p: 3, boxShadow: 3, borderRadius: 2}}>
                <Box display="flex" gap={2} flexWrap="wrap" mb={2} justifyContent={{xs: 'flex-start', md: 'flex-end'}}>
                    <TextField
                        label="Search"
                        size="small"
                        placeholder="Search"
                        value={searchInput}
                        InputProps={{
                            'aria-label': 'Search',
                            '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);
                                            setPage(1);
                                        }}>
                                        <SearchIcon/>
                                    </IconButton>
                                </InputAdornment>
                            ),
                        }}
                        onChange={(e: any) => {
                            setSearchInput(e.target.value);
                        }}
                        onKeyDown={(e: any) => {
                            if (e.key === 'Enter') {
                                setSearch(searchInput);
                            }
                        }}
                    />

                    {/* From Date */}
                    <TextField
                        label="Start Date"
                        type="date"
                        size="small"
                        value={fromDate}
                        onChange={(e: any) => {
                            setPage(1);
                            setFromDate(e.target.value);
                        }}
                        InputLabelProps={{shrink: true}}
                    />

                    {/* Till Date */}
                    <TextField
                        label="End Date"
                        type="date"
                        size="small"
                        value={tillDate}
                        onChange={(e: any) => {
                            setPage(1);
                            setTillDate(e.target.value);
                        }}
                        InputLabelProps={{shrink: true}}
                    />

                    {/* Status Dropdown */}
                    <TextField
                        select
                        label="Status"
                        size="small"
                        value={statuses}
                        onChange={(e: any) => {
                            setStatuses(e.target.value);
                            setPage(1);
                        }}
                        sx={{minWidth: 150}}
                    >
                        <MenuItem value="All">All</MenuItem>
                        {LDAStatues.map((option: any) => (
                            <MenuItem key={option} value={option}>
                                {option}
                            </MenuItem>
                        ))}
                    </TextField>

                    {/* Reset Button */}
                    <Button
                        variant="outlined"
                        size="small"
                        onClick={() => resetFilters()}
                    >
                        Reset
                    </Button>
                </Box>

                <Box mb={5}>
                    <TableContainer component={Paper} sx={{mb: 2, overflow: "auto"}}>
                        <Table stickyHeader>
                            <TableHead>
                                <TableRow>
                                    {sortableColumns.map(col => (
                                        <TableCell key={col.id} sx={{ fontWeight: 'bold', userSelect: 'none' }}>
                                            <TableSortLabel
                                                active={sortBy === col.id}
                                                direction={sortBy === col.id ? sortDirection : 'asc'}
                                                onClick={() => {
                                                    if (sortBy === col.id) {
                                                        setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc');
                                                    } else {
                                                        setSortBy(col.id);
                                                        setSortDirection('asc');
                                                    }
                                                }}
                                                IconComponent={getIconComponent(sortBy === col.id, sortDirection)}
                                            >
                                                {col.label}
                                            </TableSortLabel>
                                        </TableCell>
                                    ))}
                                    <TableCell>View</TableCell>
                                    <TableCell>Action</TableCell>
                                    <TableCell onClick={() => toggleSelect()} className="ops_page_highlight_yellow"
                                               sx={{
                                                   cursor: 'pointer',
                                                   fontWeight: 'bold',
                                                   '&:hover': {
                                                       textDecoration: 'underline',
                                                   },
                                               }}>Select</TableCell>
                                </TableRow>
                            </TableHead>
                            <TableBody>
                                {loading ? (
                                    <TableRow>
                                        <TableCell colSpan={8}>
                                            <Box display="flex" justifyContent="center" p={2}>
                                                <CircularProgress/>
                                            </Box>
                                        </TableCell>
                                    </TableRow>
                                ) : LDAList?.data.length ? (LDAList.data.map((row: LDAItem) => (
                                    <TableRow key={row.id ?? row.studentId}>
                                        <TableCell align="center">
                                            {row.academicYearName}
                                        </TableCell>
                                        <TableCell>
                                            {row.studentFullName}
                                        </TableCell>
                                        <TableCell align="center">
                                            <mini-profile
                                                    name={row.studentFullName}
                                                    callout-csv={[]}
                                                    pronouns={''}
                                                    reference={row.studentReference}
                                                    photo-url={`${baseUrl}public/photo/thumbnail/${row.studentId}-${row.studentReference}`}
                                                    profile-url={`${baseUrl}student/${row.studentReference}`}
                                                />
                                            </TableCell>
                                            <TableCell align="center">
                                                {row.status}
                                            </TableCell>
                                            <TableCell align="center">
                                                {row.adminSignedDate}
                                            </TableCell>
                                            <TableCell align="center">
                                                {row?.objectedDate}
                                            </TableCell>
                                            <TableCell size="small" align="center">
                                                <Box
                                                    component="a"
                                                    href="#"
                                                    sx={{
                                                        color: 'primary.main',
                                                        cursor: 'pointer',
                                                        '&:hover': {
                                                            textDecoration: 'none',
                                                        },
                                                    }}
                                                    onClick={(e: any) => {
                                                        e.preventDefault();
                                                        if (row.id) {
                                                            setSelectedStudentId(null);
                                                            setSelectedLDA(row.id);
                                                        } else {
                                                            setSelectedLDA(null);
                                                            setSelectedStudentId(row.studentId);
                                                        }
                                                        setOpenAgreementView(true);
                                                    }}>
                                                    Click to view
                                                </Box>
                                            </TableCell>
                                            <TableCell align="center">
                                                {row.status === 'Legacy' ? (
                                                    <Tippy key={row.id}
                                                        content={
                                                            <div className='tippy-wrapper'>
                                                                <p className='tippy-inner-content'>Reset is not available for {LDAVocab} under the Legacy status.
                                                                    These agreements were signed under a previous version.
                                                                    This is the case even if they were signed in the current year.</p>
                                                            </div>
                                                        }
                                                        arrow
                                                        allowHTML={true}
                                                        offset={[0, -5]}>
                                                    <span style={{color: '#888'}}>Not Available</span>
                                                    </Tippy>
                                                ) : (
                                                    currentAcademicYear && currentAcademicYear === row.academicYear
                                                    && (
                                                        resetPossibleStatues.includes(row.status)
                                                        || notReadyToSignStatus === row.status && row.studentSignatureId
                                                    )
                                                        ?
                                                        <Tippy key={row.id}
                                                            content={
                                                                <div className='tippy-wrapper'>
                                                                    <p className='tippy-inner-content'>Reset is
                                                                        available when the student has signed or
                                                                        objected. Clicking Reset changes the {LDAVocab}
                                                                        {' '}to an unsigned state on the student dashboard.
                                                                    </p>
                                                                </div>
                                                            }
                                                            arrow
                                                            allowHTML={true}
                                                            offset={[0, -5]}>
                                                            <Box
                                                                component="a"
                                                                href="#"
                                                                sx={{
                                                                    color: 'primary.main',
                                                                    cursor: 'pointer',
                                                                    '&:hover': {
                                                                        textDecoration: 'none',
                                                                    },
                                                                }}
                                                                onClick={(e: any) => {
                                                                    e.preventDefault();
                                                                    setSelectedLDA(row.id);
                                                                    setOpenConfirmReset(true);
                                                                }}>
                                                                Reset
                                                            </Box>
                                                        </Tippy>
                                                        : ''
                                                )}
                                            </TableCell>
                                            <TableCell size="small" align="center">
                                                {row.status === readyToSignStatus && row.id ? (
                                                    <Checkbox
                                                        checked={selectedLDAs.includes(row.id)}
                                                        onChange={() => handleSelect(row.id!)}
                                                        slotProps={{
                                                            input: {
                                                                'aria-label': `Approve agreement for ${row.studentFullName}`,
                                                            },
                                                        }}
                                                    />
                                                ) : (
                                                    <Box sx={{display: 'inline-block', cursor: 'not-allowed'}}>
                                                        <Checkbox disabled
                                                                  slotProps={{
                                                                      input: {
                                                                          'aria-label': row.studentSignatureId
                                                                              ? `Signed by ${row.studentFullName}, awaiting tutor's signature.`
                                                                              : `Awaiting signature from ${row.studentFullName}.`,
                                                                      },
                                                                  }}
                                                        />
                                                    </Box>
                                                )}
                                            </TableCell>
                                        </TableRow>
                                ))) : (
                                    <TableRow>
                                        <TableCell colSpan={8}>
                                            <Box textAlign="center" p={2}>
                                                <Typography variant="body1" color="textSecondary">
                                                    No {LDAVocab} found.
                                                </Typography>
                                            </Box>
                                        </TableCell>
                                    </TableRow>
                                )}
                            </TableBody>
                        </Table>
                    </TableContainer>
                    <CustomPagination
                        totalRecords={LDAList?.totalRecords ?? 0}
                        page={page}
                        rowsPerPage={rowsPerPage}
                        onPageChange={(newPage: number) => {
                            setPage(newPage);
                        }
                        }
                        onRowsPerPageChange={(newRows: number) => {
                            setPage(1);
                            setRowsPerPage(newRows);
                        }}
                        rowsPerPageOptions={defaultRowPerPageOptions}
                    />
                </Box>

                <Divider/>
                <Box mt={5} textAlign="center">
                    <Typography>Sign and submit below to insert your signature into all the selected documents
                        above.</Typography>
                    <Box ref={signatureRef}
                         sx={{
                             width: '100%',
                             maxWidth: 600,
                             mx: 'auto',
                             border: '1px solid black',
                             mb: 1
                         }}
                    />
                    <Box display="flex" justifyContent="center" gap="1em">
                        <Button
                            onClick={handleSubmit}
                            disabled={!isSigned}
                            variant="submitSignature"
                            color="primary"
                        >
                            Submit Signature
                        </Button>
                        <Button onClick={() => clearSignature()}>
                            Clear
                        </Button>
                    </Box>
                </Box>
            </Paper>

            <CustomDialog
                open={openAgreementView}
                onClose={handleClose}
                title=""
                cancelText="Close"
                showTitle={true}
                showContent={true}
                showActions={true}
                dialogSize="lg">
                <AgreementView {...{baseUrl, getMessageIcon, ldaId: selectedLDA, studentId: selectedStudentId}} />
            </CustomDialog>

            <CustomDialog
                open={openConfirmReset}
                onClose={handleClose}
                onConfirm={handleReset}
                title="Confirm"
                confirmText="Confirm"
                cancelText="Cancel"
                showTitle={true}
                showContent={true}
                showActions={true}
                dialogSize="xs">
                Are you sure you want to reset the {LDAVocab}?
            </CustomDialog>

        </ThemeProvider>
    );
};
