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

const Verify = () => {
  const BASE_URL = process.env.REACT_APP_BASE_URL;
  const API_KEY = process.env.REACT_APP_API_KEY;

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

  const [errorMessage, setErrorMessage] = useState('');
  const [uploadError, setUploadError] = useState('');
  const [applicationError, setApplicationError] = useState('');
  const [subjectError, setSubjectError] = useState('');
  const [thresholdError, setThresholdError] = useState('');
  const [selectedImageName, setSelectedImageName] = useState('');
  const [resultImageLabel, setResultImageLabel] = useState('');
  const inputRef = useRef(null);
  const [showResult, setShowResult] = useState(false);
  const [applicationId, setApplicationId] = useState('');
  const [thresholdId, setThresholdId] = useState('');
  const [selectedQuota, setSelectedQuota] = useState(0);
  const [subjectId, setSubjectId] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [verified, setVerified] = useState(null);
  const [imageUrl, setImageUrl] = useState('');
  const [applicationIds, setApplicationIds] = useState([]);
  const [subjectIds, setSubjectIds] = useState([]);
  const [subjectAvailabilityMessage, setSubjectAvailabilityMessage] = useState(''); // Message for subject availability
  const [inputValueApplication, setInputValueApplication] = useState(''); // Controlled input value for Application ID
  const [isMobile, setIsMobile] = useState(window.innerWidth <= 768);
  const [isServer, setIsServer] = useState(true);
  const [imageError, setImageError] = useState('');

  const thresholdIds = [
    { id: 1, name: 'cosine', displayName: 'Basic' },
    { id: 2, name: 'euclidean', displayName: 'Medium' },
    { id: 3, name: 'euclidean_l2', displayName: 'High' },
  ];

  const [inputValue, setInputValue] = useState('');

  const options = subjectIds.map(id => ({ 
    value: id, 
    label: id 
  }));

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

  const fetchApplicationIds = async () => {
    try {
      const url = `${BASE_URL}/application/list`;
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'accept': 'application/json',
          'x-api-key': `${API_KEY}`,
        },
      });
      const data = await response.json();
      setIsServer(true)
      return data.details.data; // assuming the API returns an array of applications
    } catch (error) {
      console.error('Error fetching application IDs:', error);
      setIsServer(false)
      return [];
    }
  };
  
  // Sample function to fetch Subject IDs based on applicationId
  const fetchSubjectIds = async (appId) => {
    try {
      const response = await fetch(`${BASE_URL}/trx_face/list/subject?application_id=${appId}&limit=99`, {
        method: 'GET',
        headers: {
          'accept': 'application/json',
          'x-api-key': `${API_KEY}`,
        },
      });
      const data = await response.json();
      return data.details.data; // assuming the API returns an array of subjects
    } catch (error) {
      console.error('Error fetching subject IDs:', error);
      return [];
    }
  };

  useEffect(() => {
    const fetchData = async () => {
      setIsLoading(true);
      const data = await fetchApplicationIds();
      setApplicationIds(data);
      setIsLoading(false);
    };

    fetchData();

    const handleResize = () => setIsMobile(window.innerWidth <= 768);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []); // Empty dependency array, so this runs only once when the component mounts

  // Fetch Subject IDs when applicationId changes
  useEffect(() => {
    const fetchSubjects = async () => {
      if (applicationId) {
        setIsLoading(true);
        const subjects = await fetchSubjectIds(applicationId);
        setSubjectIds(subjects);
        setIsLoading(false);
      } else {
        setSubjectIds([]); // Clear subjects if no applicationId is selected
      }
    };

    fetchSubjects();
  }, [applicationId]); // Runs whenever applicationId changes

  // Handler for changing applicationId
  const handleApplicationChange = (selectedOption) => {
    const selectedId = selectedOption.value;
    const selectedApp = applicationIds.find(app => app.id === parseInt(selectedId));

    if (selectedApp) {
      setSelectedQuota(selectedApp.quota);
    } 

    setApplicationId(selectedOption.value); // Update applicationId when user selects a new option
  };


  const handleImageUpload = (file) => {
    if (!file) {
        setImageError('Please select a file');
        return;
    }

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

    // Check file type using both extension and MIME type
    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');
        setFile(null);
        setSelectedImageName('');
        return;
    }

    // Check image dimensions
    const img = new Image();
    const objectUrl = URL.createObjectURL(file);
    
    img.onload = () => {
        URL.revokeObjectURL(objectUrl);
        
        if (img.width > 300 || img.height > 300) {
            setImageError('Image dimensions must not exceed 300x300 pixels');
            setFile(null);
            setSelectedImageName('');
            return;
        }

        // All validations passed
        setSelectedImageName(file.name);
        setFile(file);
        setImageError('');
    };

    img.onerror = () => {
        URL.revokeObjectURL(objectUrl);
        setImageError('Invalid image file');
        setFile(null);
        setSelectedImageName('');
    };

    img.src = objectUrl;
  };
  

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

  const handleCheckClick = async () => {
    // Reset previous error messages
    setErrorMessage('');
    setApplicationError('');
    setSubjectError('');
    setThresholdError('');
    setUploadError('');

    let hasError = false; // Track if any errors occur

    // Validate the applicationId
    if (!applicationId) {
        setApplicationError('Please select an Application ID before enrolling.');
        hasError = true; // Mark that an error occurred
    }

    // Validate the subjectId
    if (!subjectId) {
        setSubjectError('Please enter a Subject ID before enrolling.');
        hasError = true; // Mark that an error occurred
    }

    // Validate thresholdId
    const selectedThreshold = thresholdIds.find(threshold => threshold.name === thresholdId)?.name;
    if (!selectedThreshold) {
        setThresholdError('Invalid threshold selected.');
        hasError = true; // Mark that an error occurred
    }

    // Validate image upload
    if (!selectedImageName) {
        setUploadError('Please upload a face photo before verifying.');
        hasError = true; // Mark that an error occurred
    }

    // If there are any errors, stop the function
    if (hasError) {
        return;
    }

    // Log the input values for debugging
    console.log('Selected Image Name:', selectedImageName);
    console.log('Application ID:', applicationId);
    console.log('Subject ID:', subjectId);
    console.log('Selected Threshold:', selectedThreshold);

    // Prepare FormData for the API request
    const formData = new FormData();
    formData.append('application_id', applicationId);
    formData.append('threshold', selectedThreshold);
    formData.append('subject_id', subjectId);

    if (file) {
        formData.append('file', file, file.name);
    } else {
        setUploadError('Please upload an image file.');
        return;
    }

    setIsLoading(true);

    try {
        const response = await fetch(`${BASE_URL}/face_recognition/verifiy`, {
            method: 'POST',
            headers: {
                'accept': 'application/json',
                'x-api-key': API_KEY,
            },
            body: formData,
        });

        const data = await response.json();

        // Log the response data for debugging
        console.log('API Response Data:', data);

        if (response.ok) {
            if (data.details && data.details.data && data.details.data.result) {
                const result = data.details.data.result;

                // Update selectedQuota with the quota received from API
                setSelectedQuota(result.quota);

                if (result.image_url) {
                    const imageFileName = result.image_url.split('/').pop();
                    await fetchImage(imageFileName);
                }

                setShowResult(true);
                setVerified(result.verified);
                setResultImageLabel(selectedImageName);
            }
        } else {
            const errorMessage = data.message || data.detail || data.details?.message || 'An unknown error occurred.';
            setErrorMessage(errorMessage);
        }
    } catch (error) {
        console.error('Error:', error);
        setErrorMessage('An error occurred while making the request.');
    } 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) {
        setErrorMessage('Failed to fetch image, please try again.');
        return;
      }

      const imageBlob = await response.blob();
      const imageData = URL.createObjectURL(imageBlob);
      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 handleInputChangeApplication = (newInputValue) => {
    // Limit input to 15 characters for Application ID
    if (newInputValue.length <= 15) {
        setInputValueApplication(newInputValue);
    }
  };

  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>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 = {
    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', // Use viewport height for a more responsive size
        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: 'row',
        width: '100%',
        flexWrap: 'wrap', // Allow wrapping on smaller screens
    },
    resultsTable: {
        width: '60%',
        borderCollapse: 'collapse',
    },
    resultsTableMobile: {
        width: '100%',
        borderCollapse: 'collapse',
    },
    resultsCell: {
        padding: '8px',
        width: '30%',
        fontSize: '16px',
    },
    resultsValueCell: {
        padding: '8px',
        width: '70%',
        fontSize: '16px',
        color: 'red',
    },
    resultsTrueValue: {
        color: 'inherit',
    },
    imageContainer: {
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'flex-start',
        width: '100%',
        marginTop: '20px',
    },
    imageStyle: {
      width: isMobile ? '200px' : '320px', // 200px for mobile, 320px for larger screens
      height: isMobile ? '200px' : '320px',
      borderRadius: '5px',
      objectFit: 'cover', // Ensures the image fits within the specified dimensions
    },
    imageStyleMobile: {
        width: '100%',
        height: 'auto',
        borderRadius: '5px',
    },
    imageDetails: {
        marginTop: '10px',
        fontSize: '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',
    },
  };

  return (
    <div>
      <style>
        {`
          @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
          }
        `}
      </style>

      {isLoading && (
        <div style={styles.loadingOverlay}>
            <div style={styles.spinner}></div>
            <p style={styles.loadingText}>Loading...</p>
        </div>
      )}

      {/* Application ID Selection */}
      <div className="form-group row align-items-center">
        <div className="col-md-6">
          <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} // Limit input length for Application ID
          />
        </div>
        {applicationError && <small style={{color: 'red'}}>{applicationError}</small>}
        <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> {/* Display selected quota */}
                <span style={styles.timesText}>(times)</span>
            </div>
        </div>
      </div>

      {/* Subject ID Input */}
      <div className="form-group row align-items-center">
        <div className="col-md-6">
            <Select
              id="subjectId"
              value={options.find(option => option.value === subjectId)}
              onChange={(selectedOption) => setSubjectId(selectedOption ? selectedOption.value : '')}
              options={options}
              inputValue={inputValue}
              onInputChange={(newInputValue) => {
                  if (newInputValue.length <= 15) {  // Limit the input length
                      setInputValue(newInputValue);
                  }
              }}
            />

            {subjectError && <small style={{ color: 'red' }}>{subjectError}</small>}
            {subjectAvailabilityMessage && (
                <small style={{ color: subjectAvailabilityMessage.includes('available') ? 'green' : 'red' }}>
                    {subjectAvailabilityMessage}
                </small>
            )}
        </div>

        <div className="col-md-6">
          <div style={styles.selectWrapper}>
            <select
              id="thresholdId"
              className="form-control"
              style={styles.select}
              value={thresholdId}
              onChange={(e) => {
                setThresholdId(e.target.value);
                setThresholdError(''); // Clear error if valid
              }}
            >
              <option value="">Select Threshold</option>
              {thresholdIds.map((app) => (
                <option key={app.id} value={app.name}>
                  {app.displayName}
                </option>
              ))}
            </select>
            <FontAwesomeIcon
              icon={faChevronDown}
              style={styles.chevronIcon}
            />
            {thresholdError && <small style={styles.uploadError}>{thresholdError}</small>}
          </div>
        </div>
      </div>

      {/* Upload Section */}
      <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}
              onTypeError={(err) => {
                  setImageError('Only JPG/JPEG files are allowed');
                  setFile(null);
                  setSelectedImageName('');
              }}
              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>
                      <span 
                          style={{
                              color: '#0542cc',
                              textDecoration: 'underline',
                              cursor: 'pointer'
                          }}
                      >
                          Browse
                      </span>
                      <p className="text-muted">Recommended size: 300x300 (Max File Size: 2MB)</p>
                      <p className="text-muted">Supported file types: JPG, JPEG</p>
                  </div>
              }
            />
            {imageError && (
                <small className="text-danger mt-2" style={{ fontSize: '12px' }}>
                    {imageError}
                </small>
            )}
        </div>
      </div>
      
      {/* Display uploaded image name */}
      {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>
      )}
      {errorMessage && <small style={styles.uploadError}>{errorMessage}</small>}

      {/* Submit Button */}
      <div style={styles.submitButton}>
        <button onClick={handleCheckClick} className="btn d-flex justify-content-center align-items-center me-2" style={{ backgroundColor: '#0542CC' }}>
            <p className="text-white mb-0">Check Now</p>
        </button>
      </div>


      {/* Results Section */}
      {showResult && (
          <div style={styles.containerResultStyle}>
              <h1 style={{ color: '#0542cc', fontSize: '2rem' }}>Results</h1>
              <div style={styles.resultContainer}>
                  <table style={styles.resultsTableMobile}>
                      <tbody>
                          <tr>
                              <td style={styles.resultsCell}>Similarity</td>
                              <td style={{ ...styles.resultsValueCell, color: verified ? 'green' : 'red' }}>
                                  <strong>{verified !== null ? (verified ? 'True' : 'False') : 'N/A'}</strong>
                              </td>
                          </tr>
                      </tbody>
                  </table>

                  <div style={styles.imageContainer}>
                      <img
                          src={imageUrl || "path-to-your-image"}
                          alt="Example Image"
                          style={{
                              maxWidth: '100%',
                              width: 'auto',
                              height: 'auto',
                              objectFit: 'contain',
                              borderRadius: '5px'
                          }}
                      />
                      <p style={{ marginTop: '10px' }}>
                          File Name: {resultImageLabel}
                      </p>
                  </div>
              </div>
          </div>
      )}

    </div>
  );

}

export default Verify;
