/**
 * Content script do Outlook Web (outlook.live.com, outlook.office.com,
 * outlook.office365.com).
 *
 * Nova UI do Outlook: a tela correta é
 *   Configurações → Email → Assinaturas
 * Quando não há assinatura, o Outlook mostra o botão "+ Nova assinatura".
 * Este script:
 *  1) Injeta um botão "Instalar assinatura AssinaPro" no topo da tela.
 *  2) Ao instalar, se o editor ainda não estiver aberto, clica em
 *     "+ Nova assinatura" automaticamente e aguarda o modal.
 *  3) Preenche o campo "Nome da assinatura" e o editor rich-text.
 */
(function () {
  const BTN_ID = "ap-install-btn-outlook";
  const STATUS_ID = "ap-install-status-outlook";

  function log(...args) {
    // eslint-disable-next-line no-console
    console.log("[AssinaPro/Outlook]", ...args);
  }

  const wait = (ms) => new Promise((r) => setTimeout(r, ms));

  /** Editor rich-text de assinatura (contenteditable). */
  function findSignatureEditor() {
    const selectors = [
      '[aria-label*="assinatura" i][contenteditable="true"]',
      '[aria-label*="signature" i][contenteditable="true"]',
      '[role="textbox"][aria-label*="assinatura" i]',
      '[role="textbox"][aria-label*="signature" i]',
      // Fallback: qualquer contenteditable dentro de um diálogo/modal aberto
      '[role="dialog"] [contenteditable="true"]',
    ];
    for (const sel of selectors) {
      const el = document.querySelector(sel);
      if (el) return { body: el };
    }
    return null;
  }

  /** Campo "Nome da assinatura" / "Signature name". */
  function findNameInput() {
    const candidates = document.querySelectorAll('input[type="text"], input:not([type])');
    for (const el of candidates) {
      const label = (el.getAttribute("aria-label") || el.getAttribute("placeholder") || "").toLowerCase();
      if (label.includes("nome") || label.includes("name")) return el;
    }
    return null;
  }

  /** Botão "+ Adicionar/Nova assinatura" / "+ Add/New signature". */
  function findNewSignatureButton() {
    const buttons = document.querySelectorAll('button, [role="button"], [role="menuitem"]');
    for (const el of buttons) {
      const txt = (el.textContent || "").trim().toLowerCase().replace(/^\+\s*/, "");
      if (
        txt === "adicionar assinatura" ||
        txt === "nova assinatura" ||
        txt === "add signature" ||
        txt === "new signature" ||
        txt.startsWith("adicionar assinatura") ||
        txt.startsWith("nova assinatura") ||
        txt.startsWith("add signature") ||
        txt.startsWith("new signature")
      ) {
        return el;
      }
    }
    return null;
  }

  /** Cabeçalho "Assinaturas" / "Signatures" para ancorar o botão. */
  function findAnchor() {
    const dialog = document.querySelector('[role="dialog"]');
    const scope = dialog || document;
    const candidates = scope.querySelectorAll("h1, h2, h3, h4, label, div, span");
    for (const el of candidates) {
      const txt = (el.textContent || "").trim().toLowerCase();
      if (
        txt === "assinaturas" ||
        txt === "signatures" ||
        txt === "assinatura de email" ||
        txt === "email signature"
      ) {
        return el;
      }
    }
    return null;
  }

  function isOnSignaturesScreen() {
    if (findSignatureEditor() || findNewSignatureButton() || findAnchor()) return true;
    return /options\/mail\/signatures/i.test(location.pathname);
  }

  /** Localiza o diálogo "Editar assinatura" (o modal com o editor rich-text). */
  function findEditDialog() {
    const dialogs = document.querySelectorAll('[role="dialog"]');
    for (const d of dialogs) {
      if (d.querySelector('[contenteditable="true"]')) return d;
    }
    return null;
  }

  function ensureButton() {
    // Só injeta dentro do popup "Editar assinatura" (evita ficar cortado
    // na coluna estreita da lista de assinaturas).
    const dialog = findEditDialog();
    if (!dialog) {
      const old = document.getElementById(BTN_ID)?.closest("[data-ap-panel]");
      if (old) old.remove();
      return;
    }
    if (dialog.querySelector(`#${BTN_ID}`)) return;

    const container = document.createElement("div");
    container.setAttribute("data-ap-panel", "1");
    container.style.cssText = "margin:12px 0;padding:10px 12px;border:1px dashed #C43AAF;border-radius:10px;background:linear-gradient(135deg,#fdf2fa,#f5f3ff);font-family:'Segoe UI',Roboto,Arial,sans-serif;display:flex;align-items:center;gap:10px";

    const label = document.createElement("div");
    label.innerHTML = `<div style="font-size:13px;font-weight:600;color:#6B21A8">AssinaPro</div><div id="${STATUS_ID}" style="font-size:12px;color:#4b5563">Preencher automaticamente com sua assinatura ativa.</div>`;
    label.style.flex = "1";

    const btn = document.createElement("button");
    btn.id = BTN_ID;
    btn.type = "button";
    btn.textContent = "Instalar assinatura";
    btn.style.cssText = "background:linear-gradient(135deg,#C43AAF,#6B21A8);color:#fff;border:0;border-radius:8px;padding:8px 14px;font-size:13px;font-weight:600;cursor:pointer;box-shadow:0 2px 8px rgba(107,33,168,.25)";
    btn.addEventListener("click", installFlow);

    container.appendChild(label);
    container.appendChild(btn);

    // Insere no topo do conteúdo do diálogo.
    const editor = dialog.querySelector('[contenteditable="true"]');
    const target = editor?.closest("div") || editor;
    const parent = target?.parentElement || dialog;
    parent.insertBefore(container, parent.firstChild);
  }

  function setStatus(text, color) {
    const el = document.getElementById(STATUS_ID);
    if (el) {
      el.textContent = text;
      if (color) el.style.color = color;
    }
  }

  function pickSignature(signatures) {
    if (signatures.length === 1) return signatures[0];
    const list = signatures.map((s, i) => `${i + 1}. ${s.name}`).join("\n");
    const choice = window.prompt(`Qual assinatura instalar?\n\n${list}\n\nDigite o número:`, "1");
    const idx = Number(choice) - 1;
    return Number.isFinite(idx) && signatures[idx] ? signatures[idx] : null;
  }

  /** Aguarda o editor abrir após clicar em "+ Nova assinatura". */
  async function waitForEditor(timeoutMs = 4000) {
    const start = Date.now();
    while (Date.now() - start < timeoutMs) {
      const ed = findSignatureEditor();
      if (ed) return ed;
      await wait(150);
    }
    return null;
  }

  function setNativeInputValue(input, value) {
    const proto = Object.getPrototypeOf(input);
    const setter = Object.getOwnPropertyDescriptor(proto, "value")?.set;
    if (setter) setter.call(input, value);
    else input.value = value;
    input.dispatchEvent(new Event("input", { bubbles: true }));
    input.dispatchEvent(new Event("change", { bubbles: true }));
  }

  function applyHtmlToEditor(editor, html) {
    if (!editor?.body) return false;
    const body = editor.body;
    body.focus();
    try {
      document.execCommand("selectAll", false);
      document.execCommand("insertHTML", false, html);
    } catch {
      body.innerHTML = html;
    }
    body.dispatchEvent(new Event("input", { bubbles: true }));
    return true;
  }

  async function ensureEditorOpen() {
    let editor = findSignatureEditor();
    if (editor) return editor;
    const newBtn = findNewSignatureButton();
    if (newBtn) {
      newBtn.click();
      editor = await waitForEditor(4000);
      if (editor) return editor;
    }
    return null;
  }

  async function installFlow() {
    setStatus("Buscando sua assinatura ativa…", "#4b5563");
    chrome.runtime.sendMessage({ type: "AP_GET_SIGNATURES" }, async (res) => {
      if (!res?.ok) {
        if (res?.error === "unauthorized") {
          setStatus("Faça login na extensão (clique no ícone AssinaPro).", "#b91c1c");
        } else {
          setStatus(`Erro: ${res?.error || "falha ao buscar"}`, "#b91c1c");
        }
        return;
      }
      const signatures = res.signatures || [];
      if (signatures.length === 0) {
        setStatus("Nenhuma assinatura encontrada na sua conta.", "#b91c1c");
        return;
      }
      const picked = pickSignature(signatures);
      if (!picked) {
        setStatus("Instalação cancelada.", "#4b5563");
        return;
      }
      setStatus("Abrindo o editor de assinatura…", "#4b5563");
      const editor = await ensureEditorOpen();
      if (!editor) {
        setStatus('Clique em "+ Nova assinatura" no Outlook e tente de novo.', "#b45309");
        return;
      }
      // Preenche o nome da assinatura, se o campo estiver visível e vazio.
      const nameInput = findNameInput();
      if (nameInput && !nameInput.value) setNativeInputValue(nameInput, picked.name);

      const ok = applyHtmlToEditor(editor, picked.html);
      if (ok) {
        setStatus(`Instalada: ${picked.name}. Clique em "Salvar" no Outlook.`, "#047857");
      } else {
        setStatus("Não consegui preencher o editor. Tente novamente.", "#b45309");
      }
    });
  }

  chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => {
    if (msg?.type !== "AP_INSTALL_NOW") return false;
    (async () => {
      const editor = await ensureEditorOpen();
      if (!editor) {
        sendResponse({
          ok: false,
          message: 'Abra Configurações → Email → Assinaturas e clique em "+ Nova assinatura".',
        });
        return;
      }
      const nameInput = findNameInput();
      if (nameInput && !nameInput.value && msg.signature?.name) {
        setNativeInputValue(nameInput, msg.signature.name);
      }
      const ok = applyHtmlToEditor(editor, msg.signature?.html || "");
      sendResponse(ok ? { ok: true, provider: "Outlook" } : { ok: false, message: "Falha ao preencher o editor do Outlook." });
    })();
    return true; // async response
  });

  const observer = new MutationObserver(() => {
    try { ensureButton(); } catch (e) { log("ensureButton falhou", e); }
  });
  observer.observe(document.body, { childList: true, subtree: true });
  ensureButton();
})();
