import React, { useEffect, useRef, useState } from "react";
import { useNavigate } from "react-router-dom";
import PaginatedFormEditable from "./PaginatedFormEditable";
import Modal from "./Modal";
import Expetation from "./Expetation";
import LiquidGlassHeader from "./components/Header";
import { Loader2 } from "lucide-react";


/**
 * Perubahan utama:
 * 1) Tambah komponen <LoadingOverlay/> yang muncul saat `loading === true` di SEMUA step
 *    (kamera maupun upload).
 * 2) `handleManualUpload` sekarang memanggil `setLoading(true)` SEBELUM membaca file, agar
 *    animasi langsung tampil begitu user memilih file.
 * 3) Tombol-tombol dinonaktifkan ketika loading untuk mencegah double action.
 * 4) Tambah teks status akesibel (aria-live) agar ramah pembaca layar.
 */

const spinnerStyle = `
@keyframes spin { 
  0% { transform: rotate(0deg);} 
  100% { transform: rotate(360deg);} 
}
@keyframes dots {
  0% { content: "."; }
  33% { content: ".."; }
  66% { content: "..."; }
  100% { content: "."; }
}
.loading-dots::after { content: "."; animation: dots 1.2s infinite steps(3,end); }
`;

const styles = {
  sourceButton: {
    backgroundColor: "#5856d6",
    color: "white",
    padding: "16px 24px",
    borderRadius: "12px",
    border: "none",
    fontSize: "16px",
    fontWeight: "600",
    cursor: "pointer",
    margin: "8px 0",
    width: "200px",
    textAlign: "center",
    transition: "opacity .2s ease, transform .05s ease",
  },
  sourceButtonText: {
    color: "#666",
    fontSize: "16px",
    margin: "16px 0",
    fontWeight: "500",
  },
  cameraContainer: {
    position: "fixed",
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    backgroundColor: "black",
    zIndex: 1000,
    overflow: "hidden",
    display: "flex",
    flexDirection: "column",
  },
  backButton: {
    position: "absolute",
    top: "20px",
    left: "20px",
    backgroundColor: "rgba(255, 255, 255, 0.2)",
    color: "white",
    border: "none",
    borderRadius: "50%",
    width: "40px",
    height: "40px",
    fontSize: "18px",
    cursor: "pointer",
    zIndex: 1001,
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    backdropFilter: "blur(10px)",
    boxShadow: "0 2px 8px rgba(0,0,0,0.3)",
  },
  captureButton: {
    position: "absolute",
    bottom: "30px",
    left: "50%",
    transform: "translateX(-50%)",
    backgroundColor: "white",
    border: "3px solid rgba(255, 255, 255, 0.3)",
    borderRadius: "50%",
    width: "70px",
    height: "70px",
    fontSize: "24px",
    cursor: "pointer",
    zIndex: 1001,
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    boxShadow: "0 4px 12px rgba(0,0,0,0.4)",
    transition: "transform 0.1s ease",
  },
  canvas: {
    position: 'absolute',
    top: 0,
    left: 0,
    width: '100%',
    height: '100%',
    zIndex: 2,
    objectFit: 'cover',
  },
  guideText: {
    position: "absolute",
    top: "80px",
    left: "50%",
    transform: "translateX(-50%)",
    color: "white",
    fontSize: "16px",
    fontWeight: "500",
    zIndex: 1001,
    textAlign: "center",
    backgroundColor: "rgba(0, 0, 0, 0.5)",
    padding: "12px 20px",
    borderRadius: "20px",
    backdropFilter: "blur(10px)",
    maxWidth: "90%",
  },
  spinner: {
    border: "4px solid #f3f3f3",
    borderTop: "4px solid #429241",
    borderRadius: "50%",
    width: "44px",
    height: "44px",
    animation: "spin 1s linear infinite",
  },
  ctaBtn: {
    padding: "16px 24px",
    backgroundColor: "#5856d6",
    borderRadius: "12px",
    color: "white",
    fontWeight: "600",
    cursor: "pointer",
    textAlign: "center",
    margin: "8px auto",
    width: "200px",
    fontSize: "16px",
  },
};

/* ============================
   ORG & AUTH HELPERS
============================ */
const getCleanToken = () => {
  let raw = localStorage.getItem("token") || "";
  try { raw = JSON.parse(raw); } catch { }
  return String(raw).replace(/^"+|"+$/g, "");
};
const getSelectedOrganization = () => {
  let raw =
    localStorage.getItem("selected_organization") ??
    localStorage.getItem("select_organization");
  if (!raw) return null;
  try { return JSON.parse(raw); } catch { return raw; }
};
const getActiveOrgId = () => {
  const sel = getSelectedOrganization();
  if (!sel) return "";
  if (typeof sel === "object" && sel?.organization_id) return String(sel.organization_id);
  return String(sel);
};
const getActiveNamaType = (selectedDocumentType) => {
  if (!selectedDocumentType) return "";
  if (selectedDocumentType.id) return String(selectedDocumentType.id);
  if (selectedDocumentType.display_name) return String(selectedDocumentType.display_name);
  return "";
};
const authHeaders = ({ isJson = false } = {}) => {
  const token = getCleanToken();
  const orgId = getActiveOrgId();
  const base = {
    ...(token ? { Authorization: `Bearer ${token}` } : {}),
    ...(orgId ? { "X-Organization-Id": orgId } : {}),
  };
  return isJson ? { "Content-Type": "application/json", ...base } : base;
};

/* ============================
   KOMPPN: LoadingOverlay
============================ */
const LoadingOverlay = ({ message = "Memproses..." }) => (
   <div
    role="status" aria-live="assertive" aria-busy="true"
    style={{
    position: "fixed",
    inset: 0,
    background: "rgba(255,255,255,0.8)",
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
    justifyContent: "center",
    zIndex: 2000,              // <- kunci: lebih tinggi dari kamera/canvas
    backdropFilter: "blur(2px)"
    }}
  >
    <div style={styles.spinner} />
    <p className="mt-4 text-gray-700 font-medium">{message}</p>
  </div>
);



/* ============================
   MAIN COMPONENT
============================ */
const KTPScanner = () => {
  const navigate = useNavigate();
  const handleLogout = () => {
    localStorage.removeItem("token");
    localStorage.removeItem("user");
    window.location.reload();
  };

  // refs
  const videoRef = useRef(null);
  const canvasRef = useRef(null);
  const hiddenCanvasRef = useRef(null);
  const fileInputRef = useRef(null);
  const freezeFrameRef = useRef(null);
  const rectRef = useRef({ x: 0, y: 0, width: 0, height: 0, radius: 20 });

  // state
  const [step, setStep] = useState("document"); // "document" | "source" | "camera" | "preview"
  const [capturedImage, setCapturedImage] = useState(null);
  const [fileTemp, setFileTemp] = useState(null);
  const [isFreeze, setIsFreeze] = useState(false);
  const [loading, setLoading] = useState(false);
  const [selectedDocumentType, setSelectedDocumentType] = useState(null);
  const [cameraInitialized, setCameraInitialized] = useState(false);
  const [isScanned, setIsScanned] = useState(false);
  const [showSuccessMessage, setShowSuccessMessage] = useState(false);
  const [modalOpen, setModalOpen] = useState(false);

  /* ============================
     CAMERA FUNCTIONS - PORTRAIT OPTIMIZED
  ============================ */
  const drawRoundedRect = (ctx, x, y, width, height, radius) => {
    ctx.beginPath();
    ctx.moveTo(x + radius, y);
    ctx.lineTo(x + width - radius, y);
    ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
    ctx.lineTo(x + width, y + height - radius);
    ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
    ctx.lineTo(x + radius, y + height);
    ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
    ctx.lineTo(x, y + radius);
    ctx.quadraticCurveTo(x, y, x + radius, y);
    ctx.closePath();
    ctx.strokeStyle = "#fff";
    ctx.lineWidth = 3;
    ctx.stroke();

    const cornerSize = 25;
    ctx.strokeStyle = "#00ff88";
    ctx.lineWidth = 4;

    // Top-left
    ctx.beginPath();
    ctx.moveTo(x + radius, y);
    ctx.lineTo(x + radius + cornerSize, y);
    ctx.moveTo(x, y + radius);
    ctx.lineTo(x, y + radius + cornerSize);
    ctx.stroke();

    // Top-right
    ctx.beginPath();
    ctx.moveTo(x + width - radius - cornerSize, y);
    ctx.lineTo(x + width - radius, y);
    ctx.moveTo(x + width, y + radius);
    ctx.lineTo(x + width, y + radius + cornerSize);
    ctx.stroke();

    // Bottom-left
    ctx.beginPath();
    ctx.moveTo(x, y + height - radius - cornerSize);
    ctx.lineTo(x, y + height - radius);
    ctx.moveTo(x + radius, y + height);
    ctx.lineTo(x + radius + cornerSize, y + height);
    ctx.stroke();

    // Bottom-right
    ctx.beginPath();
    ctx.moveTo(x + width, y + height - radius - cornerSize);
    ctx.lineTo(x + width, y + height - radius);
    ctx.moveTo(x + width - radius - cornerSize, y + height);
    ctx.lineTo(x + width - radius, y + height);
    ctx.stroke();
  };

  const fillOutsideRect = (ctx, rect, canvasWidth, canvasHeight) => {
    ctx.save();
    const { x, y, width, height, radius } = rect;

    ctx.beginPath();
    ctx.moveTo(x + radius, y);
    ctx.lineTo(x + width - radius, y);
    ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
    ctx.lineTo(x + width, y + height - radius);
    ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
    ctx.lineTo(x + radius, y + height);
    ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
    ctx.lineTo(x, y + radius);
    ctx.quadraticCurveTo(x, y, x + radius, y);
    ctx.closePath();

    ctx.rect(0, 0, canvasWidth, canvasHeight);
    ctx.fillStyle = "rgba(0, 0, 0, 0.7)";
    ctx.fill("evenodd");
    ctx.restore();
  };

  const initializeCamera = async () => {
    try {
      if (typeof window !== "undefined" && window.screen?.orientation?.lock) {
        try { await window.screen.orientation.lock("potrait") ; } catch (e) {}
  }

      const pixelRatio = window.devicePixelRatio || 1;

      const constraints = {
        video: {
          facingMode: { ideal: "environment" },
          width: { ideal: 1280 },
          height: { ideal: 720 },
          frameRate: { ideal: 30, min: 15 }
        },
        audio: false,
      };

      const stream = await navigator.mediaDevices.getUserMedia(constraints);

      if (videoRef.current) {
        videoRef.current.srcObject = stream;

        videoRef.current.onloadedmetadata = () => {
          videoRef.current.play();

          setIsFreeze(false);
          freezeFrameRef.current = null;

          const video = videoRef.current;
          const canvas = canvasRef.current;
          const hiddenCanvas = hiddenCanvasRef.current;
          const ctx = canvas.getContext("2d");

          const viewportWidth = window.innerWidth;
          const viewportHeight = window.innerHeight;

          canvas.width = viewportWidth * pixelRatio;
          canvas.height = viewportHeight * pixelRatio;
          canvas.style.width = viewportWidth + 'px';
          canvas.style.height = viewportHeight + 'px';

          ctx.scale(pixelRatio, pixelRatio);

          hiddenCanvas.width = video.videoWidth;
          hiddenCanvas.height = video.videoHeight;

          const margin = 40;
          const topBottomMargin = 120;
          const availableWidth = viewportWidth - (margin * 2);
          const availableHeight = viewportHeight - (topBottomMargin * 2);
          const portraitRatio = 0.63;
          let rectWidth, rectHeight;
          rectWidth = Math.min(availableWidth * 0.85, 280);
          rectHeight = rectWidth / portraitRatio;
          if (rectHeight > availableHeight) {
            rectHeight = availableHeight;
            rectWidth = rectHeight * portraitRatio;
          }
          rectRef.current = {
            x: (viewportWidth - rectWidth) / 2,
            y: (viewportHeight - rectHeight) / 2,
            width: rectWidth,
            height: rectHeight,
            radius: 20,
          };

          const drawLoop = () => {
            if (video.readyState >= 2) {
              ctx.clearRect(0, 0, viewportWidth, viewportHeight);

              if (isFreeze && freezeFrameRef.current) {
                const tempCanvas = document.createElement('canvas');
                tempCanvas.width = freezeFrameRef.current.width;
                tempCanvas.height = freezeFrameRef.current.height;
                tempCanvas.getContext('2d').putImageData(freezeFrameRef.current, 0, 0);
                ctx.drawImage(tempCanvas, 0, 0, viewportWidth, viewportHeight);
              } else {
                const videoAspect = video.videoWidth / video.videoHeight;
                const screenAspect = viewportWidth / viewportHeight;
                let drawWidth, drawHeight, offsetX, offsetY;
                if (videoAspect > screenAspect) {
                  drawHeight = viewportHeight;
                  drawWidth = drawHeight * videoAspect;
                  offsetX = (viewportWidth - drawWidth) / 2;
                  offsetY = 0;
                } else {
                  drawWidth = viewportWidth;
                  drawHeight = drawWidth / videoAspect;
                  offsetX = 0;
                  offsetY = (viewportHeight - drawHeight) / 2;
                }
                ctx.drawImage(video, offsetX, offsetY, drawWidth, drawHeight);
              }

              if (!isFreeze) {
                fillOutsideRect(ctx, rectRef.current, viewportWidth, viewportHeight);
              }

              drawRoundedRect(
                ctx,
                rectRef.current.x,
                rectRef.current.y,
                rectRef.current.width,
                rectRef.current.height,
                rectRef.current.radius
              );
            }
            requestAnimationFrame(drawLoop);
          };

          drawLoop();
          setCameraInitialized(true);
        };
      }
    } catch (err) {
      console.error("Gagal mendapatkan kamera:", err);
      alert("Tidak dapat mengakses kamera. Pastikan browser memiliki izin kamera.");
    }
  };

  /* ============================
     CAPTURE & SCAN - PORTRAIT OPTIMIZED
  ============================ */
  const shootImage = async () => {
    const video = videoRef.current;
    const canvas = canvasRef.current;
    const { x, y, width, height } = rectRef.current;
    const hiddenCanvas = hiddenCanvasRef.current;
    const hiddenCtx = hiddenCanvas.getContext("2d");
    const visibleCtx = canvas.getContext("2d");

    // Munculkan loading segera ketika user menekan tombol tangkap
    setLoading(true);

    const pixelRatio = window.devicePixelRatio || 1;
    freezeFrameRef.current = visibleCtx.getImageData(0, 0, canvas.width, canvas.height);
    setIsFreeze(true);
    video.pause();

    hiddenCtx.drawImage(video, 0, 0, hiddenCanvas.width, hiddenCanvas.height);

    const viewportWidth = window.innerWidth;
    const viewportHeight = window.innerHeight;

    const videoAspect = video.videoWidth / video.videoHeight;
    const screenAspect = viewportWidth / viewportHeight;

    let videoDisplayWidth, videoDisplayHeight, videoOffsetX, videoOffsetY;

    if (videoAspect > screenAspect) {
      videoDisplayHeight = viewportHeight;
      videoDisplayWidth = videoDisplayHeight * videoAspect;
      videoOffsetX = (viewportWidth - videoDisplayWidth) / 2;
      videoOffsetY = 0;
    } else {
      videoDisplayWidth = viewportWidth;
      videoDisplayHeight = videoDisplayWidth / videoAspect;
      videoOffsetX = 0;
      videoOffsetY = (viewportHeight - videoDisplayHeight) / 2;
    }

    const scaleX = hiddenCanvas.width / videoDisplayWidth;
    const scaleY = hiddenCanvas.height / videoDisplayHeight;

    const cropX = (x - videoOffsetX) * scaleX;
    const cropY = (y - videoOffsetY) * scaleY;
    const cropWidth = width * scaleX;
    const cropHeight = height * scaleY;

    const finalCropX = Math.max(0, Math.min(cropX, hiddenCanvas.width - cropWidth));
    const finalCropY = Math.max(0, Math.min(cropY, hiddenCanvas.height - cropHeight));
    const finalCropWidth = Math.min(cropWidth, hiddenCanvas.width - finalCropX);
    const finalCropHeight = Math.min(cropHeight, hiddenCanvas.height - finalCropY);

    const cropCanvas = document.createElement("canvas");
    cropCanvas.width = Math.floor(finalCropWidth);
    cropCanvas.height = Math.floor(finalCropHeight);

    const cropCtx = cropCanvas.getContext("2d");
    cropCtx.drawImage(
      hiddenCanvas,
      Math.floor(finalCropX),
      Math.floor(finalCropY),
      Math.floor(finalCropWidth),
      Math.floor(finalCropHeight),
      0,
      0,
      Math.floor(finalCropWidth),
      Math.floor(finalCropHeight)
    );

    const imageData = cropCanvas.toDataURL("image/jpeg", 0.9);
    setCapturedImage(imageData);

   

    setLoading(false);
  };

  const base64ToFile = (base64Data, fileName) => {
    const arr = base64Data.split(",");
    const mime = arr[0].match(/:(.*?);/)[1];
    const bstr = atob(arr[1]);
    let n = bstr.length;
    const u8arr = new Uint8Array(n);
    while (n--) u8arr[n] = bstr.charCodeAt(n);
    return new File([u8arr], fileName, { type: mime });
  };

  const ReadImage = async (capturedImage) => {
    try {
      setLoading(true);
      const orgId = getActiveOrgId();
      const namaType = getActiveNamaType(selectedDocumentType);
      const file = base64ToFile(capturedImage, "image.jpg");
      const formData = new FormData();
      formData.append("image", file);
      formData.append("expectation", JSON.stringify(selectedDocumentType?.expectation || {}));
      if (orgId) formData.append("organization_id", orgId);
      if (namaType) formData.append("data_type_id", namaType);
      const res = await fetch("https://bot.kediritechnopark.com/webhook/solid-data/scan", {
        method: "POST",
        headers: authHeaders(),
        body: formData,
      });
      const data = await res.json();
      console.log("Scan result:", data);

      setLoading(false);
      if (data.responseCode === 409) {
        setFileTemp({ error: 409 });
      } else if (!data || Object.keys(data).length === 0) {
        setFileTemp({});
      } else {
        setFileTemp(data);
      }
      setIsScanned(true);
      setStep("preview");

    } catch (err) {
      console.error("Failed to read image:", err);
      setFileTemp({});
      setIsScanned(true);
      setLoading(false);
      setStep("preview");
    }
  };

  const handleSaveTemp = async (verifiedData) => {
    try {
      setLoading(true);
      const orgId = getActiveOrgId();
      const namaType = getActiveNamaType(selectedDocumentType);
      const formData = new FormData();
      formData.append("data", JSON.stringify(verifiedData));
      if (orgId) formData.append("organization_id", orgId);
      if (namaType) formData.append("data_type_id", namaType);

      await fetch("https://bot.kediritechnopark.com/webhook/solid-data/save", {
        method: "POST",
        headers: authHeaders(),
        body: formData,
      });

      setLoading(false);
      setFileTemp(null);
      setShowSuccessMessage(true);

      setTimeout(() => {
        setShowSuccessMessage(false);
        setIsFreeze(false);
        setIsScanned(false);
        setCapturedImage(null);
        setStep("source");
      }, 2000);
    } catch (err) {
      console.error("Gagal simpan:", err);
      setLoading(false);
    }
  };

  /* ============================
     HELPERS
  ============================ */
  const handleManualUpload = async (e) => {
    const file = e.target.files[0];
    if (!file) return;
    await new Promise(requestAnimationFrame);

    // TAMPILKAN LOADING SEGERA begitu user memilih file
    setLoading(true);

    const reader = new FileReader();
    reader.onloadend = async () => {
      setCapturedImage(reader.result);
      setIsFreeze(true);
      await ReadImage(reader.result);
      setStep("preview");
      // ReadImage sudah mengelola setLoading
    };
    reader.readAsDataURL(file);
  };

  const triggerFileSelect = () => fileInputRef.current?.click();
  const resetToSource = () => {
    setCapturedImage(null);
    setFileTemp(null);
    setIsFreeze(false);
    setIsScanned(false);
    setStep("source");
    if (videoRef.current?.srcObject) {
      videoRef.current.srcObject.getTracks().forEach((t) => t.stop());
    }
    if (typeof window !== "undefined" && window.screen?.orientation?.unlock) {
      window.screen.orientation.unlock() ;
    }
  };
  const handleRetake = () => {
  // bersihkan hasil freeze/capture dan balik ke live preview kamera
  setCapturedImage(null);
  setFileTemp(null);
  setIsScanned(false);
  setIsFreeze(false);
  try {
    videoRef.current?.play(); // lanjutkan stream kamera
  } catch {}
};

  const handleSelectDocumentType = (doc) => {
    setSelectedDocumentType(doc);
    setStep("source");
  };

  useEffect(() => {
    return () => {
      if (videoRef.current?.srcObject) {
        videoRef.current.srcObject.getTracks().forEach((t) => t.stop());
      }
      if (typeof window !== "undefined" && window.screen?.orientation?.unlock) {
        window.screen.orientation.unlock();
      }
    };
  }, []);

  /* ============================
     RENDER
  ============================ */
  return (
    <div>
      <style>{spinnerStyle}</style>

      {step !== "camera" && (
        <LiquidGlassHeader
          onLogout={handleLogout}
          scanButtonText="Dashboard"
          onScanClick={() => navigate("/dashboard")}
        />
      )}

      {/* STEP 1: PILIH DOKUMEN */}
      {step === "document" && <Expetation onSelect={handleSelectDocumentType} />}

      {/* STEP 2: PILIH SUMBER */}
      {step === "source" && (
        <div
          style={{
            display: "flex",
            flexDirection: "column",
            alignItems: "center",
            justifyContent: "center",
            minHeight: "80vh",
            padding: "20px",
            backgroundColor: "#f8f9fa",
          }}
        >
          <h3 style={{ marginBottom: 40, color: "#333", fontSize: 24 }}>Pilih Sumber Gambar</h3>

          <button
            style={{
              ...styles.sourceButton,
              opacity: loading ? 0.6 : 1,
              pointerEvents: loading ? "none" : "auto",
            }}
            disabled={loading}
            onClick={() => {
              setStep("camera");
              initializeCamera();
            }}
          >
            Ambil Gambar
          </button>

          <div style={styles.sourceButtonText}>Atau</div>

          <button
            style={{
              ...styles.sourceButton,
              opacity: loading ? 0.6 : 1,
              pointerEvents: loading ? "none" : "auto",
            }}
            disabled={loading}
            onClick={triggerFileSelect}
          >
            Upload Gambar
          </button>

          <input
            ref={fileInputRef}
            type="file"
            accept="image/*"
            onChange={handleManualUpload}
            style={{ display: "none" }}
          />

          <button
            style={{
              marginTop: 30,
              background: "transparent",
              border: "none",
              color: "#5856d6",
              fontSize: 16,
              fontWeight: 600,
              cursor: loading ? "not-allowed" : "pointer",
              textDecoration: "underline",
              opacity: loading ? 0.6 : 1,
            }}
            disabled={loading}
            onClick={() => setStep("document")}
          >
            ← Kembali ke Pilih Dokumen
          </button>
        </div>
      )}

      {/* STEP 3: KAMERA - PORTRAIT FULL SCREEN */}
      {step === "camera" && (
        <div style={styles.cameraContainer}>
          <video
            ref={videoRef}
            autoPlay
            playsInline
            muted
            style={{ position: "absolute", top: 0, left: 0, width: "100%", height: "100%", objectFit: "cover", zIndex: 1 }}
          />
          <canvas ref={canvasRef} style={styles.canvas} />
          <canvas ref={hiddenCanvasRef} style={{ display: "none" }} />

          <button onClick={resetToSource} style={styles.backButton} aria-label="Kembali">←</button>

          {!isFreeze && !loading && (
            <button
              style={{ ...styles.captureButton, transform: "translateX(-50%) scale(1)" }}
              onMouseDown={(e) => { e.target.style.transform = "translateX(-50%) scale(0.95)"; }}
              onMouseUp={(e) => { e.target.style.transform = "translateX(-50%) scale(1)"; }}
              onTouchStart={(e) => { e.target.style.transform = "translateX(-50%) scale(0.95)"; }}
              onTouchEnd={(e) => { e.target.style.transform = "translateX(-50%) scale(1)"; }}
              onClick={shootImage}
            >
              📷
            </button>
          )}

          {isFreeze && !loading && !isScanned && (
  <div
    style={{
      position: "absolute",
      bottom: 24,
      left: "50%",
      transform: "translateX(-50%)",
      display: "flex",
      gap: 12,
      zIndex: 1001,
    }}
  >
    {/* 1) Scan */}
    <button
      style={{
        backgroundColor: "#00ff88",
        color: "black",
        border: "none",
        borderRadius: 25,
        padding: "12px 24px",
        fontSize: 16,
        fontWeight: 600,
        cursor: "pointer",
        boxShadow: "0 4px 12px rgba(0,255,136,0.3)",
      }}
      onClick={() => ReadImage(capturedImage)}
    >
      Scan Dokumen
    </button>

    {/* 2) Ulangi (retake) — kamera tetap terbuka */}
    <button
      style={{
        backgroundColor: "#fff",
        color: "#111",
        border: "1px solid #e5e7eb",
        borderRadius: 25,
        padding: "12px 18px",
        fontSize: 16,
        fontWeight: 600,
        cursor: "pointer",
      }}
      onClick={handleRetake}
      aria-label="Ulangi ambil gambar"
      title="Ulangi ambil gambar"
    >
      Ulangi
    </button>

    {/* 3) Hapus & kembali ke pilih sumber */}
    <button
      style={{
        backgroundColor: "#f3f4f6",
        color: "#111",
        border: "1px solid #e5e7eb",
        borderRadius: 25,
        padding: "12px 18px",
        fontSize: 16,
        fontWeight: 600,
        cursor: "pointer",
      }}
      onClick={resetToSource}
      aria-label="Hapus & kembali ke pilih sumber"
    >
      Hapus
    </button>
  </div>
)}


        </div>
      )}

      {/* HASIL SCAN (kamera atau upload) */}
      {capturedImage && step !== "camera" && (
        <div style={{ textAlign: "center", marginTop: 20, padding: 20 }}>
          {!isScanned ? (
            <>
              <h4>Memproses Gambar...</h4>
              <img src={capturedImage} alt="Preview" style={{ maxWidth: "100%", borderRadius: 8, opacity: 0.9 }} />
            </>
          ) : fileTemp && fileTemp.error !== 409 ? (
            <>
              <img src={capturedImage} alt="Preview" style={{ maxWidth: "100%", borderRadius: 8, marginBottom: 20 }} />
              <PaginatedFormEditable data={fileTemp} handleSimpan={handleSaveTemp} />

              <div style={{ marginTop: 16 }}>
                <button
                  onClick={resetToSource}
                  style={{
                    padding: "12px 16px",
                    borderRadius: 10,
                    background: "#f3f4f6",
                    border: "1px solid #e5e7eb",
                    fontWeight: 600,
                    cursor: "pointer",
                  }}
                >
                  Hapus & Pilih Ulang
                </button>
              </div>

            </>
          ) : fileTemp && (
            <>
              <img src={capturedImage} alt="Preview" style={{ maxWidth: "100%", borderRadius: 8, marginBottom: 20 }} />
              <h4>Dokumen Sudah Terdaftar</h4>
              <h4 style={{ cursor: "pointer" }} onClick={resetToSource}>Hapus</h4>
            </>
          )}
        </div>
      )}

      <Modal
        isOpen={modalOpen}
        onClose={() => setModalOpen(false)}
        loading={loading}
        fileTemp={fileTemp}
        onSave={handleSaveTemp}
      />

      {showSuccessMessage && (
        <div
          style={{
            position: "fixed",
            top: "50%",
            left: "50%",
            transform: "translate(-50%, -50%)",
            backgroundColor: "rgba(0, 255, 136, 0.9)",
            color: "black",
            padding: "20px 30px",
            borderRadius: 12,
            fontSize: 18,
            fontWeight: 600,
            zIndex: 2100,
            boxShadow: "0 4px 20px rgba(0,0,0,0.3)",
          }}
        >
          ✅ Data berhasil disimpan!
        </div>
      )}

      {/* GLOBAL OVERLAY: tampil di SEMUA step ketika loading */}
      {loading && (
        <LoadingOverlay message="Memindai gambar" />
      )}
    </div>
  );
};

export default KTPScanner;
