import React, { useState, useEffect, useRef, useCallback } from 'react';

const COLLECT_MS = 2000;
const CENTER_MS = 3000;
const VERIFY_MS = 3000;

function CalibrationOverlay({ calibration, videoManager }) {
  const [progress, setProgress] = useState(0);
  const timerRef = useRef(null);
  const startRef = useRef(null);
  const overlayRef = useRef(null);

  const enterFullscreen = useCallback(() => {
    const el = overlayRef.current;
    if (!el) return;
    const req = el.requestFullscreen || el.webkitRequestFullscreen || el.msRequestFullscreen;
    if (req) req.call(el).catch(() => {});
  }, []);

  const exitFullscreen = useCallback(() => {
    if (document.fullscreenElement || document.webkitFullscreenElement) {
      const exit = document.exitFullscreen || document.webkitExitFullscreen || document.msExitFullscreen;
      if (exit) exit.call(document).catch(() => {});
    }
  }, []);

  useEffect(() => {
    if (calibration && calibration.active && !calibration.done) {
      const t = setTimeout(enterFullscreen, 100);
      return () => clearTimeout(t);
    }
  }, [calibration?.active, calibration?.done, enterFullscreen]);

  useEffect(() => {
    if (!calibration || !calibration.active) exitFullscreen();
  }, [calibration?.active, exitFullscreen]);

  /* eslint-disable react-hooks/set-state-in-effect -- progress resets when parent calibration phase idles */
  useEffect(() => {
    if (!calibration || !calibration.collecting || calibration.done) {
      setProgress(0);
      if (timerRef.current) cancelAnimationFrame(timerRef.current);
      return;
    }

    startRef.current = performance.now();
    const duration = calibration.verifying ? VERIFY_MS : (calibration.index === 0 ? CENTER_MS : COLLECT_MS);

    const tick = () => {
      const pct = Math.min((performance.now() - startRef.current) / duration, 1);
      setProgress(pct);
      if (pct >= 1) {
        if (videoManager) videoManager.nextCalibrationPoint();
        startRef.current = performance.now();
        setProgress(0);
      }
      timerRef.current = requestAnimationFrame(tick);
    };
    timerRef.current = requestAnimationFrame(tick);

    return () => { if (timerRef.current) cancelAnimationFrame(timerRef.current); };
  }, [calibration?.index, calibration?.collecting, calibration?.done, calibration?.verifying, videoManager]);
  /* eslint-enable react-hooks/set-state-in-effect */

  const handleCancel = () => {
    if (videoManager) videoManager.cancelCalibration();
    exitFullscreen();
  };

  if (!calibration || !calibration.active) return null;

  if (calibration.done) {
    const success = calibration.success;
    return (
      <div ref={overlayRef} className="cal-overlay">
        <div className={`cal-done-card ${success ? 'cal-done-success' : 'cal-done-fail'}`}>
          <div className="cal-done-eyebrow">
            {success ? 'Complete' : 'Failed'}
          </div>
          <h2 className="cal-done-title">
            {success ? 'Calibration Complete' : 'Calibration Failed'}
          </h2>
          <p className="cal-done-subtitle">
            {success
              ? 'Gaze tracking is now active.'
              : 'Not enough samples collected. Try again.'}
          </p>
        </div>
      </div>
    );
  }

  const [tx, ty] = calibration.target || [0.5, 0.5];
  const isVerifying = calibration.verifying;
  const accent = isVerifying ? '#007BFF' : '#28a745';
  const glow = isVerifying ? 'rgba(0, 123, 255, 0.6)' : 'rgba(40, 167, 69, 0.6)';

  return (
    <div ref={overlayRef} className="cal-overlay">
      <div className="cal-header">
        {isVerifying ? (
          <>
            <span className="cal-eyebrow cal-eyebrow-verify">Verification</span>
            <p className="cal-instruction">
              Look at the dot to confirm calibration accuracy
            </p>
          </>
        ) : (
          <>
            <span className="cal-eyebrow cal-eyebrow-collect">
              Point {calibration.index + 1} of {calibration.numPoints}
            </span>
            <p className="cal-instruction">
              {calibration.index === 0
                ? 'Look at the center dot \u2014 this sets your baseline'
                : 'Hold your gaze steady on the target'}
            </p>
          </>
        )}
      </div>

      <div
        className="cal-target"
        style={{ left: `${tx * 100}%`, top: `${ty * 100}%` }}
      >
        <svg width="60" height="60" className="cal-ring">
          <circle cx="30" cy="30" r="24" fill="none" stroke="rgba(255,255,255,0.12)" strokeWidth="3" />
          <circle
            cx="30" cy="30" r="24" fill="none" stroke={accent} strokeWidth="3"
            strokeDasharray={`${progress * 150.8} 150.8`} strokeLinecap="round"
            transform="rotate(-90, 30, 30)"
          />
        </svg>
        <div
          className="cal-dot"
          style={{
            background: `radial-gradient(circle, #fff 30%, ${accent} 100%)`,
            boxShadow: `0 0 24px ${glow}`,
          }}
        />
      </div>

      <button onClick={handleCancel} className="cal-cancel">
        Cancel Calibration
      </button>
    </div>
  );
}

export default CalibrationOverlay;
