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

export default function CameraSelfieCapture({ label = "Selfie", onChange, required = false }) {
  const videoRef = useRef(null);
  const streamRef = useRef(null);
  const [status, setStatus] = useState("idle");
  const [error, setError] = useState("");
  const [previewUrl, setPreviewUrl] = useState("");

  const stopStream = useCallback(() => {
    if (streamRef.current) {
      streamRef.current.getTracks().forEach((track) => track.stop());
      streamRef.current = null;
    }
    if (videoRef.current) {
      videoRef.current.srcObject = null;
    }
  }, []);

  const startCamera = useCallback(async () => {
    setError("");
    stopStream();
    if (previewUrl) {
      URL.revokeObjectURL(previewUrl);
      setPreviewUrl("");
      onChange?.(null);
    }

    if (!navigator.mediaDevices?.getUserMedia) {
      setError("Camera access is not supported in this browser.");
      setStatus("error");
      return;
    }

    setStatus("starting");
    try {
      const stream = await navigator.mediaDevices.getUserMedia({
        video: { facingMode: "user" },
        audio: false
      });
      streamRef.current = stream;
      if (videoRef.current) {
        videoRef.current.srcObject = stream;
        await videoRef.current.play();
      }
      setStatus("live");
    } catch (err) {
      const msg =
        err?.name === "NotAllowedError"
          ? "Camera permission denied. Allow camera access to take a selfie."
          : err?.message || "Could not open camera.";
      setError(msg);
      setStatus("error");
    }
  }, [onChange, previewUrl, stopStream]);

  useEffect(() => {
    startCamera();
    return () => {
      stopStream();
      if (previewUrl) URL.revokeObjectURL(previewUrl);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  function captureSelfie() {
    const video = videoRef.current;
    if (!video || !video.videoWidth) return;

    const canvas = document.createElement("canvas");
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    const ctx = canvas.getContext("2d");
    ctx.drawImage(video, 0, 0);

    canvas.toBlob(
      (blob) => {
        if (!blob) return;
        stopStream();
        if (previewUrl) URL.revokeObjectURL(previewUrl);
        const url = URL.createObjectURL(blob);
        setPreviewUrl(url);
        onChange?.(blob);
        setStatus("captured");
      },
      "image/jpeg",
      0.92
    );
  }

  function retake() {
    if (previewUrl) URL.revokeObjectURL(previewUrl);
    setPreviewUrl("");
    onChange?.(null);
    startCamera();
  }

  return (
    <div className="ptw-camera-selfie">
      <span className="ptw-mgmt-field__label">
        {label}
        {required ? <em className="ptw-mgmt-required"> *</em> : null}
      </span>
      <p className="ptw-mgmt-type-format__hint">
        Use your device camera to take a live selfie. File uploads are not allowed.
      </p>

      {error ? <p className="ptw-camera-selfie__error" role="alert">{error}</p> : null}

      <div className="ptw-camera-selfie__viewport">
        {status === "captured" && previewUrl ? (
          <img src={previewUrl} alt="Captured selfie preview" className="ptw-camera-selfie__preview" />
        ) : (
          <video
            ref={videoRef}
            className="ptw-camera-selfie__video"
            playsInline
            muted
            aria-label="Live camera preview"
          />
        )}
        {status === "starting" ? (
          <span className="ptw-camera-selfie__overlay">Opening camera…</span>
        ) : null}
      </div>

      <div className="ptw-camera-selfie__actions">
        {status === "captured" ? (
          <button type="button" className="swi-btn swi-btn--ghost" onClick={retake}>
            Retake selfie
          </button>
        ) : (
          <>
            <button
              type="button"
              className="swi-btn swi-btn--primary"
              onClick={captureSelfie}
              disabled={status !== "live"}
            >
              Capture selfie
            </button>
            {status === "error" ? (
              <button type="button" className="swi-btn swi-btn--ghost" onClick={startCamera}>
                Retry camera
              </button>
            ) : null}
          </>
        )}
      </div>
    </div>
  );
}
