import { useState, useRef, useEffect } from "react";
import "./VoiceStatusWidget.css";
// Pre-recorded MP3s — no browser TTS dependency (fixes Android)
import arPromptAudio from "../assets/audio/ar_prompt.mp3";
import arNoSelectionAudio from "../assets/audio/ar_no_selection.mp3";
import enStatusPromptAudio from "../assets/audio/en_status_prompt.mp3";
import enNoSelectionAudio from "../assets/audio/en_no_selection_prompt.mp3";

// ─── Defaults (Work Order) ────────────────────────────────────────────────────
const DEFAULT_STATUS_OPTIONS = [
  { value: "Open",             label: "Open",             keywords: ["open"],             color: "not-started", icon: "⏳" },
  { value: "Work In Progress", label: "Work In Progress", keywords: ["work in progress"], color: "in-progress",  icon: "🔄" },
  { value: "Closed",           label: "Closed",           keywords: ["closed"],           color: "completed",   icon: "✅" },
];

function detectStatus(text, options) {
  if (!text) return null;
  const t = text.toLowerCase().trim();
  for (const opt of options) {
    if (opt.keywords.some((k) => new RegExp(`(^|[\\s،,])${k}([\\s،,]|$)`, "i").test(t)))
      return opt.value;
  }
  return null;
}

const NUM_BARS = 18;
const SR = window.SpeechRecognition || window.webkitSpeechRecognition;



// ─── Component ────────────────────────────────────────────────────────────────
export default function VoiceStatusWidget({
  onStatusConfirmed,
  selectedCount = 0,
  selectedNames = [],
  isUpdating = false,
  statusOptions = DEFAULT_STATUS_OPTIONS,
  widgetTitle = "Voice Status Update",
  showLanguageToggle = false,
  noSelectionLabel = "project",
}) {
  const [phase, setPhase]                   = useState(selectedCount === 0 ? "noselection" : "prompted");
  const [transcript, setTranscript]         = useState("");
  const [detectedStatus, setDetectedStatus] = useState(null);
  const [confirmed, setConfirmed]           = useState(false);
  const [barHeights, setBarHeights]         = useState(Array(NUM_BARS).fill(4));
  const [lang, setLang]                     = useState("en");

  const audioCtxRef  = useRef(null);
  const sourceRef    = useRef(null);
  const animFrameRef = useRef(null);
  const recEnRef     = useRef(null);
  const recArRef     = useRef(null);
  const streamRef    = useRef(null);
  const autoStopRef  = useRef(null);
  const calledRef    = useRef(false);
  const detectedRef  = useRef(null);

  const enLabels = statusOptions.map((o) => o.label).join(", ");
  const arLabels = statusOptions.map((o) => o.arLabel || o.label).join("، ");

  const enPrompt = `Please say the status: ${enLabels}.`;
  const arPrompt = `من فضلك قل الحالة: ${arLabels}.`;

  const noSelectionMsg = `Please select at least one ${noSelectionLabel} from the list in order to continue.`;
  const arNoSelectionMsg = "من فضلك اختر مشروعاً واحداً على الأقل من القائمة للمتابعة";

  const speakHint = lang === "ar"
    ? `قل: ${arLabels}`
    : `Say: ${enLabels}`;

  function playPromptForLang(currentLang) {
    const isAr = currentLang === "ar";
    const audioFile = isAr ? arPromptAudio : enStatusPromptAudio;
    const audio = new Audio(audioFile);
    audio.onended = () => setPhase("ready");
    audio.onerror = () => setPhase("ready");
    audio.play().catch(() => setPhase("ready"));
  }

  // Mount
  useEffect(() => {
    if (selectedCount === 0) {
      // Play English MP3 first, then Arabic MP3
      const enAudio = new Audio(enNoSelectionAudio);
      enAudio.onended = () => {
        const arAudio = new Audio(arNoSelectionAudio);
        arAudio.play().catch(() => {});
      };
      enAudio.onerror = () => {
        const arAudio = new Audio(arNoSelectionAudio);
        arAudio.play().catch(() => {});
      };
      enAudio.play().catch(() => {});
      return;
    }
    const timer = setTimeout(() => playPromptForLang(lang), 1000);
    return () => { clearTimeout(timer); cleanup(); };
  }, []);

  // Re-play when language tab changes
  const isFirstLangRender = useRef(true);
  useEffect(() => {
    if (isFirstLangRender.current) { isFirstLangRender.current = false; return; }
    if (selectedCount === 0) return;
    if (phase === "listening" || phase === "detected") return;
    if (window.speechSynthesis) window.speechSynthesis.cancel();
    setPhase("prompted");
    const capturedLang = lang;
    const timer = setTimeout(() => playPromptForLang(capturedLang), 400);
    return () => clearTimeout(timer);
  }, [lang]);

  function cleanup() {
    if (autoStopRef.current)  clearTimeout(autoStopRef.current);
    if (animFrameRef.current) cancelAnimationFrame(animFrameRef.current);
    if (sourceRef.current)    { sourceRef.current.disconnect(); sourceRef.current = null; }
    if (audioCtxRef.current)  { audioCtxRef.current.close();    audioCtxRef.current = null; }
    if (streamRef.current)    { streamRef.current.getTracks().forEach((t) => t.stop()); streamRef.current = null; }
    [recEnRef, recArRef].forEach((ref) => {
      if (ref.current) { try { ref.current.stop(); } catch (_) {} ref.current = null; }
    });
    setBarHeights(Array(NUM_BARS).fill(4));
  }

  async function startWaveform() {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      streamRef.current = stream;
      const ctx = new (window.AudioContext || window.webkitAudioContext)();
      audioCtxRef.current = ctx;
      const analyser = ctx.createAnalyser();
      analyser.fftSize = 64;
      const src = ctx.createMediaStreamSource(stream);
      sourceRef.current = src;
      src.connect(analyser);
      const data = new Uint8Array(analyser.frequencyBinCount);
      function frame() {
        animFrameRef.current = requestAnimationFrame(frame);
        analyser.getByteFrequencyData(data);
        setBarHeights(
          Array.from({ length: NUM_BARS }, (_, i) => {
            const idx = Math.floor((i * data.length) / NUM_BARS);
            return 4 + (data[idx] / 255) * 22;
          })
        );
      }
      frame();
    } catch (_) {}
  }

  function buildRecognition(language, onResult) {
    if (!SR) return null;
    const rec = new SR();
    rec.lang = language;
    rec.interimResults = false; // No interim — only final results, prevents Android duplicates
    rec.continuous = false;     // Single utterance — stops after one complete phrase
    rec.maxAlternatives = 3;
    rec.onresult = (e) => {
      // Use resultIndex to get only the new result, not the full cumulative array
      const r = e.results[e.resultIndex];
      if (r && r.isFinal) {
        const text = r[0].transcript.trim();
        if (text) onResult(text, true);
      }
    };
    rec.onerror = () => {};
    rec.onend   = () => {};
    return rec;
  }

  async function handleSpeak() {
    setPhase("listening");
    setTranscript("");
    detectedRef.current = null;
    await startWaveform();

    if (!SR) { cleanup(); setPhase("ready"); return; }

    const recLang = lang === "ar" ? "ar-SA" : "en-US";
    let finalTextAccum = "";

    const handleResult = (text, isFinal) => {
      // Guard: if already detected, ignore all subsequent results (fixes Android duplicate firing)
      if (calledRef.current || detectedRef.current) return;
      setTranscript(text);
      const s = detectStatus(text, statusOptions);
      if (s) {
        // Set BOTH flags immediately — before cleanup/setTimeout to block any further results
        calledRef.current = true;
        detectedRef.current = s;
        setDetectedStatus(s);
        setPhase("detected");
        cleanup();
        setTimeout(() => {
          onStatusConfirmed?.(s);
        }, 800);
        return;
      }
      if (isFinal) finalTextAccum += text + " ";
    };

    const handleFinalNoMatch = () => {
      if (detectedRef.current || calledRef.current) return;
      if (!finalTextAccum.trim()) return;
      setPhase("notunderstood");
      cleanup();
      const isAr = lang === "ar";
      if (isAr) {
        // For Arabic retry — just go back to ready, text shown in UI
        setTimeout(() => setPhase("ready"), 1500);
      } else {
        smartSpeak({
          text:    `Please pick only from one of the values provided: ${enLabels}.`,
          lang:    "en-US",
          onEnd:   () => setPhase("ready"),
          onError: () => setPhase("ready"),
        });
      }
    };

    const rec = buildRecognition(recLang, handleResult);
    if (!rec) { cleanup(); setPhase("ready"); return; }

    recEnRef.current = rec;
    rec.onend = () => {
      if (!detectedRef.current && !calledRef.current) handleFinalNoMatch();
    };
    try { rec.start(); } catch (_) {}

    autoStopRef.current = setTimeout(() => {
      cleanup();
      setPhase((prev) => (prev === "listening" ? "ready" : prev));
    }, 8000);
  }

  function handleManualSelect(status) {
    if (calledRef.current) return;
    setDetectedStatus(status);
    detectedRef.current = status;
    setTranscript(`Selected: ${status}`);
    setPhase("detected");
    cleanup();
    setTimeout(() => {
      if (onStatusConfirmed && !calledRef.current) {
        calledRef.current = true;
        onStatusConfirmed(status);
      }
    }, 800);
  }

  function handleReset() {
    cleanup();
    calledRef.current   = false;
    detectedRef.current = null;
    setTranscript("");
    setDetectedStatus(null);
    setConfirmed(false);
    if (selectedCount === 0) {
      setPhase("noselection");
      smartSpeak({ text: noSelectionMsg, lang: "en-US", onEnd: () => {}, onError: () => {} });
    } else {
      setPhase("prompted");
      setTimeout(() => playPromptForLang(lang), 500);
    }
  }

  const cfg      = detectedStatus ? statusOptions.find((o) => o.value === detectedStatus) : null;
  const isArabic = lang === "ar";

  return (
    <div className="vsw-card">
      <div className="vsw-header">
        <div className="vsw-logo">🛠️</div>
        <div className="vsw-brand">SEERA<span>-ASM</span></div>
        {selectedCount > 0 && <span className="vsw-selected-badge">{selectedCount} selected</span>}
      </div>

      <div className="vsw-title">{widgetTitle}</div>
      <div className="vsw-subtitle">
        {selectedCount === 0
          ? `No ${noSelectionLabel}s selected`
          : `Updating ${selectedCount} record${selectedCount > 1 ? "s" : ""}`}
      </div>

      {/* 2-tab language toggle */}
      {showLanguageToggle && selectedCount > 0 && (
        <div style={{
          display: "flex", gap: 6, marginBottom: 14,
          background: "#f1f5f9", borderRadius: 10, padding: 4,
        }}>
          {[{ key: "en", label: "English" }, { key: "ar", label: "عربي" }].map(({ key, label }) => (
            <button
              key={key}
              onClick={() => setLang(key)}
              style={{
                flex: 1, padding: "6px 0", borderRadius: 7, border: "none",
                fontSize: 12, fontWeight: 600, cursor: "pointer", transition: "all 0.15s",
                background: lang === key ? "#fff" : "transparent",
                color: lang === key ? "#2563eb" : "#64748b",
                boxShadow: lang === key ? "0 1px 4px rgba(0,0,0,0.1)" : "none",
              }}
            >
              {label}
            </button>
          ))}
        </div>
      )}

      {/* No selection */}
      {phase === "noselection" && (
        <div style={{
          display: "flex", alignItems: "flex-start", gap: 12, padding: 16, marginBottom: 16,
          background: "#fffbeb", border: "1px solid #fde68a", borderRadius: 10,
        }}>
          <span style={{ fontSize: 20, flexShrink: 0 }}>⚠️</span>
          <div style={{ width: "100%" }}>
            {/* English */}
            <p style={{ fontWeight: 700, fontSize: 14, color: "#92400e", margin: "0 0 2px" }}>
              No {noSelectionLabel}s selected
            </p>
            <p style={{ fontSize: 13, color: "#b45309", margin: "0 0 10px", lineHeight: 1.5 }}>
              Please select at least one {noSelectionLabel} from the list in order to continue.
            </p>
            {/* Arabic */}
            <p style={{ fontWeight: 700, fontSize: 14, color: "#92400e", margin: "0 0 2px", direction: "rtl", textAlign: "right" }}>
              لم يتم اختيار أي مشروع
            </p>
            <p style={{ fontSize: 13, color: "#b45309", margin: 0, lineHeight: 1.5, direction: "rtl", textAlign: "right" }}>
              من فضلك اختر مشروعاً واحداً على الأقل من القائمة للمتابعة
            </p>
          </div>
        </div>
      )}

      {selectedCount > 0 && (
        <>
          {selectedNames.length > 0 && (
            <div className="vsw-wo-list">
              {selectedNames.slice(0, 3).map((n) => <span key={n} className="vsw-wo-tag">{n}</span>)}
              {selectedNames.length > 3 && <span className="vsw-wo-tag vsw-wo-tag--more">+{selectedNames.length - 3} more</span>}
            </div>
          )}

          <div className="vsw-status-row">
            {statusOptions.map((opt) => (
              <div
                key={opt.value}
                className={`vsw-pill ${detectedStatus === opt.value ? `vsw-pill--active vsw-pill--${opt.color}` : ""}`}
                onClick={() => handleManualSelect(opt.value)}
                title="Click to select manually"
              >
                <span className={`vsw-dot vsw-dot--${opt.color}`} />
                <span>{isArabic ? (opt.arLabel || opt.label) : opt.label}</span>
              </div>
            ))}
          </div>

          <div className="vsw-action-area">
            {phase === "prompted" && (
              <div className="vsw-status-message vsw-status-message--speaking">
                <div className="vsw-speaking-icon">🔊</div>
                <div className="vsw-speaking-text">{isArabic ? "يرجى الانتظار…" : "Please wait…"}</div>
                <div className="vsw-speaking-dots"><span /><span /><span /></div>
              </div>
            )}

            {phase === "ready" && (
              <>
                {/* Arabic text prompt — shown since no Arabic audio */}
                {isArabic && (
                  <div style={{
                    width: "100%", padding: "12px 16px", marginBottom: 8,
                    background: "#f0f9ff", border: "1px solid #bae6fd",
                    borderRadius: 10, textAlign: "right", direction: "rtl",
                  }}>
                    <p style={{ margin: 0, fontSize: 14, fontWeight: 600, color: "#0369a1" }}>
                      {arPrompt}
                    </p>
                  </div>
                )}
                <button className="vsw-speak-btn" onClick={handleSpeak}>
                  <div className="vsw-speak-btn-icon">🎙️</div>
                  <div className="vsw-speak-btn-text">
                    <span className="vsw-speak-btn-title">{isArabic ? "اضغط للتحدث" : "Tap to Speak"}</span>
                    <span className="vsw-speak-btn-hint">{speakHint}</span>
                  </div>
                </button>
              </>
            )}

            {phase === "listening" && (
              <div className="vsw-listening-area">
                <div className="vsw-mic-active">🔴</div>
                <div className="vsw-waveform vsw-waveform--active">
                  {barHeights.map((h, i) => <div key={i} className="vsw-bar" style={{ height: `${h}px` }} />)}
                </div>
                <div className="vsw-mic-label vsw-mic-label--listening">
                  {isArabic ? "جاري الاستماع… تحدث الآن" : "Listening… speak now"}
                </div>
                {transcript && (
                  <div style={{
                    marginTop: 8, padding: "6px 12px", background: "#f8fafc",
                    border: "1px solid #e2e8f0", borderRadius: 8, fontSize: 13,
                    color: "#1e293b", maxWidth: "100%", direction: isArabic ? "rtl" : "ltr",
                  }}>
                    {transcript}
                  </div>
                )}
              </div>
            )}

            {phase === "detected" && cfg && (
              <div className="vsw-status-message vsw-status-message--detected">
                {cfg.icon}&nbsp;{isArabic ? "تم اكتشاف الحالة!" : "Status detected!"}
              </div>
            )}

            {phase === "notunderstood" && (
              <div className="vsw-status-message vsw-status-message--notunderstood">
                ⚠️ {isArabic ? "من فضلك اختر من القيم المتاحة" : "Please pick only from one of the values provided"}
              </div>
            )}
          </div>

          {transcript && phase !== "listening" && (
            <div className="vsw-transcript vsw-transcript--filled" style={{ direction: isArabic ? "rtl" : "ltr" }}>
              {transcript}
            </div>
          )}
        </>
      )}

      <hr className="vsw-divider" />

      <div className="vsw-actions">
        <button className="vsw-btn vsw-btn--ghost" onClick={handleReset} disabled={isUpdating}>
          {isArabic ? "إعادة" : "Reset"}
        </button>
        {isUpdating && <button className="vsw-btn vsw-btn--primary" disabled>{isArabic ? "جاري التحديث…" : "Updating…"}</button>}
        {confirmed  && <button className="vsw-btn vsw-btn--confirmed vsw-btn--primary" disabled>{isArabic ? "تم التحديث!" : "Updated!"}</button>}
      </div>
    </div>
  );
}