// ============================================================================
// public/features/calls/dialer.jsx — live AI Dialer
// ----------------------------------------------------------------------------
// Pick an AI model (Hidrogen / OpenAI / Gemini …), write the call prompt,
// enter a number, and dial. The call goes out over the tenant's GSM, the AI
// talks two-way with the callee, and the transcript streams in live (polled
// from GET /api/calls/live/:uuid). Hang up any time.
// ============================================================================

function DialerScreen() {
  const [models, setModels] = React.useState([]);
  const [voices, setVoices] = React.useState({});
  const [form, setForm] = React.useState({
    number: "",
    model: "",
    voice: "",
    greeting: "Hello! This is an AI assistant calling. How are you today?",
    systemPrompt: "You are a friendly, concise AI calling assistant. Speak naturally, listen, and keep replies short.",
  });
  const [call, setCall] = React.useState(null);     // { uuid, code }
  const [live, setLive] = React.useState(null);     // { call, transcript[], lastEvent }
  const [dialing, setDialing] = React.useState(false);
  const [err, setErr] = React.useState(null);
  const pollRef = React.useRef(null);
  const transcriptEndRef = React.useRef(null);

  // Load available models once.
  React.useEffect(() => {
    VoaisAPI.get("/api/flows/test/models").then(r => {
      if (r.ok && r.data?.ok) {
        const ms = r.data.models || [];
        setModels(ms);
        setVoices(r.data.voices || {});
        // default to first available model, else first model
        const def = ms.find(m => m.available) || ms[0];
        if (def) setForm(f => ({ ...f, model: def.id }));
      }
    });
  }, []);

  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const ACTIVE = ["initiated", "ringing", "answered", "in_progress"];
  const isActive = live && ACTIVE.includes(live.call?.status);

  // Poll one call while it's active.
  const startPolling = React.useCallback((uuid) => {
    clearInterval(pollRef.current);
    const tick = async () => {
      const r = await VoaisAPI.get(`/api/calls/live/${uuid}`);
      if (r.ok && r.data?.ok) {
        setLive(r.data);
        if (!ACTIVE.includes(r.data.call?.status)) clearInterval(pollRef.current);
      }
    };
    tick();
    pollRef.current = setInterval(tick, 1500);
  }, []);

  React.useEffect(() => () => clearInterval(pollRef.current), []);
  React.useEffect(() => {
    if (transcriptEndRef.current) transcriptEndRef.current.scrollIntoView({ behavior: "smooth" });
  }, [live?.transcript?.length]);

  const dial = async () => {
    setErr(null);
    const number = form.number.trim();
    if (!/^[0-9+][0-9\s-]{5,}$/.test(number)) { setErr("Enter a valid phone number, e.g. 9399000000."); return; }
    if (!form.model) { setErr("Pick an AI model."); return; }
    setDialing(true); setLive(null);
    const r = await VoaisAPI.post("/api/calls/dial", {
      number,
      mode: "ai",
      model: form.model,
      callCfg: {
        systemPrompt: form.systemPrompt,
        greeting: form.greeting,
        voice: form.voice || undefined,
      },
    });
    setDialing(false);
    if (r.ok && r.data?.ok) {
      setCall({ uuid: r.data.callUuid, code: r.data.code });
      startPolling(r.data.callUuid);
    } else {
      setErr(r.data?.msg || "Dial failed.");
    }
  };

  const hangup = async () => {
    if (!call?.uuid) return;
    await VoaisAPI.post(`/api/calls/hangup/${call.uuid}`);
    // one more poll to capture the final state
    setTimeout(() => { if (call?.uuid) VoaisAPI.get(`/api/calls/live/${call.uuid}`).then(r => r.ok && r.data?.ok && setLive(r.data)); }, 800);
  };

  const reset = () => { clearInterval(pollRef.current); setCall(null); setLive(null); setErr(null); };

  const statusTone = (s) => s === "in_progress" || s === "answered" ? "green"
    : s === "ringing" || s === "initiated" ? "yellow"
    : s === "completed" ? "blue" : s === "failed" ? "red" : "gray";

  const selectedModel = models.find(m => m.id === form.model);
  const voiceList = selectedModel ? (voices[selectedModel.provider] || []) : [];

  return (
    <div style={{ display: "grid", gridTemplateColumns: "minmax(320px, 420px) 1fr", gap: "var(--gap-grid)", alignItems: "start" }}>
      {/* ── Left: dial form ─────────────────────────────────────────────── */}
      <Card>
        <CardHead title="New AI call" subtitle="Configure the agent, then dial." />
        <div style={{ display: "flex", flexDirection: "column", gap: 12, marginTop: 12 }}>
          <Field label="Phone number" hint="With or without country code, e.g. 9399000000">
            <input className="input" inputMode="tel" placeholder="9399000000"
              value={form.number} onChange={e => set("number", e.target.value)}
              disabled={isActive}
              style={{ fontFamily: "var(--font-mono)", fontSize: 16 }}
              onKeyDown={e => { if (e.key === "Enter" && !isActive) dial(); }}/>
          </Field>

          <Field label="AI model">
            <select className="input" value={form.model} onChange={e => { set("model", e.target.value); set("voice", ""); }} disabled={isActive}>
              {models.length === 0 && <option value="">Loading…</option>}
              {models.map(m => (
                <option key={m.id} value={m.id}>
                  {m.label}{m.available ? "" : " — no API key"}
                </option>
              ))}
            </select>
          </Field>
          {selectedModel && !selectedModel.available && (
            <div style={{ fontSize: 11.5, color: "var(--warn)" }}>
              No API key for {selectedModel.provider} — the call will run in echo mode (you'll hear yourself) until a key is set on the server.
            </div>
          )}

          {voiceList.length > 0 && (
            <Field label="Voice (optional)">
              <select className="input" value={form.voice} onChange={e => set("voice", e.target.value)} disabled={isActive}>
                <option value="">Model default</option>
                {voiceList.map(v => <option key={v} value={v}>{v}</option>)}
              </select>
            </Field>
          )}

          <Field label="Greeting" hint="First line the AI says when the call connects">
            <input className="input" value={form.greeting} onChange={e => set("greeting", e.target.value)} disabled={isActive}/>
          </Field>

          <Field label="Prompt (agent instructions)">
            <textarea className="input" rows={6} value={form.systemPrompt}
              onChange={e => set("systemPrompt", e.target.value)} disabled={isActive}
              style={{ resize: "vertical", lineHeight: 1.5 }}/>
          </Field>

          {err && <div style={{ fontSize: 12.5, color: "var(--err)" }}>{err}</div>}

          <div style={{ display: "flex", gap: 10 }}>
            {!isActive && (
              <Btn kind="primary" onClick={dial} disabled={dialing} style={{ flex: 1 }}>
                {dialing ? "Dialing…" : "📞 Call"}
              </Btn>
            )}
            {isActive && (
              <Btn kind="danger" onClick={hangup} style={{ flex: 1 }}>■ Hang up</Btn>
            )}
            {call && !isActive && (
              <Btn kind="ghost" onClick={reset}>New call</Btn>
            )}
          </div>
        </div>
      </Card>

      {/* ── Right: live call + transcript ───────────────────────────────── */}
      <Card>
        <CardHead
          title="Live call"
          subtitle={call ? `Code ${live?.call?.code || call.code} · ${live?.call?.number || form.number}` : "Your call and its transcript will appear here."}
          right={live?.call?.status && (
            <Badge tone={statusTone(live.call.status)} dot>{live.call.status.replace("_", " ")}</Badge>
          )}
        />

        {!call && (
          <div style={{ marginTop: 24, textAlign: "center", color: "var(--ink-3)", padding: "40px 0" }}>
            <div style={{ fontSize: 40, marginBottom: 10 }}>📞</div>
            Enter a number and press <b>Call</b> to start a live AI conversation.
          </div>
        )}

        {call && (
          <div style={{ marginTop: 14 }}>
            <div style={{ display: "flex", gap: 16, flexWrap: "wrap", fontSize: 12, color: "var(--ink-2)", marginBottom: 12 }}>
              {live?.call?.llm_model && <span>Model: <b>{live.call.llm_model}</b></span>}
              {typeof live?.call?.duration_s === "number" && <span>Duration: <b>{live.call.duration_s}s</b></span>}
              {live?.lastEvent && <span>Last: {live.lastEvent.event_type}{live.lastEvent.message ? ` — ${live.lastEvent.message}` : ""}</span>}
            </div>

            <div style={{ border: "1px solid var(--line)", borderRadius: "var(--r-md)", background: "var(--surface-2)",
              height: "56vh", overflowY: "auto", padding: 14, display: "flex", flexDirection: "column", gap: 10 }}>
              {(!live?.transcript || live.transcript.length === 0) && (
                <div style={{ color: "var(--ink-3)", fontSize: 12.5, margin: "auto" }}>
                  {isActive ? "Waiting for the conversation to begin…" : "No transcript."}
                </div>
              )}
              {live?.transcript?.map((t, i) => {
                const isAgent = t.role === "agent" || t.role === "assistant";
                return (
                  <div key={t.seq ?? i} style={{ display: "flex", justifyContent: isAgent ? "flex-start" : "flex-end" }}>
                    <div style={{ maxWidth: "78%", padding: "8px 12px", borderRadius: 12, fontSize: 13, lineHeight: 1.45,
                      background: isAgent ? "var(--accent-soft)" : "var(--surface-3, #2a2a35)",
                      color: "var(--ink)", borderTopLeftRadius: isAgent ? 2 : 12, borderTopRightRadius: isAgent ? 12 : 2 }}>
                      <div style={{ fontSize: 10, textTransform: "uppercase", letterSpacing: ".08em", color: "var(--ink-3)", marginBottom: 3 }}>
                        {isAgent ? "AI agent" : "Caller"}
                      </div>
                      {t.content}
                    </div>
                  </div>
                );
              })}
              <div ref={transcriptEndRef}/>
            </div>

            {live?.call?.summary && !isActive && (
              <div style={{ marginTop: 12, padding: 12, border: "1px solid var(--line)", borderRadius: "var(--r-sm)" }}>
                <div style={{ fontSize: 11, textTransform: "uppercase", color: "var(--ink-3)", marginBottom: 4 }}>Summary</div>
                <div style={{ fontSize: 13 }}>{live.call.summary}</div>
              </div>
            )}
          </div>
        )}
      </Card>
    </div>
  );
}

window.DialerScreen = DialerScreen;
