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

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 [isSelectOpen, setIsSelectOpen] = useState(false);
  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 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 thresholdIds = [
    { id: 1, name: 'cosine', displayName: 'Basic' },
    { id: 2, name: 'euclidean', displayName: 'Medium' },
    { id: 3, name: 'euclidean_l2', displayName: 'High' },
  ];

  const options = subjectIds.map(id => ({ value: id, label: id }));
  const [inputValue, setInputValue] = useState('');
  const applicationOptions = applicationIds.map(app => ({
    value: app.id,
    label: app.name
  }));
  useEffect(() => {
    const fetchApplicationIds = async () => {
      try {
        setIsLoading(true);
        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();

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

    fetchApplicationIds();

    const handleResize = () => setIsMobile(window.innerWidth <= 768);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  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',
      padding: '22px 10px 0 20px',
      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',
    },
    wrapper: {
      border: '1px solid #ddd',
      borderRadius: '6px',
      padding: '18px 10px 0 8px', // Padding lebih seragam
      height: '13svh', // Tinggi lebih kecil untuk menyesuaikan tampilan
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'space-between',
      backgroundColor: '#f9f9f9',
      overflow: 'hidden',
    },
    fileWrapper: {
      display: 'flex',
      alignItems: 'center',
      flex: '1',
    },
    textContainer: {
      flex: '1',
      fontSize: '16px', // Ukuran font lebih kecil
      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', // Ukuran ikon sedikit lebih kecil
      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%',
      maxWidth: '600px',
      margin: '20px auto',
    },
    resultContainer: {
      display: 'flex',
      alignItems: 'center',
      width: '100%',
    },
    tableStyle: {
      width: '60%',
      borderCollapse: 'collapse',
    },
    resultsTableMobile: {
      width: '100%',
      borderCollapse: 'collapse',
      fontSize: '14px',
    },
    resultsCell: {
      border: '0.1px solid gray',
      padding: '8px',
    },
    resultsValueCell: {
      border: '0.1px solid gray',
      padding: '8px',
      width: '60%',
    },
    imageContainer: {
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      marginTop: isMobile ? '20px' : '0',
    },
    imageStyle: {
      width: '300px',
      height: '300px',
      borderRadius: '5px',
      objectFit: 'cover',
    },
    imageStyleMobile: {
      width: '100%',
      height: 'auto',
    },
    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',
    },
  };

  const handleApplicationChange = async (selectedOption) => {
      if (!selectedOption) {
          console.error("Selected option is undefined");
          return;
      }

      const selectedId = selectedOption.value;
      const selectedApp = applicationIds.find(app => app.id === parseInt(selectedId));

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

      setApplicationId(selectedId);

      if (selectedId) {
          await fetchSubjectIds(selectedId);
      } else {
          setSubjectIds([]);
          setSubjectAvailabilityMessage('');
      }
  };


  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 handleFocus = () => {
    setIsSelectOpen(true);
  };

  const handleBlur = () => {
    setIsSelectOpen(false);
  };

  const handleImageUpload = (file) => {
    // Ensure file exists before accessing its properties
    if (!file) {
      console.error('File is undefined');
      setUploadError('Please upload a valid image file.');
      return;
    }
  
    const fileExtension = file.name.split('.').pop().toUpperCase();
    if (fileTypes.includes(fileExtension)) {
      setSelectedImageName(file.name);
      setFile(file);
      setUploadError(''); // Clear any previous errors
    } else {
      // Show an alert if the file type is not supported
      alert('Image format is not supported');
      setUploadError('Image format is not supported'); // Optionally set error message to display on the UI
      setFile(null); // Optionally clear the selected file
    }
  };  
  

  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

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

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

    const selectedThreshold = thresholdIds.find(threshold => threshold.name === thresholdId)?.name;

    if (!selectedThreshold) {
        setThresholdError('Invalid threshold selected.');
        hasError = true; // Mark that an error occurred
    }

    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
    console.log('Selected Image Name:', selectedImageName);
    console.log('Application ID:', applicationId);
    console.log('Subject ID:', subjectId);
    console.log('Selected Threshold:', selectedThreshold);

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

    // const file = fileInputRef.current.files[0];
    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();

        if (response.ok) {
            if (data.details && data.details.data && data.details.data.result && data.details.data.result.image_url) {
                const imageFileName = data.details.data.result.image_url.split('/').pop();
                await fetchImage(imageFileName);
            }

            setShowResult(true);
            setVerified(data.details.data.result.verified);
        } 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
    }
  };


  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">
          <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} // Use this for scroll behavior
                menuPlacement="auto"
                inputValue={inputValueApplication}
                onInputChange={handleInputChangeApplication} // Limit input length for Application ID
            />
          </div>
          {applicationError && <small style={styles.uploadError}>{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> {/* 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"
            options={options}
            value={options.find(option => option.value === subjectId)}
            onChange={selectedOption => setSubjectId(selectedOption ? selectedOption.value : '')}
            onInputChange={(value) => {
                // Check if input value length is within the 15-character limit
                if (value.length <= 15) {
                    setInputValue(value); // Set the input value if within limit
                }
            }} 
            onFocus={() => fetchSubjectIds(applicationId)} // Fetch subject IDs on focus
            placeholder="Enter Subject ID"
            isClearable
            noOptionsMessage={() => (
                <div style={{ color: 'red' }}>Subject ID not registered.</div>
            )}
            inputValue={inputValue}  // Bind the inputValue state to control the input
          />
          {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
              }}
              onFocus={handleFocus}
              onBlur={handleBlur}
            >
              <option value="">Select Threshold</option>
              {thresholdIds.map((app) => (
                <option key={app.id} value={app.name}>
                  {app.displayName}
                </option>
              ))}
            </select>
            <FontAwesomeIcon
              icon={isSelectOpen ? faChevronDown : faChevronLeft}
              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}
            onDrop={(files) => handleImageUpload(files[0])}
            children={
              <div style={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>
            }
          />
          {uploadError && <small style={styles.uploadError}>{uploadError}</small>}
        </div>
      </div>
      
      {/* Display uploaded image name */}
      {selectedImageName && (
        <div className="col-md-6 mt-4" style={styles.wrapper}>
            <div style={styles.fileWrapper}>
                <FontAwesomeIcon icon={faImage} style={styles.imageIcon} />
                <div style={styles.textContainer}>
                    <h5>Uploaded File:</h5>
                    <p>{selectedImageName}</p>
                    {file && (
                        <p style={styles.fileSize}>
                            Size: {formatFileSize(file.size)}
                        </p>
                    )}
                </div>
                <div style={styles.closeButtonContainer}>
                    <button
                        style={styles.closeButton}
                        onClick={handleImageCancel}
                        aria-label="Remove uploaded image"
                    >
                        <FontAwesomeIcon
                            icon={faTimes}
                            style={styles.closeIcon}
                        />
                    </button>
                </div>
            </div>
        </div>
      )}
      
      {/* 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: isMobile ? '1.5rem' : '2rem' }}>Results</h1>
          <div style={{ ...styles.resultContainer, flexDirection: isMobile ? 'column' : 'row' }}>
            <table style={isMobile ? styles.resultsTableMobile : styles.tableStyle}>
              <tbody>
                <tr>
                  <td style={{ ...styles.resultsCell, width: '40%' }}>Similarity</td>
                  <td
                    style={{
                      ...styles.resultsValueCell,
                      color: verified ? 'green' : verified === false ? 'red' : 'black',
                    }}
                  >
                    <strong>{verified !== null ? (verified ? 'True' : 'False') : 'N/A'}</strong>
                  </td>
                </tr>
              </tbody>
            </table>

            <div style={{ ...styles.imageContainer, width: isMobile ? '100%' : '30%' }}>
              <img
                src={imageUrl || "path-to-your-image"} 
                alt="Example Image"
                style={isMobile ? styles.imageStyleMobile : styles.imageStyle}
              />
              <p style={{ marginTop: '10px', fontSize: isMobile ? '12px' : '16px' }}>
                File Name: {selectedImageName}
              </p>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

export default Verify;
