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

const Enroll = () => {

    const BASE_URL = process.env.REACT_APP_BASE_URL
    const API_KEY = process.env.REACT_APP_API_KEY

    const fileTypes = ["JPG", "JPEG", "PNG"];
    const [file, setFile] = useState(null);

    const [errorMessage, setErrorMessage] = useState('');
    const [selectedImageName, setSelectedImageName] = useState('');
    const [resultImageLabel, setresultImageLabel] = useState("");
    const fileInputRef = useRef(null);
    const [showResult, setShowResult] = useState(false);
    const [applicationId, setApplicationId] = useState('');
    const [applicationIds, setApplicationIds] = useState([]);
    const [selectedQuota, setSelectedQuota] = useState(0);
    const [subjectId, setSubjectId] = useState('');
    const [subjectIds, setSubjectIds] = useState([]);
    const [imageUrl, setImageUrl] = useState('');
    const [isLoading, setIsLoading] = useState(false);

    const [applicationError, setApplicationError] = useState('');
    const [subjectError, setSubjectError] = useState('');
    const [imageError, setImageError] = useState('');
    const [subjectAvailabilityMessage, setSubjectAvailabilityMessage] = useState(''); // Message for subject availability

    const [inputValueApplication, setInputValueApplication] = useState(''); // Controlled input value for Application ID
    const [options, setOptions] = useState([]);    
    const [isMobile, setIsMobile] = useState(false);
    const [isServer, setIsServer] = useState(true);

    useEffect(() => {
        const fetchApplicationIds = async () => {
            try {
                setIsLoading(true);
                const response = await fetch(`${BASE_URL}/application/list`, {
                    method: 'GET',
                    headers: {
                        'accept': 'application/json',
                        'x-api-key': API_KEY,
                    },
                });
        
                if (!response.ok) {
                    throw new Error('Failed to fetch application IDs');
                }
        
                const data = await response.json();
                console.log('Response Data:', data);
        
                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 })));

        const handleResize = () => {
            setIsMobile(window.innerWidth <= 768); // Deteksi apakah layar kecil (mobile)
        };

        window.addEventListener('resize', handleResize);
        handleResize(); // Initial check

        return () => window.removeEventListener('resize', handleResize);

    }, [subjectIds]);
    
    const handleApplicationChange = async (selectedOption) => {
        const selectedId = selectedOption.value;
        const selectedApp = applicationIds.find(app => app.id === parseInt(selectedId));

        if (!selectedOption) {
            console.error("Selected option is undefined");
            return;
        }
        if (selectedApp) {
            setSelectedQuota(selectedApp.quota);
        }

        setApplicationId(selectedId);

        // Fetch subjects related to the application
        await fetchSubjectIds(selectedId);
    };

    const handleInputChangeApplication = (newInputValue) => {
        // Limit input to 15 characters for Application ID
        if (newInputValue.length <= 15) {
            setInputValueApplication(newInputValue);
        }
    };
    
    
    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();
            console.log("Fetched Subject IDs:", data); // Log data fetched from API
    
            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);
        }
    };
    
    const handleImageUpload = (file) => {
      // Ensure the file is not undefined or null before accessing its properties
      if (file && file.name) {
          const fileExtension = file.name.split('.').pop().toUpperCase();
          if (fileTypes.includes(fileExtension)) {
              setSelectedImageName(file.name);
              setFile(file);
              setImageError(''); // Clear any previous errors
          } else {
              alert('Image format is not supported');
              setImageError('Image format is not supported');
              setFile(null);
          }
      } else {
          console.error('No file selected or invalid file object.');
      }
    };
  

    const handleImageCancel = () => {
        setSelectedImageName('');
        setFile(null);
        if (fileInputRef.current) {
            fileInputRef.current.value = '';
        }
    };

    const handleEnrollClick = async () => {
        let hasError = false;
    
        // Validate inputs and set corresponding errors
        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.' : '',
        };
    
        // Update state with errors
        if (validationErrors.imageError) {
            setImageError(validationErrors.imageError);
            hasError = true;
        } else {
            setImageError(''); // Clear error if valid
        }
    
        if (validationErrors.applicationError) {
            setApplicationError(validationErrors.applicationError);
            hasError = true;
        } else {
            setApplicationError(''); // Clear error if valid
        }
    
        if (validationErrors.subjectError) {
            setSubjectError(validationErrors.subjectError);
            hasError = true;
        } else {
            setSubjectError(''); // Clear error if valid
        }
    
        // If there are errors, return early
        if (hasError) return;
    
        if (!file) {
            setImageError('No file selected. Please upload a valid image file.');
            return;
        }
    
        const formData = new FormData();
        formData.append('application_id', String(applicationId));
        formData.append('subject_id', subjectId);
        formData.append('file', file);
    
        console.log('Inputs:', {
            applicationId,
            subjectId,
            file: file.name,
        });
    
        setIsLoading(true);
        setErrorMessage(''); // Clear previous error message
    
        try {
            const response = await fetch(`${BASE_URL}/face_recognition/enroll`, {
                method: 'POST',
                body: formData,
                headers: {
                    'accept': 'application/json',
                    'x-api-key': `${API_KEY}`,
                }
            });
    
            if (!response.ok) {
                const errorDetails = await response.json();
                console.error('Response error details:', errorDetails);
                if (errorDetails.detail && errorDetails.detail.includes('Subject ID')) {
                    setSubjectError(errorDetails.detail);
                } else {
                    setErrorMessage(errorDetails.detail || 'Failed to enroll, please try again');
                }
                return;
            }
    
            const result = await response.json();
            console.log('Enrollment response:', result);
    
            // Update quota based on the response data
            if (result.details && result.details.data && result.details.data.quota !== undefined) {
                const updatedQuota = result.details.data.quota;
                setSelectedQuota(updatedQuota); // Update the state with the new quota
            }
    
            if (result.details && result.details.data && result.details.data.image_url) {
                const imageFileName = result.details.data.image_url.split('/').pop();
                console.log('Image URL:', result.details.data.image_url);
                await fetchImage(imageFileName);
    
                // Set resultImageLabel after successful enrollment
                setresultImageLabel(selectedImageName);  // Set resultImageLabel after success
            } else {
                console.error('Image URL not found in response:', result);
                setErrorMessage('Image URL not found in response. Please try again.');
            }
    
            setShowResult(true);
            console.log('Enrollment successful:', result);
        } catch (error) {
            console.error('Error during API call:', error);
            setErrorMessage('An unexpected error occurred. Please try again.');
        } finally {
            setIsLoading(false);
        }
    };    

    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) {
                const errorDetails = await response.json();
                console.error('Image fetch error details:', errorDetails);
                setErrorMessage('Failed to fetch image, please try again.');
                return;
            }

            const imageBlob = await response.blob();
            const imageData = URL.createObjectURL(imageBlob);
            console.log('Fetched image URL:', imageData);

            setImageUrl(imageData);
        } catch (error) {
            console.error('Error fetching image:', error);
            setErrorMessage(error.message);
        } finally {
            setIsLoading(false);
        }
    };
    
    const CustomLabel = ({ overRide, children, ...props }) => {
        // We intentionally don't pass `overRide` to the label
        return (
            <label {...props}>
                {children}
            </label>
        );
    };
    
    const applicationOptions = applicationIds.map(app => ({
        value: app.id,
        label: app.name
    }));

    const handleSubjectIdChange = async (e) => {
        const id = e.target.value;
        setSubjectId(id);
    
        console.log("Current Subject ID Input:", id); // Debugging: Log input
    
        if (id) {
            const exists = subjectIds.includes(id);
            console.log("Subject IDs:", subjectIds); // Debugging: Log existing Subject IDs
    
            if (exists) {
                setSubjectAvailabilityMessage('Subject already exists.'); // Error message
                setSubjectError(''); // Clear any subject error
            } else {
                setSubjectAvailabilityMessage('This subject ID is available.'); // Success message
                setSubjectError('');
            }
        } else {
            setSubjectAvailabilityMessage(''); // Clear message if input is empty
        }
    };     

    // Fungsi untuk mengonversi ukuran file dari byte ke KB/MB
    const formatFileSize = (sizeInBytes) => {
        if (sizeInBytes < 1024) {
            return `${sizeInBytes} bytes`; // Jika ukuran lebih kecil dari 1 KB
        } else if (sizeInBytes < 1048576) {
            return `${(sizeInBytes / 1024).toFixed(2)} KB`; // Jika ukuran lebih kecil dari 1 MB
        } else {
            return `${(sizeInBytes / 1048576).toFixed(2)} MB`; // Jika ukuran lebih besar dari 1 MB
        }
    };

    const styles = {
        formGroup: {
            marginTop: '-45px',
        },
        selectWrapper: {
            position: 'relative',
            marginTop: '0',
        },
        select: {
            width: '100%',
            paddingRight: '30px',
        },
        chevronIcon: {
            position: 'absolute',
            right: '10px',
            top: '50%',
            transform: 'translateY(-50%)',
            pointerEvents: 'none',
        },
        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',
        },
        uploadAreaMobile: {
            backgroundColor: '#e6f2ff',
            height: '50svh',
            cursor: 'pointer',
            marginTop: '1rem',
            paddingTop: '18px',
            display: 'flex',
            flexDirection: 'column',
            justifyContent: 'center',
            alignItems: 'center',
            border: '1px solid #ced4da',
            borderRadius: '0.25rem',
            padding: '20px',
        },
        uploadIcon: {
            fontSize: '40px',
            color: '#0542cc',
            marginBottom: '7px',
        },
        uploadText: {
            color: '#1f2d3d',
            fontWeight: '400',
            fontSize: '16px',
            lineHeight: '13px',
        },
        wrapper: {
            border: '1px solid #ddd',
            borderRadius: '6px',
            padding: '18px 10px 0 8px',
            height: '13svh',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'space-between',
            backgroundColor: '#f9f9f9',
            overflow: 'hidden',
        },
        fileWrapper: {
            display: 'flex',
            alignItems: 'center',
            flex: '1',
        },
        textContainer: {
            flex: '1',
            fontSize: '16px',
            marginLeft: '6px',
            overflow: 'hidden',
            whiteSpace: 'nowrap',
            textOverflow: 'ellipsis',
            marginTop: '1rem',
        },
        fileSize: {
            fontSize: '12px',
            color: '#555',
            marginBottom: '2rem',
        },
        closeButtonContainer: {
            display: 'flex',
            alignItems: 'center',
            marginLeft: 'auto',
        },
        closeButton: {
            background: 'transparent',
            border: 'none',
            cursor: 'pointer',
            padding: '0',
        },
        imageIcon: {
            color: '#0542cc',
            fontSize: '18px',
            marginRight: '6px',
        },
        closeIcon: {
            color: 'red',
            fontSize: '18px',
        },
        submitButton: {
            marginLeft: 'auto',
            marginTop: '4rem',
            textAlign: 'start',
            position: 'relative',
            zIndex: 1,
        },
        uploadError: {
            color: 'red',
            fontSize: '12px',
            marginTop: '5px',
        },
        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',
        },
        imageStyle: {
            width: '300px',
            height: '300px',
            borderRadius: '5px',
        },
        imageStyleMobile: {
            width: '100%',
            height: 'auto',
            borderRadius: '5px',
        },
        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',
        },
        uploadedFileWrapper: {
            backgroundColor: '#fff',
            border: '0.2px solid gray',
            padding: '15px 0 0 17px',
            borderRadius: '5px',
            display: 'flex',
            alignItems: 'center',
            gap: '10px',
            justifyContent: 'space-between',
        },
        uploadedFileInfo: {
            marginRight: '18rem',
            marginTop: '0.2rem',
        },
        uploadedFileText: {
            fontSize: '16px',
            color: '#1f2d3d',
        },
        customLabel: {
            fontWeight: 600,
            fontSize: '14px',
            color: '#212529',
        },
        responsiveImageStyle: {
            width: '100%',
            maxHeight: '250px',
            objectFit: 'cover',
            marginTop: '20px',
        },
        responsiveResultContainer: {
            padding: '1rem',
            border: '1px solid #ccc',
            borderRadius: '8px',
            marginTop: '20px',
        },
        responsiveImageContainer: {
            marginTop: '20px',
            textAlign: 'center',
        },
        responsiveSubmitButton: {
            marginTop: '1rem',
        },
        responsiveLoadingOverlay: {
            position: 'absolute',
            top: '0',
            left: '0',
            width: '100%',
            height: '100%',
            backgroundColor: 'rgba(0,0,0,0.5)',
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
            zIndex: '10',
        },
        responsiveSpinner: {
            border: '4px solid #f3f3f3',
            borderTop: '4px solid #3498db',
            borderRadius: '50%',
            width: '50px',
            height: '50px',
            animation: 'spin 2s linear infinite',
        },
        responsiveLoadingText: {
            color: 'white',
            marginTop: '10px',
        },
    };

    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>
        );
    }    
    
    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>
    
            <div className='col-md-6'>
                <div className="row form-group mt-4">
                    <CustomLabel htmlFor="uploadPhoto" style={styles.customLabel}>
                        Upload Face Photo
                    </CustomLabel>
                    <FileUploader
                        handleChange={handleImageUpload}
                        name="file"
                        types={fileTypes}
                        multiple={false}
                        onDrop={(files) => {
                            if (files && files[0]) {
                                handleImageUpload(files[0]);
                            }
                        }}
                        children={
                            <div style={isMobile ? styles.uploadAreaMobile : styles.uploadArea}>
                                <i className="fas fa-cloud-upload-alt" style={styles.uploadIcon}></i>
                                <p style={styles.uploadText}>Drag and Drop Here</p>
                                <p>Or</p>
                                <a href="#" onClick={() => fileInputRef.current.click()}>Browse</a>
                                <p className="text-muted">Recommended size: 300x300 (Max File Size: 2MB)</p>
                                <p className="text-muted">Supported file types: JPG, JPEG</p>
                            </div>
                        }
                    />
                    <input
                        type="file"
                        id="fileUpload"
                        ref={fileInputRef}
                        style={{ display: 'none' }}
                        accept="image/jpeg, image/jpg"
                        onChange={e => handleImageUpload(e.target.files[0])}
                    />
                    {imageError && <small style={{ color: 'red' }}>{imageError}</small>}
                </div>
            </div>
    
            {selectedImageName && (
                <div className="mt-3">
                    <p><strong>File:</strong> {selectedImageName}</p>
                    {file && (
                        <p style={styles.fileSize}>
                            Size: {formatFileSize(file.size)}
                        </p>
                    )}
                    <button className="btn btn-danger" onClick={handleImageCancel}>
                        <FontAwesomeIcon icon={faTimes} className="me-2" />Cancel
                    </button>
                </div>
            )}
            {errorMessage && <small style={styles.uploadError}>{errorMessage}</small>}
    
            <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={isMobile ? styles.imageStyleMobile : styles.imageStyle}
                            />
                            <p style={isMobile ? { ...styles.imageDetails, fontSize: '14px' } : styles.imageDetails}>
                                {resultImageLabel}  {/* Display resultImageLabel instead of selectedImageName */}
                            </p>
                        </div>
                    </div>
                </div>
            )}
        </>
    );
    
}

export default Enroll;



