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 Compare = () => {

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

  const [isSelectOpen, setIsSelectOpen] = useState(false);
  const [errorMessage, setErrorMessage] = useState('');
  const [selectedImageName, setSelectedImageName] = useState('');
  const [selectedCompareImageName, setSelectedCompareImageName] = useState('');
  const fileInputRef = useRef(null);
  const fileCompareInputRef = useRef(null);
  const [showResult, setShowResult] = useState(false);
  const [applicationId, setApplicationId] = useState('');
  const [selectedQuota, setSelectedQuota] = useState(0);
  const [thresholdId, setTresholdId] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [imageUrl, setImageUrl] = useState('');
  const [imageCompareUrl, setImageCompareUrl] = useState('');
  const [verified, setVerified] = useState(null);

  const fileTypes = ["JPG", "JPEG", "PNG"];
  const [file, setFile] = useState(null); // For the first image
  const [compareFile, setCompareFile] = useState(null); // For the second imag

  const [applicationIds, setApplicationIds] = useState([]);
  const [inputValueApplication, setInputValueApplication] = useState(''); // Controlled input value for Application ID

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

  const [applicationError, setApplicationError] = useState('');
  const [thresholdError, setThresholdError] = useState('');
  const [uploadError, setUploadError] = useState('');
  const [compareUploadError, setCompareUploadError] = useState('');

  useEffect(() => {
    const fetchApplicationIds = async () => {
      try {
          setIsLoading(true)

          const url = `${BASE_URL}/application/list`;
          console.log('Fetching URL:', url); // Log the URL
          
          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) {
              const ids = data.details.data.map(app => app.id);
              console.log('Application Id: ' + ids); // Log the IDs
              setApplicationIds(data.details.data); // Update state with the fetched 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 handleApplicationChange = (selectedOption) => {
    if (selectedOption) {
      const selectedId = selectedOption.value;
      const selectedApp = applicationIds.find(app => app.id === parseInt(selectedId));
      if (selectedApp) {
        setApplicationId(selectedId);
        setSelectedQuota(selectedApp.quota); // Set the selected quota
      }
    }
  };
  

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

  const handleFocus = () => {
    setIsSelectOpen(true);
  };

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

  const handleImageUpload = (file) => {
    if (file && fileTypes.includes(file.name.split('.').pop().toUpperCase())) {
      setSelectedImageName(file.name);
      setFile(file); // Store the file directly in state
      setUploadError(''); // Clear error if valid
    }
  };
  
  const handleCompareImageUpload = (file) => {
    if (file && fileTypes.includes(file.name.split('.').pop().toUpperCase())) {
      setSelectedCompareImageName(file.name);
      setCompareFile(file); // Store the compare file directly in state
      setCompareUploadError(''); // Clear error if valid
    }
  };  

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

  const handleCompareImageCancel = () => {
    setSelectedCompareImageName('');
    setImageCompareUrl('');
    if (fileCompareInputRef.current) fileCompareInputRef.current.value = '';
  };

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

    // Initialize a flag to check for errors
    let hasError = false;

    // Validate Application ID
    if (!applicationId) {
        setApplicationError('Please select an Application ID before compare.');
        hasError = true;
    }

    // Validate Threshold ID
    const selectedThreshold = thresholdIds.find(threshold => threshold.name === thresholdId)?.name;
    if (!selectedThreshold) {
        setThresholdError('Invalid threshold selected.');
        hasError = true;
    }

    // Validate Image Uploads
    if (!selectedImageName) {
        setUploadError('Please upload a face photo before compare.');
        hasError = true;
    }

    if (!selectedCompareImageName) {
        setCompareUploadError('Please upload a compare face photo before compare.');
        hasError = true;
    }

    // If there are any errors, return early
    if (hasError) {
        return;
    }

    // Prepare FormData and log inputs
    const formData = new FormData();
    formData.append('application_id', applicationId);
    formData.append('file1', file); // Use the state variable directly
    formData.append('file2', compareFile); // Use the state variable directly
    formData.append('threshold', selectedThreshold);

    // Log the inputs
    console.log('Inputs:', {
        applicationId,
        threshold: selectedThreshold,
        file1: selectedImageName,
        file2: selectedCompareImageName,
    });

    setIsLoading(true);
    setErrorMessage('');

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

        const data = await response.json();
        if (response.ok) {
            // Fetch image URLs from response
            const imageUrl1 = data.details.data.result.image_url1;
            const imageUrl2 = data.details.data.result.image_url2;

            await fetchImage(imageUrl1, setImageUrl);
            await fetchImage(imageUrl2, setImageCompareUrl);

            setVerified(data.details.data.result.verified);
            setShowResult(true);
            console.log('Comparison successful:', data);
        } else {
            console.error('Error response:', data);
            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 (imageUrl, setImageUrl) => {
      setIsLoading(true);
      try {
          const response = await fetch(imageUrl, {
              method: 'GET',
              headers: {
                  'accept': 'application/json',
                  'x-api-key': `${API_KEY}`, // Ensure this is valid
              }
          });

          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); // Set the state with the blob URL

      } catch (error) {
          console.error('Error fetching image:', error);
          setErrorMessage(error.message);
      } finally {
          setIsLoading(false);
      }
  };

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

  const ResultsSection = ({ showResult, verified, imageUrl, selectedImageName, imageCompareUrl, selectedCompareImageName }) => (
    showResult && (
      <div style={styles.containerResultStyle}>
        <h1 style={{ color: '#0542cc', fontSize: '1.5rem', textAlign: 'center' }}>Results</h1>
        <div style={styles.resultContainer}>
          <table style={styles.tableStyle}>
            <tbody>
              <tr>
                <td style={{ border: '0.1px solid gray', padding: '8px', width: '30%' }}>Similarity</td>
                <td style={styles.similarityText(verified)}>
                  {verified !== null ? (verified ? 'True' : 'False') : 'N/A'}
                </td>
              </tr>
            </tbody>
          </table>
  
          <div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'center', gap: '20px' }}>
            <div style={styles.imageContainer}>
              <img 
                src={imageUrl || "path-to-your-image"} 
                alt="Original Foto" 
                style={styles.imageStyle} 
              />
              <p style={{ marginTop: '1rem', textAlign: 'center' }}>{selectedImageName}</p>
            </div>
  
            <div style={styles.imageCompareContainer}>
              <img 
                src={imageCompareUrl || "path-to-your-image"} 
                alt="Compare Foto" 
                style={styles.imageStyle} 
              />
              <p style={{ marginTop: '1rem', textAlign: 'center' }}>{selectedCompareImageName}</p>
            </div>
          </div>
        </div>
      </div>
    )
  );

  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>
      {/* Inject keyframes for the spinner */}
      <style>
        {`
          @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
          },
          @media (max-width: 768px) {
            .resultContainer {
              flex-direction: column;
              align-items: center;
            }
          }
        `}
      </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} // Pass selected option directly
              options={applicationOptions}
              placeholder="Select Application ID"
              isSearchable
              menuPortalTarget={document.body}
              menuPlacement="auto"
              inputValue={inputValueApplication}
              onInputChange={handleInputChangeApplication}
            />
          </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 and Threshold Selection */}
      <div className="form-group row align-items-center">
        <div className="col-md-6">
          <div style={styles.selectWrapper}>
            <select
              id="thresholdId"
              className="form-control"
              style={styles.select}
              value={thresholdId}
              onChange={(e) => setTresholdId(e.target.value)}
              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>

      <div className="row">
        {/* Upload Image #1 */}
        <div className="col-md-6">
          <div className="row form-group mt-4">
            <label style={{ fontWeight: 600, fontSize: '14px', color: '#212529' }}>Upload Face Photo</label>
            <FileUploader
              handleChange={handleImageUpload}
              name="file"
              types={fileTypes}
              multiple={false}
              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="#">Browse</a>
                  <p className="text-muted">Recommended size: 250x250 (Max File Size: 2MB)</p>
                  <p className="text-muted">Supported file types: JPG, JPEG</p>
                </div>
              }
            />
            {uploadError && <small style={styles.uploadError}>{uploadError}</small>}
          </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>
          )}
        </div>
        {errorMessage && <small style={styles.uploadError}>{errorMessage}</small>}

        {/* Upload Image #2 */}
        <div className="col-md-6">
          <div className="row form-group mt-4">
            <label style={{ fontWeight: 600, fontSize: '14px', color: '#212529' }}>Upload Compare Photo</label>
            <FileUploader
              handleChange={handleCompareImageUpload}
              name="file"
              types={fileTypes}
              multiple={false}
              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="#">Browse</a>
                  <p className="text-muted">Recommended size: 250x250 (Max File Size: 2MB)</p>
                  <p className="text-muted">Supported file types: JPG, JPEG</p>
                </div>
              }
            />
            {compareUploadError && <small style={styles.uploadError}>{compareUploadError}</small>}
          </div>

          {/* Display uploaded image name */}
          {selectedCompareImageName && (
              <div className="mt-3">
                  <p><strong>File:</strong> {selectedCompareImageName}</p>
                  {compareFile && (
                      <p style={styles.fileSize}>
                          Size: {formatFileSize(compareFile.size)}
                      </p>
                  )}
                  <button className="btn btn-danger" onClick={handleCompareImageCancel}>
                      <FontAwesomeIcon icon={faTimes} className="me-2" />Cancel
                  </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 && (
        <ResultsSection
          showResult={showResult}
          verified={verified}
          imageUrl={imageUrl}
          selectedImageName={selectedImageName}
          imageCompareUrl={imageCompareUrl}
          selectedCompareImageName={selectedCompareImageName}
        />
      )}
    </div>
  )
}

export default Compare

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: '40svh',
      cursor: 'pointer',
      marginTop: '1rem',
      display: 'flex',
      flexDirection: 'column',
      justifyContent: 'center',
      alignItems: 'center',
      border: '1px solid #ced4da',
      borderRadius: '0.25rem',
      padding: '25px 10px 10px 10px'
  },
  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: {
    margin: '20px 0',
    padding: '10px',
    border: '1px solid #e0e0e0',
    borderRadius: '8px',
    backgroundColor: '#f9f9f9',
  },
  resultContainer: {
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
  },
  tableStyle: {
    width: '100%',
    borderCollapse: 'collapse',
    marginBottom: '20px',
  },
  imageContainer: {
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    flex: 1,
    padding: '10px',
  },
  imageCompareContainer: {
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    flex: 1,
    padding: '10px',
  },
  imageStyle: {
    width: '100%',
    height: 'auto',
    maxWidth: '150px', // Limit image width
    borderRadius: '8px',
  },
  similarityText: (verified) => ({
    border: '0.1px solid gray',
    padding: '8px',
    color: verified ? 'green' : 'red',
    fontWeight: 'bold',
  }),
  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',
  },
};