// material-ui
import * as React from 'react';
import {apiPath} from "../../../auth/utils";
import { POST_SIG_UPLOAD1, GET_FORM_SIG_PAGE_CONFIG } from "../../../utils/ApiPathConst";
import axios from 'axios';
import {
    DataGrid,
    GridActionsCellItem,
} from "@mui/x-data-grid";
import EditIcon from '@mui/icons-material/Edit';
import UploadFileIcon from '@mui/icons-material/UploadFile';
import CheckCircleIcon from '@mui/icons-material/CheckCircle';

// FIX 1: Correctly import both download icons from their respective paths
import FileDownloadIcon from '@mui/icons-material/FileDownload';
import DownloadDoneIcon from '@mui/icons-material/DownloadDone'; 

import {
    Dialog,
    DialogTitle,
    DialogContent,
    DialogActions,
    Button,
    Typography,
    Box,
    CircularProgress,
} from '@mui/material';
import {useContext, useEffect} from "react";
import {useNavigate} from "react-router-dom";
// Note: Assuming these utility functions/components are defined elsewhere
import {CustomNoRowsOverlay, dateComparator, getDateString} from "../../../utils/CommonFunction";
import AbilityContext from "../../../components/AbilityProvider";
import {LIONER_BUTTON_THEME} from "../../../themes/colorConst";
import {ThemeProvider} from "@emotion/react";

// ==============================|| PDF TABLE ||============================== //

// Define the structure for the row data stored in state
const initialUploadState = {
    id: null,
    templateName: null, // This will be the formCode
    refType: null, // To differentiate between upload1 and upload2 if needed
}

export default function PdfTable({recordList}) {
    const [rows, setRows] = React.useState(recordList);
    const [rowModesModel] = React.useState({});

    // State for Dialog visibility and Loading state
    const [isDialogOpen, setIsDialogOpen] = React.useState(false);
    // State to hold the ID, templateName, and refType for the current upload operation
    const [currentUploadRow, setCurrentUploadRow] = React.useState(initialUploadState);
    const [currentUploadLabel, setCurrentUploadLabel] = React.useState(null);
    const [isUploading, setIsUploading] = React.useState(false);

    const navigate = useNavigate()
    const ability = useContext(AbilityContext);

    const [paginationModel, setPaginationModel] = React.useState({
        page: 0,
        pageSize:10
    });

    // Ref for the hidden file input
    const fileInputRef = React.useRef(null);

    useEffect(() => {
        setPaginationModel({page:0,pageSize:10});
        setRows(recordList);
    }, [recordList]);

    const handleEditClick = (id) => () => {
        navigate(`/pdf/maintain/${id}`);
    };

    /** Safely get YYYY-MM-DD from row.created; returns null if missing or invalid. */
    const getAsOfDateString = (row) => {
        const raw = row?.created;
        if (raw == null || raw === "") return null;
        const d = new Date(raw);
        if (Number.isNaN(d.getTime())) return null;
        return d.toISOString().slice(0, 10);
    };

    /**
     * Opens the upload dialog and sets the current row details for Upload 1.
     * Fetches form-sig-page config from API for dynamic label (page number).
     */
    const handleUploadClick = (id, templateName, formCode, row) => () => {
        setCurrentUploadRow({
            id: id,
            templateName: templateName,
            formCode: formCode,
            refType: "upload1"
        });
        setCurrentUploadLabel(null);
        setIsDialogOpen(true);
        const asOfDate = getAsOfDateString(row);
        const params = new URLSearchParams({ formCode });
        if (asOfDate) params.set("asOfDate", asOfDate);
        axios.get(`${apiPath}${GET_FORM_SIG_PAGE_CONFIG}?${params}`)
            .then((res) => {
                const configs = res.data?.configs || [];
                const upload1 = configs.find((c) => c.sigType === "upload1");
                setCurrentUploadLabel(upload1?.label || "Upload Signature");
            })
            .catch(() => setCurrentUploadLabel("Upload Signature"));
    };

    /**
     * Opens the upload dialog and sets the current row details for Upload 2.
     * Fetches form-sig-page config from API for dynamic label.
     */
    const handleUpload2Click = (id, templateName, formCode, row) => () => {
        setCurrentUploadRow({
            id: id,
            templateName: templateName,
            formCode: formCode,
            refType: "upload2"
        });
        setCurrentUploadLabel(null);
        setIsDialogOpen(true);
        const asOfDate = getAsOfDateString(row);
        const params = new URLSearchParams({ formCode });
        if (asOfDate) params.set("asOfDate", asOfDate);
        axios.get(`${apiPath}${GET_FORM_SIG_PAGE_CONFIG}?${params}`)
            .then((res) => {
                const configs = res.data?.configs || [];
                const upload2 = configs.find((c) => c.sigType === "upload2");
                setCurrentUploadLabel(upload2?.label || "Upload 2");
            })
            .catch(() => setCurrentUploadLabel("Upload 2"));
    };

    /**
     * Handles the standard download (fillable file, endpoint: /download-ff/{id})
     */
    const handleDownloadClick = (id) => () => {

        // 1. Construct the download URL for the FILLABLE file
        const downloadUrl = `${apiPath}/pdf/download-ff/${id}`;

        // Use axios to fetch the PDF as a Blob
        axios.get(downloadUrl, {
            responseType: 'blob', // IMPORTANT: Tells axios to handle the response as binary data
        })
        .then((response) => {

            // 2. Extract Filename from Content-Disposition Header
            const contentDisposition = response.headers['content-disposition'];
            let filename = `document-${id}.pdf`; // Fallback filename

            if (contentDisposition) {
                // Regex to find filename="name.pdf" or filename*=UTF-8''name.pdf
                const filenameMatch = contentDisposition.match(/filename\*?=['"]?([^'"]+)/);
                if (filenameMatch && filenameMatch[1]) {
                    // Decode URI component and remove extra quotes
                    filename = decodeURIComponent(filenameMatch[1].replace(/\\"/g, ''));
                }
            }

            // 3. Create a temporary anchor tag (<a>) to trigger the download
            const blob = new Blob([response.data], { type: 'application/pdf' });
            const url = window.URL.createObjectURL(blob);
            const link = document.createElement('a');

            link.href = url;
            link.setAttribute('download', filename);
            document.body.appendChild(link);
            link.click();

            // 4. Clean up
            document.body.removeChild(link);
            window.URL.revokeObjectURL(url);
        })
        .catch((error) => {
            console.error(`Download failed for ID ${id}:`, error);
            // Handle error response (e.g., if the backend returns a 404 or a JSON error)
            alert('Failed to download the PDF file. Check server logs.');
        });
    };

    /**
     * Handles the flat download (finalized file, endpoint: /download-flat/{id})
     */
    const handleFlatDownloadClick = (id) => () => {

        // 1. Construct the download URL for the FLATTENED file
        const downloadUrl = `${apiPath}/pdf/download-flat/${id}`;

        // Use axios to fetch the PDF as a Blob
        axios.get(downloadUrl, {
            responseType: 'blob', // IMPORTANT: Tells axios to handle the response as binary data
        })
        .then((response) => {

            // 2. Extract Filename from Content-Disposition Header
            const contentDisposition = response.headers['content-disposition'];
            let filename = `document-flat-${id}.pdf`; // Fallback filename

            if (contentDisposition) {
                // Regex to find filename="name.pdf" or filename*=UTF-8''name.pdf
                const filenameMatch = contentDisposition.match(/filename\*?=['"]?([^'"]+)/);
                if (filenameMatch && filenameMatch[1]) {
                    // Decode URI component and remove extra quotes
                    filename = decodeURIComponent(filenameMatch[1].replace(/\\"/g, ''));
                }
            }

            // 3. Create a temporary anchor tag (<a>) to trigger the download
            const blob = new Blob([response.data], { type: 'application/pdf' });
            const url = window.URL.createObjectURL(blob);
            const link = document.createElement('a');

            link.href = url;
            link.setAttribute('download', filename);
            document.body.appendChild(link);
            link.click();

            // 4. Clean up
            document.body.removeChild(link);
            window.URL.revokeObjectURL(url);
        })
        .catch((error) => {
            console.error(`Flat download failed for ID ${id}:`, error);
            // Handle error response (e.g., if the backend returns a 404 or a JSON error)
            alert('Failed to download the flattened PDF file. Check server logs.');
        });
    };

    const handleCloseDialog = () => {
        setIsDialogOpen(false);
        setCurrentUploadRow(initialUploadState);
        setCurrentUploadLabel(null);
        if (fileInputRef.current) {
            fileInputRef.current.value = ""; // Clear the file input
        }
    };

    // Fallback dialog title when API config is not yet loaded or fails
    const getUploadDialogTitle = (formCode, refType) => {
        if (refType === "upload1") return "Upload Signature";
        if (refType === "upload2") return "Upload 2";
        return "Upload File";
    };
    
    // Function to handle file selection and API submission
    const handleFileChange = async (event) => {
        const file = event.target.files[0];
        const { id, refType } = currentUploadRow; // Removed templateName as it's not needed for FormData

        if (!file || !id || !refType) return;

        if (file.type !== "application/pdf") {
            alert("Please select a PDF file.");
            event.target.value = "";
            return;
        }

        // The URL should potentially change based on refType if upload2 uses a different endpoint
        const uploadUrl = `${apiPath}${POST_SIG_UPLOAD1}`; // Assuming POST_SIG_UPLOAD1 is used for both for now

        // 1. Create FormData
        const formData = new FormData();
        formData.append('file', file);
        formData.append('refId', id);
        formData.append('refType', refType); // Pass the refType to the backend
        setIsUploading(true);

        try {
            const response = await axios.post(
                uploadUrl,
                formData,
                {
                    headers: {
                        'Content-Type': 'multipart/form-data',
                    }
                }
            );

            if (response.status === 200) {
                alert('Upload success');
                console.log(`PDF file ${file.name} successfully uploaded for record ID: ${id} with refType: ${refType}!`);

                // --- START: Update local state to show the green tick ---
                const uploadedFileId = response.data?.fileId || 'temp-id-' + Date.now(); // Assume the response has a fileId or use a temp one
                
                setRows(prevRows => 
                    prevRows.map(row => {
                        if (row.id === id) {
                            // Update the relevant file ID field based on refType
                            const updateField = refType === 'upload1' ? 'upload1FileId' : 'upload2FileId';
                            return {
                                ...row,
                                [updateField]: uploadedFileId // Set the file ID to trigger the icon
                            };
                        }
                        return row;
                    })
                );
                // --- END: Update local state to show the green tick ---

            } else {
                 throw new Error(`Upload failed with status: ${response.status}`);
            }

        } catch (error) {
            console.error('Upload error:', error);
            // Check if the error has a response and use its message if available
            const errorMessage = error.response?.data?.message || error.message;
            alert(`Error uploading file: ${errorMessage}`);
        } finally {
            // 3. Cleanup and close
            setIsUploading(false);
            handleCloseDialog();
        }
    };

    const handleChooseFile = () => {
        // Trigger the hidden file input click
        if (fileInputRef.current) {
            fileInputRef.current.click();
        }
    };

    const columns = [
        {
            field: 'actions',
            type: 'actions',
            headerName: 'Edit',
            width: 100,
            cellClassName: 'actions',
            getActions: ({id}) => {
                return [
                    <ThemeProvider key="OutSave" theme={LIONER_BUTTON_THEME}>
                        <GridActionsCellItem
                            icon={<EditIcon sx={{fontSize: 25}}/>}
                            label="Edit"
                            className="textPrimary"
                            onClick={handleEditClick(id)}
                            color="edit"
                        />
                    </ThemeProvider>
                ]
            },
        },

        {
            id: 'templateName',
            field: 'templateName',
            headerName: 'Form Name',
            flex: 2,
            renderCell: (params) => {
                return (
                    <div style={{display: 'flex', alignItems: 'center', justifyContent: 'center', whiteSpace: 'normal', wordBreak: 'break-word'}}>
                        {params.value} {params.row.vNum}
                    </div>
                );
            }
        },
        {
            field: 'upload1',
            type: 'actions',
            // Multi-line header
            headerName: (
                <div>
                    Upload Sig.
                </div>
            ),
            width: 100,
            cellClassName: 'actions',
            getActions: ({ id, row }) => {

                // Check upload status
                const isUploaded1 = !!row.upload1FileId;
                const isUploaded2 = !!row.upload2FileId; 
                const templateName = row.templateName;
                const formCode = row.formCode;

                // FIX 5: Use conditional colors for Upload 1
                const upload1Icon = isUploaded1
                    ? <CheckCircleIcon sx={{fontSize: 25, color: 'success.main'}} /> // Green tick if uploaded
                    : <UploadFileIcon sx={{fontSize: 25, color: 'warning.main'}} />; // Warning color if not uploaded

                const upload1Label = isUploaded1 ? "Update Signature" : "Upload Signature";

                // Define the actions
                const actions = [
                    <ThemeProvider key="UploadSign1" theme={LIONER_BUTTON_THEME}>
                        <GridActionsCellItem
                            icon={upload1Icon} // Use the dynamic icon
                            label={upload1Label} // Use the dynamic label
                            className="textPrimary"
                            onClick={handleUploadClick(id, templateName, formCode, row)}
                            color="upload"
                        />
                    </ThemeProvider>
                ];

                // Conditional rendering logic for Upload 2
                if (row.formCode === "MLB03S" || row.formCode === "SLGII" || row.formCode === "SLAPP") {
                    
                    // FIX 5: Use conditional colors for Upload 2
                    const upload2Icon = isUploaded2
                        ? <CheckCircleIcon sx={{fontSize: 25, color: 'success.main'}} /> // Green tick if uploaded
                        : <UploadFileIcon sx={{fontSize: 25, color: 'warning.main'}} />; // Warning color if not uploaded

                    const upload2Label = isUploaded2 ? "Update 2" : "Upload 2";
                    
                    actions.push(
                        <ThemeProvider key="UploadSign2" theme={LIONER_BUTTON_THEME}>
                            <GridActionsCellItem
                                icon={upload2Icon}
                                label={upload2Label}
                                className="textPrimary"
                                onClick={handleUpload2Click(id, templateName, formCode, row)}
                                color="upload"
                            />
                        </ThemeProvider>
                    );
                }

                return actions;
            },
        },
        {
            field: 'download_live',
            type: 'actions',
            headerName: 'Download',
            width: 100,
            cellClassName: 'actions',
            getActions: ({id}) => {
                return [
                    <ThemeProvider key="DownloadFile" theme={LIONER_BUTTON_THEME}>
                        <GridActionsCellItem
                            icon={<FileDownloadIcon sx={{fontSize: 25}}/>}
                            label="Download"
                            className="textPrimary"
                            onClick={handleDownloadClick(id)}
                            // CHANGED: Use a standard MUI color like "primary"
                            color="primary" 
                        />
                    </ThemeProvider>
                ]
            },
        },
        {
            field: 'download_flat', // Unique field name
            type: 'actions',
            headerName: (
                <div style={{ lineHeight: '1.2' }}>
                    Download
                    <br />
                    without signature
                </div>
            ),
            width: 100,
            cellClassName: 'actionsFlatDownload',
            getActions: ({id}) => {
                return [
                    <ThemeProvider key="DownloadFlatFile" theme={LIONER_BUTTON_THEME}>
                        <GridActionsCellItem
                            icon={<FileDownloadIcon sx={{fontSize: 25}}/>} 
                            label="Download flat"
                            className="textPrimary"
                            onClick={handleFlatDownloadClick(id)}
                            color="default" 
                        />
                    </ThemeProvider>
                ]
            },
        },
        {
            id: 'createDate',
            field: 'createDate',
            headerName: 'Create Datetime',
            flex: 1,
            sortComparator: dateComparator,
            renderCell: (params) => (
                <div>
                    {getDateString(params.row.created, 'dd/MM/yyyy HH:mm:ss')}
                </div>
            ),
        },
        {
            id: 'version',
            field: 'version',
            headerName: 'Version',
            flex: 0.5,
            renderCell: (params) => {
                return (
                    <div style={{display: 'flex', alignItems: 'center', justifyContent: 'center', whiteSpace: 'normal', wordBreak: 'break-word'}}>
                        {params.value}
                    </div>
                );
            }
        },
        {
            id: 'modified',
            field: 'modified',
            headerName: 'Modified Date',
            flex: 1,
            sortComparator: dateComparator,
            renderCell: (params) => (
                <div>
                    {getDateString(params.row.modified, 'dd/MM/yyyy HH:mm:ss')}
                </div>
            ),
        },
    ];

    return (
        <div>
            <DataGrid
                rows={rows}
                columns={columns}
                // Increased height to accommodate the multi-line header
                columnHeaderHeight={70}
                editMode="row"
                rowModesModel={rowModesModel}
                getRowHeight={() => 'auto'}
                paginationModel={paginationModel}
                onPaginationModelChange={setPaginationModel}
                slots={{
                    noRowsOverlay: () => (
                        CustomNoRowsOverlay()
                    )
                }}
                pageSizeOptions={[10]}
                autoHeight
            />

            {/* The Upload Dialog Box */}
            <Dialog
                open={isDialogOpen}
                onClose={handleCloseDialog}
                fullWidth
                maxWidth="sm"
                // Prevent closing when upload is active
                disableEscapeKeyDown={isUploading}
                TransitionProps={{ onExited: handleCloseDialog }}
            >
                <DialogTitle>
                    {currentUploadLabel != null ? currentUploadLabel : getUploadDialogTitle(currentUploadRow.formCode, currentUploadRow.refType)}
                </DialogTitle>
                <DialogContent dividers>
                    <Box sx={{ mt: 2, textAlign: 'center' }}>
                        {/* Button to trigger file selection */}
                        <Button
                            variant="contained"
                            color="primary"
                            startIcon={isUploading ? <CircularProgress size={20} color="inherit" /> : <UploadFileIcon />}
                            onClick={handleChooseFile}
                            disabled={isUploading}
                        >
                            {isUploading ? 'Uploading...' : 'Choose PDF File'}
                        </Button>

                        {/* Hidden File Input */}
                        <input
                            ref={fileInputRef}
                            type="file"
                            accept="application/pdf"
                            onChange={handleFileChange}
                            style={{ display: 'none' }}
                            disabled={isUploading}
                        />

                        {/* Display the selected file name if a file is chosen */}
                        {fileInputRef.current?.files[0] && (
                            <Typography variant="body2" sx={{ mt: 1 }}>
                                Selected: **{fileInputRef.current.files[0].name}**
                            </Typography>
                        )}
                    </Box>

                </DialogContent>
                <DialogActions>
                    <Button onClick={handleCloseDialog} color="inherit" disabled={isUploading}>
                        Cancel
                    </Button>
                </DialogActions>
            </Dialog>
        </div>
    );
}