// // src/App.js
// import React, { useState, useEffect, useRef } from 'react';
// //import OpenCvButton from './OpenCvButton';
// import './App.css';

// export const App = () => {
//   const [opencvLoaded, setOpencvLoaded] = useState(false);
//   const [isCanvasVisible, setIsCanvasVisible] = useState(false);
//   const videoRef = useRef(null);
//   const canvasRef = useRef(null);
//   const instructionTextRef = useRef(null);
//   const loaderRef = useRef(null);
//   const FPS = 1080; // Adjust FPS as needed
//   const ZOOM_FACTOR = 1.5;

//   useEffect(() => {
//     const checkOpenCV = () => {
//       if (window.cv) {
//         setOpencvLoaded(true);
//       } else {
//         setTimeout(checkOpenCV, 100);
//       }
//     };
//     checkOpenCV();
//   }, []);

//   useEffect(() => {
//     if (opencvLoaded) {
//       openCvReady();
//     }
//   }, [opencvLoaded]);

//   const openCvReady = () => {
//     console.log("in opencvready");
//     console.log("1");
//     window.cv['onRuntimeInitialized'] = () => {
//       console/log("9");
//       const video = videoRef.current;
//       const canvas = canvasRef.current;
//       const instructionText = instructionTextRef.current;
//       navigator.mediaDevices.getUserMedia({
//         video: true,
//         audio: false
//       })
//         .then(function (stream) {
//           video.srcObject = stream;
//           video.play();
//           setIsCanvasVisible(false);

//           video.addEventListener('loadeddata', () => {
//             const videoAspect = video.videoWidth / video.videoHeight;
//             const canvasWidth = canvas.clientWidth;
//             const canvasHeight = canvasWidth / videoAspect;

//             canvas.width = canvasWidth;
//             canvas.height = canvasHeight;

//             const src = new window.cv.Mat(video.videoHeight, video.videoWidth, window.cv.CV_8UC4);
//             const dst = new window.cv.Mat(video.videoHeight, video.videoWidth, window.cv.CV_8UC4);
//             const gray = new window.cv.Mat();
//             const cap = new window.cv.VideoCapture(video);
//             const faces = new window.cv.RectVector();
//             const classifier = new window.cv.CascadeClassifier();
//             const utils = new window.Utils('errorMessage');
//             const faceCascadeFile = 'haarcascade_frontalface_default.xml';
//             utils.createFileFromUrl(faceCascadeFile, faceCascadeFile, () => {
//               classifier.load(faceCascadeFile);
//               console.log("Classifier loaded:", classifier.empty() ? "Failed to load" : "Successfully loaded");
//             });

//             const processVideo = () => {
//               if (!window.cv || !window.cv.Mat) {
//                 console.log('OpenCV.js is not loaded');
//                 return;
//               } else {
//                 console.log('OpenCV.js is loaded');
//               }

//               let begin = Date.now();
//               cap.read(src);
//               console.log("process video 1");

//               // Zoom the video frame
//               let zoomedSrc = new window.cv.Mat();
//               let zoomRect = new window.cv.Rect(
//                 src.cols / 2 - (src.cols / (2 * ZOOM_FACTOR)),
//                 src.rows / 2 - (src.rows / (2 * ZOOM_FACTOR)),
//                 src.cols / ZOOM_FACTOR,
//                 src.rows / ZOOM_FACTOR
//               );
//               zoomedSrc = src.roi(zoomRect);
//               window.cv.resize(zoomedSrc, dst, new window.cv.Size(src.cols, src.rows), 0, 0, window.cv.INTER_LINEAR);
//               console.log("process video 2");
//               let clonedst = new window.cv.Mat();
//               dst.copyTo(clonedst);

//               instructionText.textContent = "Keep Your Face In The Frame";
//               console.log("process video 3");

//               // Perform face detection on the zoomed image
//               let faces1 = new window.cv.RectVector();
//               console.log("process video 3.1");
//               let faces = new window.cv.RectVector();
//               console.log("process video 3.2");
//               try {
//                 console.log("process video 3.3");
//                 classifier.detectMultiScale(src, faces, 1.5, 3, 0);
//                 console.log("process video 3.4");
//                 classifier.detectMultiScale(src, faces1, 1.5, 3, 0);
//                 console.log("process video 4");
//                 console.log("Face size is " + faces.size() + faces1.size());
//                 console.log("process video 5");
//                 console.log("faces1.size: ", faces1.size());
//                 if (faces1.size() === 1) {
//                   const face = faces.get(0);
//                   const face1 = faces1.get(0);
//                   const rect = new window.cv.Rect(face.x, face.y, face.width, face.height);
//                   console.log("process video 6");

//                   // Draw rectangle around the detected face
//                   window.cv.rectangle(src, new window.cv.Point(face.x, face.y), new window.cv.Point(face.x + face.width, face.y + face.height), [0, 255, 0, 255], 2);

//                   const bufferRatio = 0.14; // 14% buffer
//                   let bufferedX = Math.max(0, face.x - face.width * bufferRatio);
//                   let bufferedY = Math.max(0, face.y - face.height * bufferRatio);
//                   let bufferedWidth = Math.min(src.cols - bufferedX, face.width * (1 + 2 * bufferRatio));
//                   let bufferedHeight = Math.min(src.rows - bufferedY, face.height * (1 + 2 * bufferRatio));
//                   console.log("process video 7");
//                   const bufferedRect = new window.cv.Rect(bufferedX, bufferedY, bufferedWidth, bufferedHeight);
//                   console.log("process video 8");

//                   // Draw the buffered rectangle on the canvas
//                   window.cv.rectangle(src, new window.cv.Point(bufferedRect.x, bufferedRect.y), new window.cv.Point(bufferedRect.x + bufferedRect.width, bufferedRect.y + bufferedRect.height), [5, 255, 0, 255], 2);
//                   console.log("process video 9");

//                   const faceArea = face1.width * face1.height;
//                   const ovalArea = Math.PI * (canvas.width / 2) * (canvas.height / 2);
//                   const faceAreaPercentage = (faceArea / ovalArea) * 100;
//                   let faceDetectionCount = 0;
//                   console.log("process video 10", face1.height);

//                   if (!isFaceInsideOval(face1, canvas)) {
//                     console.log("in is faceinsideoval if", faceAreaPercentage);
//                     instructionText.textContent = "Move inside the oval window";
//                     faceDetectionCount = 0;

//                     instructionText.textContent = "Processing....";
//                     faceDetectionCount++;
//                     if (faceDetectionCount === 1) {
//                       console.log("in if above upload()");
//                       uploadBufferedFaceImage(bufferedRect);
//                       showLoader();
//                       return false;
//                     }
//                   }
//                 }
//               } catch (err) {
//                 console.log(err);
//               } finally {
//                 faces1.delete();
//                 faces.delete();
//               }

//               // Show the result on the canvas
//               if (isCanvasVisible) {
//                 window.cv.flip(dst, dst, 1);
//                 window.cv.imshow("canvas_output", src);
//               }

//               let delay = 1000 / FPS - (Date.now() - begin);
//               setTimeout(processVideo, delay);
//             };

//             const uploadBufferedFaceImage = (rect) => {
//               console.log("in upload()");
//               const videoCanvas = document.createElement('canvas');
//               videoCanvas.width = video.videoWidth;
//               videoCanvas.height = video.videoHeight;
//               const videoCtx = videoCanvas.getContext('2d');
//               videoCtx.drawImage(video, 0, 0, videoCanvas.width, videoCanvas.height);

//               const cropCanvas = document.createElement('canvas');
//               cropCanvas.width = rect.width;
//               cropCanvas.height = rect.height;
//               const cropCtx = cropCanvas.getContext('2d');

//               const imageData = videoCtx.getImageData(rect.x, rect.y, rect.width, rect.height);
//               cropCtx.putImageData(imageData, 0, 0);
//               console.log("in mid upload()");
//               cropCanvas.toBlob((blob) => {
//                 const formData = new FormData();
//                 formData.append('image', blob, 'face.png');

//                 const downloadLink = document.createElement('a');
//                 downloadLink.href = URL.createObjectURL(blob);
//                 downloadLink.download = 'face.png';
//                 downloadLink.textContent = 'Download Cropped Image';
//                 document.body.appendChild(downloadLink);
//                 const responseText = document.getElementById('response-text');
//                 fetch('http://192.168.1.172:8014/upload.php', {
//                   method: 'POST',
//                   body: formData,
//                 })
//                   .then(response => response.json())
//                   .then(data => {
//                     hideLoader();
//                     responseText.innerHTML = '<p>' + data + '</p>';
//                     console.log('Upload successful:', data);
//                     window.location.href = './verified.html';
//                   })
//                   .catch(error => {
//                     hideLoader();
//                     responseText.innerHTML = '<p>' + error + '</p>';
//                     console.error('Error uploading image:', error);
//                     window.location.href = './failed.html';
//                   });
//               });
//             };

//             const showLoader = () => {
//               loaderRef.current.style.display = 'block';
//             };

//             const hideLoader = () => {
//               loaderRef.current.style.display = 'none';
//             };

//             const isFaceInsideOval = (face, canvas) => {
//               const ovalCenterX = canvas.width / 2;
//               const ovalCenterY = canvas.height / 2;
//               const ovalRadiusX = canvas.width / 2;
//               const ovalRadiusY = canvas.height / 2;

//               const faceCenterX = face.x + face.width / 2;
//               const faceCenterY = face.y + face.height / 2;
//               const normalizedX = (faceCenterX - ovalCenterX) / ovalRadiusX;
//               const normalizedY = (faceCenterY - ovalCenterY) / ovalRadiusY;
//               const distanceFromCenter = Math.sqrt(normalizedX * normalizedX + normalizedY * normalizedY);

//               return distanceFromCenter <= 1;
//             };

//             setTimeout(processVideo, 0);
//           });
//         })
//         .catch(function (err) {
//           console.log("An error occurred: " + err);
//         });
//     };
//   };

//   return (
//     <div className="container">
//       <img id="powered-logo" src="purple_logo_accura.png" alt="Powered by Your Logo" />
//       <p id="instructionText" ref={instructionTextRef}></p>
//       <div className="camera-input">
//         <video id="videoInput" ref={videoRef} width="640" height="480" autoPlay muted></video>
//         <canvas id="canvas_output" ref={canvasRef} style={{ display: isCanvasVisible ? 'block' : 'none' }}></canvas>
//       </div>
//       <div id="loader" ref={loaderRef} className="loader" style={{ display: 'none' }}></div>
//       <div id="response-text"></div>
//       <div id="powered-by">
//         <a href="https://ibeta.com/wp-content/uploads/2022/08/220816-Accura-Scan-PAD-Level-1-Confirmation-Letter.pdf" target="_blank">
//           <img id="IBETA_logo" src="images/IBETA-Level-1.webp" alt="IBETA-Level-1" />
//         </a>
//         <a href="https://www.ibeta.com/wp-content/uploads/2023/07/230712-Accura-Scan-PAD-Level-2-APCER-Confirmation-Letter.pdf" target="_blank">
//           <img style={{ paddingBottom: '3px' }} id="IBETA_logo" src="images/IBETA-Level-2.webp" alt="IBETA-Level-2" />
//         </a>
//       </div>
//     </div>
//   );
// };

// export default App;




// src/App.js
import React, { useState, useEffect, useRef } from 'react';
import OpenCvButton from './OpenCvButton.js';
import './App.css';

export const App = () => {
  const [opencvLoaded, setOpencvLoaded] = useState(false);
  const [isCanvasVisible, setIsCanvasVisible] = useState(false);
  const videoRef = useRef(null);
  const canvasRef = useRef(null);
  const instructionTextRef = useRef(null);
  const loaderRef = useRef(null);
  const FPS = 1080; // Adjust FPS as needed
  const ZOOM_FACTOR = 1.5;
 // const [showApp, setShowApp1] = useState(false);
  useEffect(() => {
    const checkOpenCV = () => {
      if (window.cv) {
        setOpencvLoaded(true);
      } else {
        setTimeout(checkOpenCV, 100);
      }
    };
    checkOpenCV();
  }, []);

  useEffect(() => {
    if (opencvLoaded) {
      openCvReady();
    }
  }, [opencvLoaded]);

  // useEffect(() => {
  //   const savedShowApp = localStorage.getItem('showApp') === 'true';
  //   setShowApp1(savedShowApp);
  // }, []);
  
  const openCvReady = () => {
    console.log("in opencvready");
    window.cv['onRuntimeInitialized'] = () => {
      const video = videoRef.current;
      const canvas = canvasRef.current;
      const instructionText = instructionTextRef.current;
      navigator.mediaDevices.getUserMedia({
        video: true,
        audio: false
      })
        .then(function (stream) {
          video.srcObject = stream;
          video.play();
          setIsCanvasVisible(false);

          video.addEventListener('loadeddata', () => {
            const videoAspect = video.videoWidth / video.videoHeight;
            const canvasWidth = canvas.clientWidth;
            const canvasHeight = canvasWidth / videoAspect;

            canvas.width = canvasWidth;
            canvas.height = canvasHeight;

            const src = new window.cv.Mat(video.videoHeight, video.videoWidth, window.cv.CV_8UC4);
            const dst = new window.cv.Mat(video.videoHeight, video.videoWidth, window.cv.CV_8UC4);
            const gray = new window.cv.Mat();
            const cap = new window.cv.VideoCapture(video);
            const faces = new window.cv.RectVector();
            const classifier = new window.cv.CascadeClassifier();
            const utils = new window.Utils('errorMessage');
            const faceCascadeFile = 'haarcascade_frontalface_default.xml';
            utils.createFileFromUrl(faceCascadeFile, faceCascadeFile, () => {
              classifier.load(faceCascadeFile);
              console.log("Classifier loaded:", classifier.empty() ? "Failed to load" : "Successfully loaded");
            });

            const processVideo = () => {
              if (!window.cv || !window.cv.Mat) {
                console.log('OpenCV.js is not loaded');
                return;
              } else {
                console.log('OpenCV.js is loaded');
              }

              let begin = Date.now();
              cap.read(src);
              console.log("process video 1");

              // Zoom the video frame
              let zoomedSrc = new window.cv.Mat();
              let zoomRect = new window.cv.Rect(
                src.cols / 2 - (src.cols / (2 * ZOOM_FACTOR)),
                src.rows / 2 - (src.rows / (2 * ZOOM_FACTOR)),
                src.cols / ZOOM_FACTOR,
                src.rows / ZOOM_FACTOR
              );
              zoomedSrc = src.roi(zoomRect);
              window.cv.resize(zoomedSrc, dst, new window.cv.Size(src.cols, src.rows), 0, 0, window.cv.INTER_LINEAR);
              console.log("process video 2");
              let clonedst = new window.cv.Mat();
              dst.copyTo(clonedst);

              instructionText.textContent = "Keep Your Face In The Frame";
              console.log("process video 3");

              // Perform face detection on the zoomed image
              let faces1 = new window.cv.RectVector();
              console.log("process video 3.1");
              let faces = new window.cv.RectVector();
              console.log("process video 3.2");
              try {
                console.log("process video 3.3");
                classifier.detectMultiScale(src, faces, 1.5, 3, 0);
                console.log("process video 3.4");
                classifier.detectMultiScale(src, faces1, 1.5, 3, 0);
                console.log("process video 4");
                console.log("Face size is " + faces.size() + faces1.size());
                console.log("process video 5");
                console.log("faces1.size: ", faces1.size());
                if (faces1.size() === 1) {
                  const face = faces.get(0);
                  const face1 = faces1.get(0);
                  const rect = new window.cv.Rect(face.x, face.y, face.width, face.height);
                  console.log("process video 6");

                  // Draw rectangle around the detected face
                  window.cv.rectangle(src, new window.cv.Point(face.x, face.y), new window.cv.Point(face.x + face.width, face.y + face.height), [0, 255, 0, 255], 2);

                  const bufferRatio = 0.14; // 14% buffer
                  let bufferedX = Math.max(0, face.x - face.width * bufferRatio);
                  let bufferedY = Math.max(0, face.y - face.height * bufferRatio);
                  let bufferedWidth = Math.min(src.cols - bufferedX, face.width * (1 + 2 * bufferRatio));
                  let bufferedHeight = Math.min(src.rows - bufferedY, face.height * (1 + 2 * bufferRatio));
                  console.log("process video 7");
                  const bufferedRect = new window.cv.Rect(bufferedX, bufferedY, bufferedWidth, bufferedHeight);
                  console.log("process video 8");

                  // Draw the buffered rectangle on the canvas
                  window.cv.rectangle(src, new window.cv.Point(bufferedRect.x, bufferedRect.y), new window.cv.Point(bufferedRect.x + bufferedRect.width, bufferedRect.y + bufferedRect.height), [5, 255, 0, 255], 2);
                  console.log("process video 9");

                  const faceArea = face1.width * face1.height;
                  const ovalArea = Math.PI * (canvas.width / 2) * (canvas.height / 2);
                  const faceAreaPercentage = (faceArea / ovalArea) * 100;
                  let faceDetectionCount = 0;
                  console.log("process video 10", face1.height);

                  if (!isFaceInsideOval(face1, canvas)) {
                    console.log("in is faceinsideoval if", faceAreaPercentage);
                    instructionText.textContent = "Move inside the oval window";
                    faceDetectionCount = 0;

                    instructionText.textContent = "Processing....";
                    faceDetectionCount++;
                    if (faceDetectionCount === 1) {
                      console.log("in if above upload()");
                      uploadBufferedFaceImage(bufferedRect);
                      showLoader();
                      return false;
                    }
                  }
                }
              } catch (err) {
                console.log(err);
              } finally {
                faces1.delete();
                faces.delete();
              }

              // Show the result on the canvas
              if (isCanvasVisible) {
                window.cv.flip(dst, dst, 1);
                window.cv.imshow("canvas_output", src);
              }

              let delay = 1000 / FPS - (Date.now() - begin);
              setTimeout(processVideo, delay);
            };

            const uploadBufferedFaceImage = (rect) => {
              console.log("in upload()");
              const videoCanvas = document.createElement('canvas');
              videoCanvas.width = video.videoWidth;
              videoCanvas.height = video.videoHeight;
              const videoCtx = videoCanvas.getContext('2d');
              videoCtx.drawImage(video, 0, 0, videoCanvas.width, videoCanvas.height);

              const cropCanvas = document.createElement('canvas');
              cropCanvas.width = rect.width;
              cropCanvas.height = rect.height;
              const cropCtx = cropCanvas.getContext('2d');

              const imageData = videoCtx.getImageData(rect.x, rect.y, rect.width, rect.height);
              cropCtx.putImageData(imageData, 0, 0);
              console.log("in mid upload()");
              cropCanvas.toBlob((blob) => {
                const formData = new FormData();
                formData.append('image', blob, 'buffered_face_image.jpg');

                fetch('http://192.168.0.144:8014/upload.php', {
                  method: 'POST',
                  body: formData
                })
                  .then(response => response.json())
                  .then(data => {
                    if (data.error) {
                      alert('Please try again. Something went wrong.');
                      console.log(data);
                    } else {
                      console.log('Image uploaded successfully');
                      const score = data.score;
                      console.log("in above last upload()", score);
                      if (score >= 50) {
                        window.location.href = 'verified.html';
                      } else {
                        window.location.href = 'failed.html';
                      }
                    }
                  })
                  .catch(error => {
                    console.error('Error uploading image:', error);
                    alert('Please try again. Something went wrong.');
                  });
              }, 'image/jpeg', 0.92);
            };

            setTimeout(processVideo, 0);
          });
        })
        .catch(function (err) {
          console.log("An error occurred! " + err);
        });
    };
  };

  const showLoader = () => {
    loaderRef.current.style.display = 'block';
  };

  const isFaceInsideOval = (face, canvas) => {
    const ovalCenterX = canvas.width / 2;
    const ovalCenterY = canvas.height / 2;
    const ovalRadiusX = canvas.width / 2;
    const ovalRadiusY = canvas.height / 2;

    const faceCenterX = face.x + face.width / 2;
    const faceCenterY = face.y + face.height / 2;

    const distanceX = (faceCenterX - ovalCenterX) ** 2 / (ovalRadiusX ** 2);
    const distanceY = (faceCenterY - ovalCenterY) ** 2 / (ovalRadiusY ** 2);
    console.log("isFaceInsideOvalfunctionend");
    return distanceX + distanceY <= 1;
  };

  // const handleClick = () => {
  //   console.log("Button clicked, setting showApp to true", showApp);

  //   // Save the state to local storage
  //   localStorage.setItem('showApp', 'true');

  //   // Reload the page
  //   window.location.reload();
  // };

  return (
        <div>
    {/* {!showApp ? (
      <button onClick={handleClick}>
        Initialize OpenCV
      </button>
    ) : ( */}
      <div className="container">
      <img id="powered-logo" src="purple_logo_accura.png" alt="Powered by Your Logo" />
      <p id="instructionText" ref={instructionTextRef}></p>
      <div className="camera-input">
        <video id="videoInput" ref={videoRef} width="640" height="480" autoPlay muted></video>
        <canvas id="canvas_output" ref={canvasRef} ></canvas>
      </div>
      <div id="loader" ref={loaderRef} className="loader" style={{ display: 'none' }}></div>
      <div id="response-text"></div>
      <div id="powered-by">
        <a href="https://ibeta.com/wp-content/uploads/2022/08/220816-Accura-Scan-PAD-Level-1-Confirmation-Letter.pdf" target="_blank">
          <img id="IBETA_logo" src="images/IBETA-Level-1.webp" alt="IBETA-Level-1" />
        </a>
        <a href="https://www.ibeta.com/wp-content/uploads/2023/07/230712-Accura-Scan-PAD-Level-2-APCER-Confirmation-Letter.pdf" target="_blank">
          <img style={{ paddingBottom: '3px' }} id="IBETA_logo" src="images/IBETA-Level-2.webp" alt="IBETA-Level-2" />
        </a>
      </div>
    </div>
    {/* )} */}
</div>
  );
};
// style={{ display: isCanvasVisible ? 'block' : 'none' }}
export default App;