import React, { useState, useRef, useEffect } from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faTimes, faCloudUploadAlt  } from '@fortawesome/free-solid-svg-icons';
import Select from 'react-select'
import { ServerDownAnimation } from '../../../../assets/images';

const Enroll = () => {

    // Environment variables
    const BASE_URL = process.env.REACT_APP_BASE_URL;
    const API_KEY = process.env.REACT_APP_API_KEY;

    // State hooks
    const [file, setFile] = useState(null);
    const [imageError, setImageError] = useState('');
    const [selectedImageName, setSelectedImageName] = useState('');
    const [subjectId, setSubjectId] = useState('');
    const [subjectIds, setSubjectIds] = useState([]);
    const [imageUrl, setImageUrl] = useState('');
    const [isLoading, setIsLoading] = useState(false);
    const [applicationId, setApplicationId] = useState('');
    const [applicationIds, setApplicationIds] = useState([]);
    const [selectedQuota, setSelectedQuota] = useState(0);
    const [showResult, setShowResult] = useState(false);
    const [resultImageLabel, setresultImageLabel] = useState("");

    // Error messages
    const [errorMessage, setErrorMessage] = useState('');
    const [applicationError, setApplicationError] = useState('');
    const [subjectError, setSubjectError] = useState('');
    const [subjectAvailabilityMessage, setSubjectAvailabilityMessage] = useState('');

    // Controlled inputs
    const [inputValueApplication, setInputValueApplication] = useState('');
    const [options, setOptions] = useState([]);

    // Mobile check
    const [isMobile, setIsMobile] = useState(false);

    // Server check
    const [isServer, setIsServer] = useState(true);

    // Validation errors
    const [validationErrors, setValidationErrors] = useState({
        applicationId: '',
        file: ''
    });

    // Application Options
    const applicationOptions = applicationIds.map(app => ({
        value: app.id,
        label: app.name
    }));

    const fileInputRef = useRef(null);

    // Fetch application IDs and subject options on component mount
    useEffect(() => {
        const fetchApplicationIds = async () => {
            setIsLoading(true);
            try {
                const response = await fetch(`${BASE_URL}/application/list`, {
                    method: 'GET',
                    headers: { 'accept': 'application/json', 'x-api-key': API_KEY },
                });
                const data = await response.json();

                if (data.status_code === 200) {
                    setApplicationIds(data.details.data);
                    setIsServer(true);
                } else {
                    setIsServer(false);
                    throw new Error(data.details.message || 'Failed to fetch application IDs');
                }
            } catch (error) {
                setErrorMessage(error.message || 'Error fetching application IDs');
                setIsServer(false);
            } finally {
                setIsLoading(false);
            }
        };

        fetchApplicationIds();
        setOptions(subjectIds.map(id => ({ value: id, label: id })));

        // Handle mobile responsiveness
        const handleResize = () => {
            setIsMobile(window.innerWidth <= 768);
        };
        window.addEventListener('resize', handleResize);
        handleResize(); // Initial check

        return () => window.removeEventListener('resize', handleResize);
    }, [subjectIds]);

    // Handle application change
    const handleApplicationChange = async (selectedOption) => {
        setApplicationError('');
        const selectedId = selectedOption.value;
        const selectedApp = applicationIds.find(app => app.id === parseInt(selectedId));

        if (selectedApp) {
            setSelectedQuota(selectedApp.quota);
        }
        setApplicationId(selectedId);
        await fetchSubjectIds(selectedId);
    };

    // Handle input change for Application ID
    const handleInputChangeApplication = (newInputValue) => {
        if (newInputValue.length <= 15) {
            setInputValueApplication(newInputValue);
        }
    };

    // Fetch subject IDs based on application ID
    const fetchSubjectIds = async (appId) => {
        setIsLoading(true);
        try {
            const response = await fetch(`${BASE_URL}/trx_face/list/subject?application_id=${appId}&search=${subjectId}&limit=99`, {
                method: 'GET',
                headers: { 'accept': 'application/json', 'x-api-key': API_KEY },
            });
            const data = await response.json();

            if (data.status_code === 200) {
                setSubjectIds(data.details.data);
            } else {
                console.error('Failed to fetch subject IDs:', data.details.message);
            }
        } catch (error) {
            console.error('Error fetching subject IDs:', error);
        } finally {
            setIsLoading(false);
        }
    };

    // Handle Drop File Image
    const handleFileDrop = (files) => {
        if (files && files[0]) {
            handleImageUpload(files[0]);
        } else {
            console.error('No valid files dropped');
        }
    };

    // Handle image file upload
    const handleImageUpload = (file) => {
        setShowResult(false);
        if (!file) {
            setImageError('Please select a file');
            return;
        }

        const maxSize = 2 * 1024 * 1024; // 2MB
        if (file.size > maxSize) {
            setImageError('File size exceeds 2MB limit');
            return;
        }

        const fileExtension = file.name.split('.').pop().toLowerCase();
        const validExtensions = ['jpg', 'jpeg'];
        const validMimeTypes = ['image/jpeg', 'image/jpg'];

        if (!validExtensions.includes(fileExtension) || !validMimeTypes.includes(file.type)) {
            setImageError('Only JPG/JPEG files are allowed');
            return;
        }

        const previewUrl = URL.createObjectURL(file);
        const img = new Image();
        img.onload = () => {
            setFile(file);
            setSelectedImageName(file.name);
            setImageUrl(previewUrl);
            setImageError('');
        };

        img.onerror = () => {
            URL.revokeObjectURL(previewUrl);
            setImageError('Invalid image file');
        };

        img.src = previewUrl;
    };

    // Cancel image upload
    const handleImageCancel = () => {
        setSelectedImageName('');
        setFile(null);
        if (fileInputRef.current) fileInputRef.current.value = '';
    };
    
    // Validation function
    const validateForm = () => {
        let isValid = true;
        const validationErrors = {
            imageError: !selectedImageName ? 'Please upload a face photo before enrolling.' : '',
            applicationError: !applicationId ? 'Please select an Application ID before enrolling.' : '',
            subjectError: !subjectId ? 'Please enter a Subject ID before enrolling.' : '',
        };

        if (validationErrors.imageError) {
            setImageError(validationErrors.imageError);
            isValid = false;
        }

        if (validationErrors.applicationError) {
            setApplicationError(validationErrors.applicationError);
            isValid = false;
        }

        if (validationErrors.subjectError) {
            setSubjectError(validationErrors.subjectError);
            isValid = false;
        }

        if (!file) {
            setImageError('No file selected. Please upload a valid image file.');
            isValid = false;
        }

        return isValid;
    };

    // HandleEnrollClick function
    const handleEnrollClick = () => {
        if (!validateForm()) {
            return;
        }

        setIsLoading(true);
        setErrorMessage('');

        const formData = new FormData();
        formData.append('application_id', String(applicationId));
        formData.append('subject_id', subjectId);
        formData.append('file', file);

        fetch(`${BASE_URL}/face_recognition/enroll`, {
            method: 'POST',
            headers: {
                'accept': 'application/json',
                'x-api-key': API_KEY,
            },
            body: formData,
        })
        .then(response => {
            if (!response.ok) {
                return response.json().then(errorData => {
                    throw new Error(errorData.detail || 'Failed to enroll, please try again');
                });
            }
            return response.json();
        })
        .then(result => {
            console.log('📡 API Response:', result);

            if (result.details.data.quota !== undefined) {
                setSelectedQuota(result.details.data.quota);
            }

            setShowResult(true);
            setErrorMessage('');
            setSelectedImageName('');
            setresultImageLabel(selectedImageName);

            if (result.details.data.image_url) {
                const imageFileName = result.details.data.image_url.split('/').pop();
                return fetchImage(imageFileName);
            }
        })
        .catch(error => {
            console.error('🔥 Request Failed:', error);
            setErrorMessage(error.message);
            setShowResult(false);
        })
        .finally(() => {
            setIsLoading(false);
        });
    };

    // Fetch image preview
    const fetchImage = async (imageFileName) => {
        setIsLoading(true);
        try {
            const response = await fetch(`${BASE_URL}/preview/image/${imageFileName}`, {
                method: 'GET',
                headers: { 'accept': 'application/json', 'x-api-key': API_KEY },
            });

            if (!response.ok) {
                setErrorMessage('Failed to fetch image, please try again.');
                return;
            }

            const imageBlob = await response.blob();
            setImageUrl(URL.createObjectURL(imageBlob));
        } catch (error) {
            setErrorMessage(error.message);
        } finally {
            setIsLoading(false);
        }
    };

    // Handle subject ID change
    const handleSubjectIdChange = (e) => {
        const id = e.target.value;
        setSubjectId(id);

        if (id) {
            const exists = subjectIds.includes(id);
            if (exists) {
                setSubjectAvailabilityMessage('Subject already exists.');
                setSubjectError('');
            } else {
                setSubjectAvailabilityMessage('This subject ID is available.');
                setSubjectError('');
            }
        } else {
            setSubjectAvailabilityMessage('');
        }
    };

    // handle Labeling
    const CustomLabel = ({ overRide, children, ...props }) => {
        // We intentionally don't pass `overRide` to the label
        return (
            <label {...props}>
                {children}
            </label>
        );
    };

    // Handle Server Down
    if (!isServer) {
        return (
            <div style={{ textAlign: 'center', marginTop: '50px' }}>
                <img 
                    src={ServerDownAnimation} 
                    alt="Server Down Animation" 
                    style={{ width: '18rem', height: '18rem', marginBottom: '20px' }} 
                />
                <h2 style={{ color: 'red' }}>Server tidak dapat diakses</h2>
                <p>{errorMessage || 'Silakan periksa koneksi internet Anda atau coba lagi nanti.'}</p>
                <button 
                    onClick={() => window.location.reload()} 
                    style={{
                        padding: '10px 20px',
                        backgroundColor: '#0542cc',
                        color: '#fff',
                        border: 'none',
                        borderRadius: '5px',
                        cursor: 'pointer'
                    }}>
                    Coba Lagi
                </button>
            </div>
        );
    }  
   
    const styles = {
        remainingQuota: {
            display: 'flex',
            flexDirection: 'row',
            alignItems: 'center',
            marginTop: '4px',
        },
        quotaText: {
            fontSize: '40px',
            color: '#0542cc',
            fontWeight: '600',
        },
        timesText: {
            marginLeft: '8px',
            verticalAlign: 'super',
            fontSize: '20px',
        },
        uploadArea: {
            backgroundColor: '#e6f2ff',
            height: '250px',
            cursor: 'pointer',
            marginTop: '1rem',
            paddingTop: '22px',
            display: 'flex',
            flexDirection: 'column',
            justifyContent: 'center',
            alignItems: 'center',
            border: '1px solid #ced4da',
            borderRadius: '0.25rem',
        },
        uploadIcon: {
            fontSize: '40px',
            color: '#0542cc',
            marginBottom: '7px',
        },
        uploadText: {
            color: '#1f2d3d',
            fontWeight: '400',
            fontSize: '16px',
            lineHeight: '13px',
        },
        customLabel: {
            fontWeight: 600,
            fontSize: '14px',
            color: '#212529',
        },
        submitButton: {
            marginLeft: 'auto',
            marginTop: '4rem',
            textAlign: 'start',
            position: 'relative',
            zIndex: 1,
        },
        errorText: {
            color: '#dc3545',
            fontSize: '12px',
            marginTop: '5px',
            display: 'block'
        },
        containerResultStyle: {
            padding: '20px',
            border: '1px solid #0053b3',
            borderRadius: '5px',
            width: '100%',
            margin: '20px auto',
        },
        resultContainer: {
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'flex-start',
            flexDirection: isMobile ? 'column' : 'row',
            width: '100%',
        },
        resultsTable: {
            width: '60%',
            borderCollapse: 'collapse',
        },
        resultsTableMobile: {
            width: '100%',
            borderCollapse: 'collapse',
        },
        resultsCell: {
            padding: '8px',
            width: '30%',
            fontSize: isMobile ? '14px' : '16px',
        },
        resultsValueCell: {
            padding: '8px',
            width: '70%',
            fontSize: isMobile ? '14px' : '16px',
            color: 'red',
        },
        resultsTrueValue: {
            color: 'inherit',
        },
        imageContainer: {
            display: 'flex',
            flexDirection: 'column',
            alignItems: isMobile ? 'center' : 'flex-start',
            width: '100%',
            marginTop: isMobile ? '10px' : '0',
        },
        imageDetails: {
            marginTop: '10px',
            fontSize: isMobile ? '14px' : '16px',
            color: '#1f2d3d',
        },
        loadingOverlay: {
            position: 'fixed',
            top: 0,
            left: 0,
            right: 0,
            bottom: 0,
            backgroundColor: 'rgba(0, 0, 0, 0.2)',
            display: 'flex',
            flexDirection: 'column',
            justifyContent: 'center',
            alignItems: 'center',
            zIndex: 1000,
        },
        spinner: {
            border: '4px solid rgba(0, 0, 0, 0.1)',
            borderLeftColor: '#0542cc',
            borderRadius: '50%',
            width: '90px',
            height: '90px',
            animation: 'spin 1s ease-in-out infinite',
        },
        loadingText: {
            marginTop: '10px',
            fontSize: '1.2rem',
            color: '#fff',
            textAlign: 'center',
        }
    };
    
    return (
        <>
            <style>
                {`
                    @keyframes spin {
                        0% { transform: rotate(0deg); }
                        100% { transform: rotate(360deg); }
                    }
                    .select-wrapper {
                        max-height: 200px;
                        overflow-y: auto;
                    }
                `}
            </style>
    
            {isLoading && (
                <div style={styles.loadingOverlay}>
                    <div style={styles.spinner}></div>
                    <p style={styles.loadingText}>Loading...</p>
                </div>
            )}
    
            <div className="form-group row align-items-center">
                <div className="col-md-6">
                    <div className="select-wrapper">
                        <Select
                            id="applicationId"
                            value={applicationOptions.find(option => option.value === applicationId)}
                            onChange={handleApplicationChange}
                            options={applicationOptions}
                            placeholder="Select Application ID"
                            isSearchable
                            menuPortalTarget={document.body}
                            menuPlacement="auto"
                            inputValue={inputValueApplication}
                            onInputChange={handleInputChangeApplication}
                        />
                    </div>
                    {applicationError && <small style={{ color: 'red' }}>{applicationError}</small>}
                </div>

                <div className="col-md-6">
                    <p className="text-secondary" style={{ fontSize: '16px', fontWeight: '400', margin: '0', marginTop: '8px' }}>
                        Remaining Quota
                    </p>
                    <div style={styles.remainingQuota}>
                        <span style={styles.quotaText}>{selectedQuota}</span>
                        <span style={styles.timesText}>(times)</span>
                    </div>
                </div>
            </div>

    
            <div className="form-group row align-items-center">
                <div className="col-md-6">
                    <input
                        type="text"
                        id="subjectId"
                        className="form-control"
                        placeholder="Enter Subject ID"
                        value={subjectId}
                        onChange={handleSubjectIdChange}
                        onFocus={() => fetchSubjectIds(applicationId)}
                        maxLength={15}
                    />
                    {subjectError && <small style={{ color: 'red' }}>{subjectError}</small>}
                    {subjectAvailabilityMessage && (
                        <small style={{ color: subjectAvailabilityMessage.includes('available') ? 'green' : 'red' }}>
                            {subjectAvailabilityMessage}
                        </small>
                    )}
                </div>
            </div>
    
            {/* Image Upload */}
            <div className="col-md-6">
                <div className="form-group mt-4">
                    <CustomLabel htmlFor="imageInput" style={styles.customLabel}>
                        Upload Face Photo
                    </CustomLabel>
                    <div style={styles.uploadWrapper}>
                        {/* Drag and Drop File Input */}
                        <div
                            style={styles.uploadArea}
                            onDrop={(e) => {
                                e.preventDefault();
                                handleFileDrop(e.dataTransfer.files);
                            }}
                            onDragOver={(e) => e.preventDefault()}
                        >
                            <FontAwesomeIcon icon={faCloudUploadAlt} style={styles.uploadIcon} />
                            <p style={styles.uploadText}>Drag and Drop Here</p>
                            <p>Or</p>
                            <a href="#" onClick={() => fileInputRef.current.click()} style={styles.browseLink}>Browse</a>
                            <p className="text-muted" style={styles.uploadText}>Recommended size: 320x200 (Max File Size: 2MB)</p>
                            <p className="text-muted" style={styles.uploadText}>Supported file types: JPG, JPEG</p>
                        </div>

                        {/* File Input */}
                        <input
                            ref={fileInputRef}
                            type="file"
                            id="imageInput"
                            className="form-control"
                            style={{ display: 'none' }}
                            accept="image/jpeg, image/jpg"
                            onChange={(e) => handleImageUpload(e.target.files[0])}
                        />

                        {selectedImageName && (
                            <div className="mt-3">
                                <p><strong>File:</strong> {selectedImageName}</p>
                                <button className="btn btn-danger" onClick={handleImageCancel}>
                                    <FontAwesomeIcon icon={faTimes} className="me-2" />Cancel
                                </button>
                            </div>
                        )}
                        {/* Display validation errors */}
                        {validationErrors.file && <p style={styles.errorText}>{validationErrors.file}</p>}
                        {imageError && <p style={styles.errorText}>{imageError}</p>}
                    </div>
                </div>
            </div>

            {errorMessage && (
                <div style={styles.errorContainer}>
                    <p style={styles.errorText}>{errorMessage}</p>
                </div>
            )}
    
            <div style={styles.submitButton}>
                <button onClick={handleEnrollClick} className="btn d-flex justify-content-center align-items-center me-2" style={{ backgroundColor: '#0542CC' }}>
                    <p className="text-white mb-0">Enroll Now</p>
                </button>
            </div>
    
            {showResult && (
                <div style={styles.containerResultStyle}>
                    <h1 style={{ color: '#0542cc', fontSize: isMobile ? '1.5rem' : '2rem' }}>Results</h1>
                    <div style={styles.resultContainer}>
                        <table style={isMobile ? styles.resultsTableMobile : styles.resultsTable}>
                            <tbody>
                                <tr>
                                    <td style={{ ...styles.resultsCell, width: '40%' }}>Similarity</td>
                                    <td style={{ ...styles.resultsValueCell, ...styles.resultsTrueValue }}>True</td>
                                </tr>
                            </tbody>
                        </table>
                        <div style={styles.imageContainer}>
                            <img
                                src={imageUrl || "path-to-your-image"}
                                alt="Contoh Foto"
                                style={{
                                    maxWidth: '100%',
                                    height: 'auto',
                                    objectFit: 'contain',
                                    borderRadius: '5px'
                                }}
                            />
                            <p style={isMobile ? { ...styles.imageDetails, fontSize: '14px' } : styles.imageDetails}>
                                {resultImageLabel}
                            </p>
                        </div>
                    </div>
                </div>
            )}
        </>
    );
    
}

export default Enroll;