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';

const Verify = () => {
  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 [uploadError, setUploadError] = useState('');
  const [applicationError, setApplicationError] = useState('');
  const [subjectError, setSubjectError] = useState('');
  const [thresholdError, setThresholdError] = useState('');
  const [selectedImageName, setSelectedImageName] = useState('');
  const [resultImageLabel, setResultImageLabel] = useState('');
  const fileInputRef = 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 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 && file.name) {
        const fileExtension = file.name.split('.').pop().toUpperCase();
        if (fileTypes.includes(fileExtension)) {
            setSelectedImageName(file.name);
            setFile(file);
            setUploadError('');
        } else {
            alert('Image format is not supported');
            setUploadError('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 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);
    }
  };

  // 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
    }
  };

  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>
          <div style={styles.uploadWrapper}>
            <div
              style={styles.uploadArea}
              onDrop={(e) => {
                e.preventDefault();
                // Handle drop event
                const file = e.dataTransfer.files[0];
                handleImageUpload(file);
              }}
              onDragOver={(e) => e.preventDefault()}
            >
              <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={(e) => {
                  e.preventDefault();
                  // Only open file input if no file is selected
                  if (!fileInputRef.current.files.length) {
                    fileInputRef.current.click();
                  }
                }}
                style={styles.browseLink}
              >
                Browse
              </a>
              <p className="text-muted" style={styles.uploadText}>
                Recommended size: 300x300 (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="uploadPhoto"
              className="form-control"
              style={{ display: 'none' }}
              accept="image/jpeg, image/jpg"
              onChange={(e) => handleImageUpload(e.target.files[0])}
            />

            {/* Error Message */}
            {uploadError && <small style={styles.uploadError}>{uploadError}</small>}
          </div>
        </div>
      </div>
      
      {/* Display uploaded image name */}
      {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>}

      {/* 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={styles.imageStyle}
              />
              <p style={{ marginTop: '10px' }}>
                File Name: {resultImageLabel} {/* Display the resultImageLabel here */}
              </p>
            </div>
          </div>
        </div>
      )}
    </div>
  );

}

export default Verify;
