const { SAMPLE_VIDEO } = window.GT_DATA;

// Multi-step flow:
//   input  → paste url
//   title  → "buscando vídeo" (short cosmetic load) → reveals avatar picker
//   avatar → choose avatar (required); on confirm, POST /thumbnails

const TITLE_TASKS = [
  "Conectando ao YouTube",
  "Lendo título e descrição"
];

const TaskList = ({ tasks, current }) => (
  <div className="loading-tasks">
    {tasks.map((t, i) => (
      <div key={i} className={"loading-task " + (i < current ? "done" : i === current ? "active" : "")}>
        <span className="dot" />
        <span>{t}</span>
      </div>
    ))}
  </div>
);

// Same patterns the backend uses to extract the video id. Used for auto-advance
// the moment a complete URL is pasted/typed.
const YOUTUBE_URL_RE = [
  /^https?:\/\/(?:www\.|m\.)?youtube\.com\/watch\?[^#]*?\bv=([A-Za-z0-9_-]{11})/i,
  /^https?:\/\/youtu\.be\/([A-Za-z0-9_-]{11})/i,
  /^https?:\/\/(?:www\.)?youtube\.com\/shorts\/([A-Za-z0-9_-]{11})/i,
  /^https?:\/\/(?:www\.)?youtube\.com\/embed\/([A-Za-z0-9_-]{11})/i,
];
const isYouTubeUrl = (s) => YOUTUBE_URL_RE.some((re) => re.test(s.trim()));

const EMOTIONS = [
  { id: null,        label: "Padrão",    glyph: "" },
  { id: "shock",     label: "Choque",    glyph: "😱" },
  { id: "happy",     label: "Sorrindo",  glyph: "😊" },
  { id: "laughing",  label: "Rindo",     glyph: "😂" },
  { id: "excited",   label: "Empolgado", glyph: "🤩" },
  { id: "serious",   label: "Sério",     glyph: "😐" },
  { id: "thinking",  label: "Pensativo", glyph: "🤔" },
  { id: "angry",     label: "Bravo",     glyph: "😠" },
  { id: "sad",       label: "Triste",    glyph: "😢" },
];

// Style templates = every preview thumbnail in web/src/yt-mock.jsx. Single
// source of truth for both the picker and the YouTube preview. Falls back to
// two seed entries if yt-mock isn't loaded yet.
const STYLE_TEMPLATES = (() => {
  const list = window.YT_MOCK_VIDEOS || [];
  if (list.length === 0) {
    return [
      { id: "tpl-01", url: "https://img.youtube.com/vi/TX1Ij51esI0/hqdefault.jpg", label: "Template 01" },
      { id: "tpl-02", url: "https://img.youtube.com/vi/h2-YIp9IjMM/hqdefault.jpg", label: "Template 02" },
    ];
  }
  return list.map((v, i) => ({
    id: `tpl-${String(i + 1).padStart(2, "0")}`,
    url: v.thumb,
    label: `Template ${String(i + 1).padStart(2, "0")}`,
  }));
})();

// Persist the Onboarding selections so we can survive a side-trip to the
// avatar creator (or any other route) without making the user redo their work.
// sessionStorage scopes to the tab — clears when the tab closes, so a fresh
// session starts clean. We clear explicitly after a successful generation.
const ONB_STORAGE_KEY = "onboarding_draft_v1";
function loadDraft() {
  try {
    const raw = sessionStorage.getItem(ONB_STORAGE_KEY);
    return raw ? JSON.parse(raw) : null;
  } catch { return null; }
}
function saveDraft(draft) {
  try { sessionStorage.setItem(ONB_STORAGE_KEY, JSON.stringify(draft)); } catch (_) {}
}
function clearDraft() {
  try { sessionStorage.removeItem(ONB_STORAGE_KEY); } catch (_) {}
}

const Onboarding = ({ initialUrl = "", onGenerate, onCreateAvatar, onUpgrade, isPro = false, credits = 0 }) => {
  const draft = React.useMemo(() => loadDraft(), []);
  const [url, setUrl] = React.useState(draft?.url ?? initialUrl);
  const [stage, setStage] = React.useState(
    draft?.stage ?? ((draft?.url ?? initialUrl) ? "title" : "input"),
  );
  const [task, setTask] = React.useState(0);
  const [preview, setPreview] = React.useState(draft?.preview ?? null);
  const [previewError, setPreviewError] = React.useState(null);
  const [avatars, setAvatars] = React.useState([]);
  const [pickedAvatar, setPickedAvatar] = React.useState(draft?.pickedAvatar ?? null);
  const [pickedEmotion, setPickedEmotion] = React.useState(draft?.pickedEmotion ?? null);
  // Per-variation template URLs. Index 0 is used when A/B is off; 1-2 only
  // when A/B is on. null = no template for that variation.
  const [pickedTemplates, setPickedTemplates] = React.useState(
    draft?.pickedTemplates ?? [null, null, null],
  );
  const [abTest, setAbTest] = React.useState(draft?.abTest ?? false);
  const [submitting, setSubmitting] = React.useState(false);
  const [submitError, setSubmitError] = React.useState(null);

  // Save draft whenever any persistable selection changes.
  React.useEffect(() => {
    if (stage === "input" && !url) {
      // Empty form — don't pollute storage.
      clearDraft();
      return;
    }
    saveDraft({ url, stage, preview, pickedAvatar, pickedEmotion, pickedTemplates, abTest });
  }, [url, stage, preview, pickedAvatar, pickedEmotion, pickedTemplates, abTest]);

  // Title stage: animate task list AND fetch real YouTube metadata in parallel.
  // Advance to avatar only when fetch succeeds; on error, stay put so the user
  // can correct the URL.
  React.useEffect(() => {
    if (stage !== "title") return;
    let active = true;
    let timer = null;
    const animDone = task >= TITLE_TASKS.length;

    if (!animDone) {
      timer = setTimeout(() => active && setTask(task + 1), 550);
    } else if (preview) {
      timer = setTimeout(() => active && (setStage("avatar"), setTask(0)), 250);
    }
    return () => { active = false; if (timer) clearTimeout(timer); };
  }, [stage, task, preview]);

  // Fire the preview fetch once when entering the title stage.
  React.useEffect(() => {
    if (stage !== "title") return;
    let active = true;
    setPreview(null);
    setPreviewError(null);
    (async () => {
      try {
        const res = await window.gtAPI.fetch(`/youtube/preview?url=${encodeURIComponent(url)}`);
        if (active) setPreview(res);
      } catch (e) {
        if (active) setPreviewError(e.message || "falha ao ler URL");
      }
    })();
    return () => { active = false; };
  }, [stage]);

  // Load real avatars when entering the avatar stage.
  React.useEffect(() => {
    if (stage !== "avatar") return;
    let active = true;
    (async () => {
      try {
        const res = await window.gtAPI.fetch("/avatars");
        if (!active) return;
        setAvatars(res.items || []);
      } catch (e) {
        console.error("avatars fetch failed:", e);
      }
    })();
    return () => { active = false; };
  }, [stage]);

  const submitUrl = (e) => {
    e.preventDefault();
    if (!url.trim()) return;
    setStage("title");
    setTask(0);
  };

  const generate = async () => {
    if (submitting || !pickedAvatar) return;
    setSubmitting(true);
    setSubmitError(null);
    try {
      const res = await window.gtAPI.fetch("/thumbnails", {
        method: "POST",
        body: JSON.stringify({
          youtube_url: url,
          avatar_id: pickedAvatar,
          ...(abTest && isPro
            ? { template_image_urls: pickedTemplates.slice(0, 3).map((t) => t || "") }
            : { template_image_url: pickedTemplates[0] || undefined }),
          emotion: pickedEmotion || undefined,
          variations: abTest && isPro ? 3 : 1,
          aspect_ratio: "16:9",
        }),
      });
      clearDraft();
      onGenerate({ thumbnailId: res.id, abTest: abTest && isPro });
    } catch (e) {
      setSubmitError(e.message || "falha ao gerar");
      setSubmitting(false);
    }
  };

  // Step indicator (1: link, 2: avatar, 3: gerar)
  const stepIdx = ({ input: 0, title: 0, avatar: 1 })[stage] ?? 0;
  const pickedMeta = avatars.find(a => a.id === pickedAvatar) || null;

  return (
    <div className="onb-wrap">
      <div className="col-gap" style={{gap: 6}}>
        <div className="eyebrow"><span className="dot" />Nova thumbnail</div>
        <h2>{stage === "input" ? "Cole o link do seu vídeo." :
              stage === "title" ? "Lendo seu vídeo…" :
              "Qual avatar vai estampar a capa?"}</h2>
        <p className="muted-2" style={{maxWidth: 560, margin: 0}}>
          {stage === "input" && "Funciona com qualquer URL pública do YouTube. A IA usa título + seu avatar pra montar a capa."}
          {stage === "title" && "A gente busca o título do vídeo direto do YouTube — sem você precisar copiar nada."}
          {stage === "avatar" && "A mesma pessoa em todas as capas. Você escolhe agora; pode mudar depois no editor."}
        </p>
      </div>

      <div className="onb-steps onb-steps-4">
        {["Link", "Avatar", "Gerar"].map((label, i) => (
          <div key={label} className={"step " + (i < stepIdx ? "done" : i === stepIdx ? "active" : "")}>
            <span className="step-num">{i + 1}</span>
            <span className="step-label">{label}</span>
          </div>
        ))}
      </div>

      {/* === STAGE: input === */}
      {stage === "input" && (
        <form className="url-card" onSubmit={submitUrl}>
          <div className="urlrow">
            <div className="input" style={{border: 0, background: "transparent"}}>
              <Icon name="youtube" size={20} />
              <input
                autoFocus
                placeholder="https://youtube.com/watch?v=..."
                value={url}
                onChange={(e) => {
                  const v = e.target.value;
                  setUrl(v);
                  // Auto-advance the moment a complete YouTube URL is recognized
                  // (paste OR finish typing). The manual button remains a fallback
                  // for unusual URLs the regex doesn't catch.
                  if (stage === "input" && isYouTubeUrl(v)) {
                    setStage("title");
                    setTask(0);
                  }
                }}
              />
            </div>
            <button type="submit" className="btn btn-primary">Continuar <Icon name="arrow-right" size={16} /></button>
          </div>
          <div className="row-gap muted" style={{fontSize: 13}}>
            <span className="spacer" />
            <span><span className="kbd">⌘</span> <span className="kbd">↵</span> continuar</span>
          </div>
        </form>
      )}

      {/* === STAGE: title (short loading + url validation) === */}
      {stage === "title" && (
        <div className="loading-state">
          {previewError ? (
            <>
              <div style={{width: 56, height: 56, borderRadius: "50%", background: "var(--brand-soft, rgba(225,29,72,0.12))", color: "var(--brand)", display: "grid", placeItems: "center"}}>
                <Icon name="close" size={26} />
              </div>
              <div className="col-gap" style={{gap: 6, alignItems: "center", textAlign: "center"}}>
                <div style={{fontWeight: 600}}>URL inválida ou indisponível</div>
                <div className="muted" style={{fontSize: 13, maxWidth: 360}}>{previewError}</div>
              </div>
              <button className="btn" onClick={() => { setPreviewError(null); setStage("input"); setTask(0); }}>
                <Icon name="arrow-left" size={14} /> Corrigir URL
              </button>
            </>
          ) : (
            <>
              <div className="ring-lg" />
              <TaskList tasks={TITLE_TASKS} current={task} />
            </>
          )}
        </div>
      )}

      {/* === STAGE: avatar pick === */}
      {stage === "avatar" && (
        <div className="onb-avatar-stage">
          {/* YouTube preview card */}
          <div className="onb-found-card">
            <div className="onb-found-thumb" style={{overflow: "hidden"}}>
              {preview?.thumbnail_url
                ? <img src={preview.thumbnail_url} alt="" style={{width: "100%", height: "100%", objectFit: "cover"}} />
                : <Icon name="youtube" size={26} />}
            </div>
            <div className="col-gap" style={{gap: 4, flex: 1, minWidth: 0}}>
              <div className="eyebrow" style={{color: previewError ? "var(--brand)" : "var(--success, #10b981)"}}>
                {previewError
                  ? <><Icon name="close" size={12} /> Não foi possível ler a URL</>
                  : <><Icon name="check" size={12} /> Vídeo encontrado</>}
              </div>
              <div style={{fontFamily: "var(--font-display)", fontWeight: 700, fontSize: 18, lineHeight: 1.25}}>
                {preview?.title || url}
              </div>
              <div className="muted" style={{fontSize: 12}}>
                {preview?.author_name || (previewError ? previewError : "—")}
              </div>
            </div>
          </div>

          {/* Avatar grid */}
          <div className="col-gap" style={{gap: 10}}>
            <div className="row-gap" style={{alignItems: "baseline"}}>
              <div className="eyebrow">Avatares</div>
              <span className="spacer" />
            </div>
            <div className="onb-avatar-grid">
              {avatars.map(av => (
                <button key={av.id ?? "none"}
                        className={"onb-avatar-card " + (pickedAvatar === av.id ? "active" : "")}
                        onClick={() => setPickedAvatar(av.id)}>
                  <div className="onb-av-face">
                    {av.preview_url || av.image_url
                      ? <img src={av.preview_url || av.image_url} alt={av.name}
                             onError={(e) => { if (av.preview_url_full && e.target.src !== av.preview_url_full) e.target.src = av.preview_url_full; }}
                             style={{width: 64, height: 64, borderRadius: "50%", objectFit: "cover"}} />
                      : <FacePlaceholder tone={0} emotion="happy" size={64} />}
                  </div>
                  <div className="onb-av-meta">
                    <div className="onb-av-name">{av.name}</div>
                    <div className="onb-av-sub">{av.style || av.description || ""} {av.meta ? "· " + av.meta : ""}</div>
                  </div>
                  {pickedAvatar === av.id && (
                    <div className="onb-av-check"><Icon name="check" size={12} /></div>
                  )}
                </button>
              ))}
              {onCreateAvatar && (
                <button className="onb-avatar-card" onClick={onCreateAvatar}
                        style={{borderStyle: "dashed", color: "var(--text-3)"}}>
                  <div className="onb-av-face" style={{display: "grid", placeItems: "center", background: "var(--bg-2)"}}>
                    <Icon name="plus" size={28} />
                  </div>
                  <div className="onb-av-meta">
                    <div className="onb-av-name">Novo avatar</div>
                    <div className="onb-av-sub">criar a partir de fotos</div>
                  </div>
                </button>
              )}
            </div>
          </div>

          {/* Emotion picker — only when an avatar is selected */}
          {pickedAvatar && (
            <div className="col-gap" style={{gap: 10}}>
              <div className="eyebrow">Emoção do avatar <span className="muted" style={{fontWeight: 400, textTransform: "none"}}>(opcional)</span></div>
              <div className="row-gap" style={{gap: 6, flexWrap: "wrap"}}>
                {EMOTIONS.map((e) => (
                  <button key={e.id ?? "default"}
                          className={"btn btn-sm " + (pickedEmotion === e.id ? "btn-primary" : "")}
                          onClick={() => setPickedEmotion(e.id)}>
                    {e.glyph && <span style={{marginRight: 6, fontSize: 14, lineHeight: 1}}>{e.glyph}</span>}
                    {e.label}
                  </button>
                ))}
              </div>
            </div>
          )}

          {/* Template (style) picker — one row per A/B variation. */}
          {(() => {
            const variationCount = abTest && isPro ? 3 : 1;
            const setTplAt = (idx, url) => {
              setPickedTemplates((prev) => {
                const next = [...prev];
                next[idx] = url;
                return next;
              });
            };
            return (
              <div className="col-gap" style={{gap: 14}}>
                <div className="row-gap" style={{alignItems: "baseline"}}>
                  <div className="eyebrow">
                    Template de estilo <span className="muted" style={{fontWeight: 400, textTransform: "none"}}>(opcional)</span>
                  </div>
                </div>
                <div className="muted-2" style={{fontSize: 12, marginTop: -8}}>
                  {variationCount > 1
                    ? "Pode escolher um template diferente pra cada variação A/B."
                    : "Use uma thumb existente como referência de composição, paleta e mood. O rosto continua sendo o do seu avatar."}
                </div>
                {Array.from({ length: variationCount }).map((_, i) => (
                  <div key={i} className="col-gap" style={{gap: 8}}>
                    <div className="row-gap" style={{alignItems: "center", gap: 10}}>
                      {variationCount > 1 && (
                        <span className="mono muted" style={{fontSize: 11}}>
                          VARIAÇÃO {String(i + 1).padStart(2, "0")}
                        </span>
                      )}
                      <span className="spacer" />
                      {pickedTemplates[i] && (
                        <button className="btn btn-sm btn-ghost" onClick={() => setTplAt(i, null)}>
                          Sem template
                        </button>
                      )}
                    </div>
                    <div style={{
                      display: "grid",
                      gridTemplateColumns: "repeat(auto-fill, minmax(180px, 1fr))",
                      gap: 10,
                    }}>
                      {STYLE_TEMPLATES.map((t, tplIdx) => {
                        const locked = !isPro && tplIdx >= 2;
                        const onClick = () => {
                          if (locked) { onUpgrade && onUpgrade(); return; }
                          setTplAt(i, pickedTemplates[i] === t.url ? null : t.url);
                        };
                        return (
                          <button key={t.id}
                                  onClick={onClick}
                                  title={locked ? "Disponível no plano Pro" : t.label}
                                  style={{
                                    position: "relative",
                                    aspectRatio: "16 / 9",
                                    borderRadius: 10,
                                    overflow: "hidden",
                                    border: `2px solid ${pickedTemplates[i] === t.url ? "var(--brand)" : "var(--border)"}`,
                                    background: "var(--bg-2)",
                                    cursor: "pointer",
                                    padding: 0,
                                    transition: "border-color .15s",
                                  }}>
                            <img src={t.url} alt={t.label}
                                 style={{
                                   width: "100%", height: "100%", objectFit: "cover", display: "block",
                                   filter: locked ? "grayscale(1) brightness(0.55)" : "none",
                                 }} />
                            <div style={{
                              position: "absolute", bottom: 6, left: 6,
                              background: "rgba(0,0,0,0.7)", color: "#fff",
                              fontSize: 10, padding: "2px 6px", borderRadius: 4,
                              fontFamily: "var(--font-mono)",
                            }}>{t.label}</div>
                            {locked && (
                              <div style={{
                                position: "absolute", inset: 0,
                                display: "flex", flexDirection: "column",
                                alignItems: "center", justifyContent: "center",
                                gap: 6, color: "#fff",
                              }}>
                                <Icon name="lock" size={18} />
                                <span className="chip brand" style={{fontSize: 10}}>Pro</span>
                              </div>
                            )}
                            {pickedTemplates[i] === t.url && !locked && (
                              <div style={{
                                position: "absolute", top: 6, right: 6,
                                width: 22, height: 22, borderRadius: "50%",
                                background: "var(--brand)", color: "#fff",
                                display: "grid", placeItems: "center",
                              }}>
                                <Icon name="check" size={12} />
                              </div>
                            )}
                          </button>
                        );
                      })}
                    </div>
                  </div>
                ))}
              </div>
            );
          })()}

          {/* A/B test row — Pro only. Locked row routes to checkout. */}
          <div className={"onb-ab-row " + (isPro ? "" : "locked")}
               onClick={() => { if (!isPro && onUpgrade) onUpgrade(); }}
               style={!isPro ? { cursor: "pointer" } : undefined}>
            <div className="onb-ab-icon">
              <Icon name="sparkles" size={16} />
            </div>
            <div className="col-gap" style={{gap: 2, flex: 1}}>
              <div className="row-gap" style={{gap: 8, alignItems: "center"}}>
                <div style={{fontWeight: 600, fontSize: 14}}>Gerar 3 variações pra teste A/B</div>
                {!isPro && <span className="chip brand" style={{fontSize: 10}}>Pro</span>}
              </div>
              <div className="muted" style={{fontSize: 12}}>
                {isPro
                  ? "Custa 3 créditos por geração. O YouTube permite testar até 3 thumbnails por vídeo."
                  : "Disponível no plano Pro. Toque pra fazer upgrade."}
              </div>
            </div>
            <label className={"onb-switch " + (isPro ? "" : "disabled")}
                   onClick={(e) => e.stopPropagation()}>
              <input type="checkbox" checked={abTest && isPro} disabled={!isPro}
                     onChange={(e) => setAbTest(e.target.checked)} />
              <span className="onb-switch-track"><span className="onb-switch-thumb" /></span>
            </label>
          </div>

          {submitError && (
            <div className="card" style={{padding: 14, borderColor: "var(--brand)", color: "var(--brand)", fontSize: 13}}>
              {submitError}
            </div>
          )}

          <div className="row-gap" style={{justifyContent: "flex-end", gap: 10, alignItems: "center"}}>
            <button className="btn" onClick={() => setStage("input")} disabled={submitting}>
              <Icon name="arrow-left" size={14} /> Voltar
            </button>
            {(() => {
              const cost = abTest && isPro ? 3 : 1;
              const insufficient = credits < cost;
              if (insufficient && onUpgrade) {
                return (
                  <button className="btn btn-primary btn-lg" onClick={onUpgrade}>
                    <Icon name="zap" size={14} /> Comprar créditos ({credits} disponíveis)
                  </button>
                );
              }
              return (
                <button className="btn btn-primary btn-lg" onClick={generate}
                        disabled={submitting || insufficient || !pickedAvatar}
                        title={!pickedAvatar ? "Escolha um avatar pra gerar" : ""}>
                  {submitting ? (
                    <><span className="ring" /> Enviando…</>
                  ) : !pickedAvatar ? (
                    <>Escolha um avatar <Icon name="arrow-right" size={16} /></>
                  ) : (
                    <>Gerar capa{cost > 1 ? "s" : ""} ({cost} crédito{cost > 1 ? "s" : ""}) <Icon name="arrow-right" size={16} /></>
                  )}
                </button>
              );
            })()}
          </div>
        </div>
      )}
    </div>
  );
};

window.Onboarding = Onboarding;
