// Feed publishing for LinkedIn + X (Twitter), ported from content/linkedin-content.js
// and content/twitter-content.js. Same shape as fb_publish.js: open composer, type,
// submit, detect outcome. Exposes window.__oaiPublishLinkedIn / __oaiPublishTwitter.
(function () {
  if (window.__oaiFeedReady) return;
  window.__oaiFeedReady = true;

  const LI = {
    open: ['[aria-label*="Start a post" i]', '[aria-label*="התחלת פוסט"]', '[aria-label*="צרו פוסט"]', '.share-box-feed-entry__trigger', 'button.share-box-feed-entry__trigger'],
    dialog: ['[role="dialog"]', '.share-box'],
    editable: ['.ql-editor[contenteditable="true"]', '[role="dialog"] [contenteditable="true"][role="textbox"]', '[role="dialog"] [contenteditable="true"]'],
    submit: ['[role="dialog"] button[aria-label*="Post" i]:not([aria-label*="Save" i])', '[role="dialog"] button[aria-label*="פרסם"]', '.share-actions__primary-action', 'button.artdeco-button--primary[type="button"]'],
  };
  const TW = {
    open: ['[data-testid="SideNav_NewTweet_Button"]', '[aria-label="Post"][role="link"]', '[aria-label="פוסט"][role="link"]'],
    dialog: ['[role="dialog"][aria-labelledby]', '[aria-modal="true"]'],
    editable: ['[data-testid="tweetTextarea_0"]', 'div[contenteditable="true"][data-testid*="tweetTextarea"]', 'div[role="textbox"][contenteditable="true"]'],
    submit: ['[data-testid="tweetButton"]', '[data-testid="tweetButtonInline"]'],
    max: 280,
  };

  const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
  const rand = (a, b) => a + Math.floor(Math.random() * (b - a));

  function qsAny(sels, root) {
    root = root || document;
    for (const s of sels) { const el = root.querySelector(s); if (el) return el; }
    return null;
  }
  function waitFor(sels, timeout) {
    return new Promise((res, rej) => {
      const dl = Date.now() + (timeout || 12000);
      (function t() { const el = qsAny(sels); if (el) return res(el); if (Date.now() > dl) return rej(new Error('timeout ' + sels[0])); setTimeout(t, 250); })();
    });
  }
  function typeChar(el, ch) {
    const kc = ch.length === 1 ? ch.charCodeAt(0) : 0;
    const o = { key: ch === '\n' ? 'Enter' : ch, keyCode: kc, which: kc, bubbles: true, cancelable: true, composed: true };
    el.dispatchEvent(new KeyboardEvent('keydown', o));
    el.dispatchEvent(new InputEvent('beforeinput', { inputType: 'insertText', data: ch, bubbles: true, cancelable: true, composed: true }));
    const ok = document.execCommand && document.execCommand('insertText', false, ch);
    if (!ok) el.dispatchEvent(new InputEvent('input', { inputType: 'insertText', data: ch, bubbles: true, cancelable: true, composed: true }));
    el.dispatchEvent(new KeyboardEvent('keyup', o));
  }
  async function typeInto(el, text) {
    el.focus();
    el.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }));
    el.dispatchEvent(new MouseEvent('click', { bubbles: true }));
    for (const ch of text) { typeChar(el, ch); await sleep(rand(25, 85)); }
  }
  async function detectOutcome(dialog, timeout) {
    const dl = Date.now() + (timeout || 12000);
    const fail = ['try again', 'נסה שוב', 'something went wrong', 'משהו השתבש', 'could not', 'לא ניתן'];
    while (Date.now() < dl) {
      const body = (document.body.innerText || '').toLowerCase();
      for (const w of fail) if (body.includes(w)) return { ok: false, signal: 'error: ' + w };
      if (dialog && !document.body.contains(dialog)) return { ok: true, signal: 'dialog-removed' };
      await sleep(400);
    }
    return { ok: true, signal: 'no-error-timeout' };
  }

  async function run(S, text) {
    try {
      if (!text || !text.trim()) return { ok: false, error: 'empty text' };
      if (S.max && text.length > S.max) text = text.slice(0, S.max);
      let opener = qsAny(S.open);
      if (!opener) { try { opener = await waitFor(S.open, 8000); } catch (e) {} }
      if (!opener) return { ok: false, error: 'composer not found' };
      await sleep(rand(700, 1800));
      opener.click();
      await waitFor(S.dialog, 10000);
      await sleep(700);
      const editable = await waitFor(S.editable, 8000);
      await sleep(rand(400, 1000));
      await typeInto(editable, text);
      const dialog = qsAny(S.dialog);
      const submit = await waitFor(S.submit, 8000);
      await sleep(rand(600, 1400));
      submit.click();
      const o = await detectOutcome(dialog, 12000);
      return o.ok ? { ok: true, signal: o.signal } : { ok: false, error: o.signal };
    } catch (e) { return { ok: false, error: String((e && e.message) || e) }; }
  }

  window.__oaiPublishLinkedIn = (text) => run(LI, text);
  window.__oaiPublishTwitter = (text) => run(TW, text);
})();
