// tab-linkedin.jsx — LinkedIn: your daily post pool.
// Three columns: POOL (drafts by status) · EDITOR (edit/copy/media/actions) · PREVIEW
//   (live LinkedIn render with the "…see more" fold marked so you can tune the hook).
// A scheduled writer keeps ~7 fresh drafts in the pool. We don't auto-publish to
// LinkedIn (manual copy by design); "Scheduled" is a dated reminder.
const { useState: useStateLI, useEffect: useEffectLI, useRef: useRefLI } = React;
const LIS = window.RaiseShell;

const LI_PILLARS = ['Feedback in Public', 'Build in Public', 'Learn in Public'];
const LI_STATUS = [['draft', 'Drafts'], ['pipeline', 'Pipeline'], ['scheduled', 'Scheduled'], ['posted', 'Posted'], ['skipped', 'Skipped']];
const LI_POOL_TARGET = 7;

function liPillarColor(p) {
  return { 'Feedback in Public': 'var(--primary)', 'Build in Public': '#1d9e75', 'Learn in Public': '#8159bf' }[p] || 'var(--ink-3)';
}
function liTick() {
  const [, f] = useStateLI(0);
  useEffectLI(() => { const h = () => f(x => x + 1); window.addEventListener('raise-livedata', h); return () => window.removeEventListener('raise-livedata', h); }, []);
}
// LinkedIn desktop truncates ~3 lines or ~210 chars, whichever comes first.
function liFoldIndex(text) {
  const byChar = 210;
  let nl = 0, idx = -1;
  for (let i = 0; i < text.length; i++) { if (text[i] === '\n') { nl++; if (nl === 3) { idx = i; break; } } }
  const byLine = idx >= 0 ? idx : text.length;
  return Math.min(byChar, byLine);
}
function liDomain(u) { try { return new URL(u).hostname.replace(/^www\./, ''); } catch (_) { return u; } }

// ── live LinkedIn-style preview with the fold marker ──
function LIPreview({ post }) {
  const body = post.body || '';
  const fold = liFoldIndex(body);
  const before = body.slice(0, fold);
  const after = body.slice(fold);
  const card = { background: 'var(--surface,#fff)', border: '1px solid var(--line,#e7e2d7)', borderRadius: 12, padding: 14 };
  return (
    <div style={{ ...card }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 9, marginBottom: 10 }}>
        <LIS.Avatar name="Austin Jia" />
        <div>
          <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--ink)' }}>Austin Jia</div>
          <div style={{ fontSize: 11, color: 'var(--ink-3)' }}>Founder &amp; CEO, AllStreet Capital · Now</div>
        </div>
      </div>
      <div style={{ fontSize: 13.5, lineHeight: 1.5, color: 'var(--ink)', whiteSpace: 'pre-wrap' }}>
        {before}
        {after.length > 0 && (
          <>
            <span style={{ color: 'var(--ink-3)' }}>… </span>
            <span style={{ color: 'var(--primary)', fontWeight: 600 }}>see more</span>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, margin: '8px 0' }}>
              <div style={{ flex: 1, borderTop: '1px dashed var(--primary)' }} />
              <span style={{ fontSize: 9.5, letterSpacing: .5, color: 'var(--primary)', textTransform: 'uppercase' }}>fold · click to expand</span>
              <div style={{ flex: 1, borderTop: '1px dashed var(--primary)' }} />
            </div>
            <span style={{ color: 'var(--ink-2)' }}>{after}</span>
          </>
        )}
      </div>
      {post.imageUrl && <img src={post.imageUrl} alt="" style={{ width: '100%', maxHeight: 200, objectFit: 'cover', borderRadius: 8, marginTop: 10, border: '1px solid var(--line,#e7e2d7)' }} />}
      {post.linkUrl && (
        <div style={{ marginTop: 10, border: '1px solid var(--line,#e7e2d7)', borderRadius: 8, padding: '8px 10px', background: 'var(--surface-2,#f1efe8)' }}>
          <div style={{ fontSize: 10.5, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: .4 }}>{liDomain(post.linkUrl)}</div>
          <div style={{ fontSize: 12, color: 'var(--ink-2)', wordBreak: 'break-all' }}>{post.linkUrl}</div>
        </div>
      )}
      <div style={{ display: 'flex', gap: 16, marginTop: 12, paddingTop: 10, borderTop: '1px solid var(--line,#e7e2d7)', fontSize: 11.5, color: 'var(--ink-3)' }}>
        <span>👍 Like</span><span>💬 Comment</span><span>↻ Repost</span><span>➤ Send</span>
      </div>
    </div>
  );
}

function TabLinkedIn() {
  const RLD = window.RaiseLiveData;
  liTick();
  useEffectLI(() => { if (RLD && RLD.loadContentPosts && !RLD._postsOk) RLD.loadContentPosts(); }, []);

  const live = !!(RLD && RLD.contentPosts);
  const posts = live ? RLD.contentPosts() : [];
  const [statusTab, setStatusTab] = useStateLI('draft');
  const [selId, setSelId] = useStateLI(null);
  const [edit, setEdit] = useStateLI(null);
  const [dirty, setDirty] = useStateLI(false);
  const [showImg, setShowImg] = useStateLI(false);
  const [showLink, setShowLink] = useStateLI(false);
  const [feedback, setFeedback] = useStateLI('');
  const [aiBusy, setAiBusy] = useStateLI(false);
  const taRef = useRefLI(null);

  const list = posts.filter(p => p.status === statusTab);
  const drafts = posts.filter(p => p.status === 'draft');

  useEffectLI(() => {
    if (!list.some(p => p.id === selId)) setSelId(list[0] ? list[0].id : null);
  }, [statusTab, list.map(p => p.id).join(',')]);
  useEffectLI(() => {
    const p = posts.find(x => x.id === selId);
    setEdit(p ? { ...p } : null); setDirty(false);
    setShowImg(!!(p && p.imageUrl)); setShowLink(!!(p && p.linkUrl));
    setFeedback('');
  }, [selId]);
  // auto-grow the editor to fit the whole post
  useEffectLI(() => {
    const el = taRef.current; if (!el) return;
    el.style.height = 'auto'; el.style.height = Math.max(240, el.scrollHeight) + 'px';
  }, [edit && edit.body, selId]);

  if (!live) {
    return (<><LIS.TopBar title="LinkedIn" sub="your daily post pool" /><div className="muted" style={{ fontSize: 13, padding: '24px', textAlign: 'center' }}>Sign in to load your posts.</div></>);
  }

  const sel = edit;
  const setF = (k, v) => { setEdit(e => ({ ...e, [k]: v })); setDirty(true); };
  const editPayload = () => ({ body: sel.body, pillar: sel.pillar, linkUrl: sel.linkUrl || null, imageUrl: sel.imageUrl || null });
  const save = () => { if (!sel) return; RLD.patchContentPost(sel.id, editPayload()).then(() => { setDirty(false); LIS.toast('Saved ✓'); }).catch(() => LIS.toast('Could not save')); };
  const move = (patch, msg) => { if (!sel) return; if (dirty) Object.assign(patch, editPayload()); RLD.patchContentPost(sel.id, patch).then(() => { setDirty(false); LIS.toast(msg); }).catch(() => LIS.toast('Could not save')); };
  const copy = () => { if (!sel) return; try { navigator.clipboard.writeText(sel.body || ''); LIS.toast('Copied — paste into LinkedIn'); } catch (_) { LIS.toast('Copy failed'); } };
  const openLI = () => window.open('https://www.linkedin.com/feed/', '_blank', 'noopener');
  const del = () => { if (sel && window.confirm('Delete this post?')) RLD.deleteContentPost(sel.id).then(() => { setSelId(null); LIS.toast('Deleted'); }); };
  const addNew = () => { RLD.addContentPost({ body: '', pillar: 'Feedback in Public', status: 'draft' }).then(r => { if (r && r.ok) { setStatusTab('draft'); if (r.id) setSelId(r.id); LIS.toast('New draft — start writing'); } else LIS.toast('Could not add'); }); };
  const regenerate = async () => {
    if (!sel) return;
    const AI = window.RaiseAI;
    const fb = (feedback || '').trim();
    if (!AI) { LIS.toast('AI isn’t available'); return; }
    if (!(sel.body || '').trim() && !fb) { LIS.toast('Write a draft or add feedback first'); return; }
    setAiBusy(true);
    try {
      const out = await AI.rewrite(sel.body || '', { task: 'rewrite_post', context: { instruction: fb, pillar: sel.pillar } });
      setF('body', out);
      LIS.toast('Regenerated ✓');
    } catch (e) {
      const m = (e && e.message) || '';
      LIS.toast(m === 'budget_exceeded' ? 'AI budget reached for this month'
        : m === 'llm_not_configured' ? 'AI isn’t set up — see Settings → Assistant'
        : 'Could not regenerate — try again');
    }
    setAiBusy(false);
  };

  const inStyle = { fontSize: 13, padding: '7px 9px', border: '1px solid var(--line,#e7e2d7)', borderRadius: 8, background: 'var(--surface,#fff)', color: 'var(--ink)', width: '100%', boxSizing: 'border-box' };
  const chip = { fontSize: 11.5, padding: '4px 9px', border: '1px dashed var(--line,#c9c1b2)', borderRadius: 20, background: 'transparent', color: 'var(--ink-3)', cursor: 'pointer' };

  const Row = ({ p }) => {
    const active = p.id === selId;
    const snip = (p.body || '').replace(/\n+/g, ' ').slice(0, 64);
    return (
      <button onClick={() => setSelId(p.id)} style={{
        display: 'flex', flexDirection: 'column', gap: 4, width: '100%', textAlign: 'left', cursor: 'pointer',
        padding: '10px 11px', border: '1px solid ' + (active ? 'var(--primary)' : 'var(--line,#e7e2d7)'),
        background: active ? 'var(--primary-tint,#f4e6dd)' : 'var(--surface,#fff)', borderRadius: 10, marginBottom: 7
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 7 }}>
          <span style={{ fontSize: 9.5, fontWeight: 700, letterSpacing: .3, color: liPillarColor(p.pillar), border: '1px solid ' + liPillarColor(p.pillar), borderRadius: 5, padding: '1px 5px', whiteSpace: 'nowrap' }}>{(p.pillar || '').replace(' in Public', '').toUpperCase()}</span>
          {p.imageUrl && <span title="has image" style={{ fontSize: 11, color: 'var(--ink-3)' }}>◴</span>}
          {p.linkUrl && <span title="has link" style={{ fontSize: 11, color: 'var(--ink-3)' }}>↗</span>}
          {p.scheduledFor && <span style={{ marginLeft: 'auto', fontSize: 10.5, color: 'var(--primary)' }}>{p.scheduledFor}</span>}
        </div>
        <div style={{ fontSize: 12.5, color: 'var(--ink-2)', lineHeight: 1.4 }}>{snip}{(p.body || '').length > 64 ? '…' : ''}</div>
      </button>
    );
  };

  return (
    <>
      <LIS.TopBar title="LinkedIn" sub="your daily post pool — edit, copy, post">
        <div className="qpill acc">{drafts.length}/{LI_POOL_TARGET} ready</div>
        <button className="btn primary sm" onClick={addNew}>＋ New post</button>
        <button className="btn sm ic" onClick={() => RLD.loadContentPosts().then(() => LIS.toast('Refreshed'))} title="Reload posts"><window.Ico n="refresh" size={13} /> Refresh</button>
      </LIS.TopBar>

      <div style={{ display: 'flex', gap: 14, padding: '4px 16px 20px', height: '100%', minHeight: 0, boxSizing: 'border-box' }}>
        {/* LEFT — pool by status */}
        <div style={{ width: 280, flexShrink: 0, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginBottom: 10 }}>
            {LI_STATUS.map(([k, lbl]) => {
              const n = posts.filter(p => p.status === k).length;
              return <button key={k} onClick={() => setStatusTab(k)} className={'btn sm' + (statusTab === k ? ' primary' : '')} style={{ fontSize: 11.5 }}>{lbl} · {n}</button>;
            })}
          </div>
          <div className="scroll" style={{ flex: 1, minHeight: 0, paddingRight: 2 }}>
            {list.length === 0
              ? <div className="muted" style={{ fontSize: 12.5, padding: '16px 4px' }}>{statusTab === 'draft' ? 'No drafts yet — the writer tops the pool up to 7 daily.' : 'Nothing here.'}</div>
              : list.map(p => <Row key={p.id} p={p} />)}
          </div>
        </div>

        {/* MIDDLE — editor */}
        <div className="scroll" style={{ flex: 1, minWidth: 360, minHeight: 0 }}>
          {!sel
            ? <div className="muted" style={{ fontSize: 13, padding: '40px 0', textAlign: 'center' }}>Select a post, or hit ＋ New post.</div>
            : (
              <div style={{ maxWidth: 720 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>
                  <select value={sel.pillar} onChange={e => setF('pillar', e.target.value)} style={{ ...inStyle, width: 'auto' }}>
                    {LI_PILLARS.map(p => <option key={p} value={p}>{p}</option>)}
                  </select>
                  <span style={{ fontSize: 11.5, color: 'var(--ink-3)' }}>{(sel.body || '').length} chars</span>
                  {dirty && <span style={{ fontSize: 11.5, color: 'var(--primary)' }}>unsaved</span>}
                </div>

                <textarea ref={taRef} value={sel.body} onChange={e => setF('body', e.target.value)}
                  placeholder="Write your post…"
                  style={{ ...inStyle, fontSize: 14, lineHeight: 1.55, resize: 'none', overflow: 'hidden', fontFamily: 'inherit', minHeight: 240 }} />

                {/* media — collapsed to chips when empty */}
                <div style={{ display: 'flex', gap: 8, marginTop: 10, flexWrap: 'wrap' }}>
                  {!showImg && <button style={chip} onClick={() => setShowImg(true)}>＋ image</button>}
                  {!showLink && <button style={chip} onClick={() => setShowLink(true)}>＋ link</button>}
                </div>
                {showImg && <label style={{ fontSize: 12, color: 'var(--ink-2)', display: 'block', marginTop: 8 }}>Image URL (auto-suggested from the article — paste your own to swap, or upload on LinkedIn)
                  <input style={inStyle} value={sel.imageUrl || ''} placeholder="https://… image" onChange={e => setF('imageUrl', e.target.value)} /></label>}
                {showLink && <label style={{ fontSize: 12, color: 'var(--ink-2)', display: 'block', marginTop: 8 }}>Link (source article)
                  <input style={inStyle} value={sel.linkUrl || ''} placeholder="https://…" onChange={e => setF('linkUrl', e.target.value)} /></label>}

                {/* AI feedback + regenerate */}
                <div style={{ marginTop: 14, padding: 11, border: '1px solid var(--line,#e7e2d7)', borderRadius: 10, background: 'var(--primary-tint,#f7f1ea)' }}>
                  <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--ink-2)', marginBottom: 6 }}>Feedback for the assistant <span style={{ fontWeight: 400, color: 'var(--ink-3)' }}>(optional)</span></div>
                  <textarea value={feedback} onChange={e => setFeedback(e.target.value)}
                    placeholder="e.g. Punchier hook. Cut the third paragraph. Make it more concrete and personal."
                    style={{ ...inStyle, fontSize: 13, lineHeight: 1.5, minHeight: 56, resize: 'vertical', fontFamily: 'inherit' }} />
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 8, flexWrap: 'wrap' }}>
                    <button className="btn primary sm" disabled={aiBusy} onClick={regenerate}>{aiBusy ? 'Regenerating…' : '✦ AI regenerate'}</button>
                    {feedback && <button className="btn sm" disabled={aiBusy} onClick={() => setFeedback('')}>Clear</button>}
                    <span style={{ fontSize: 11, color: 'var(--ink-3)' }}>Rewrites the post in your voice{feedback.trim() ? ' with your feedback' : ''}.</span>
                  </div>
                </div>

                {/* primary actions */}
                <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, marginTop: 14 }}>
                  <button className="btn primary sm" onClick={copy}>⧉ Copy text</button>
                  <button className="btn sm" onClick={openLI}>Open LinkedIn ↗</button>
                  {sel.linkUrl && <button className="btn sm" onClick={() => window.open(sel.linkUrl, '_blank', 'noopener')}>Open link ↗</button>}
                  <button className="btn sm" disabled={!dirty} onClick={save}>Save edits</button>
                </div>
                {/* workflow */}
                <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center', marginTop: 10, paddingTop: 12, borderTop: '1px solid var(--line,#e7e2d7)' }}>
                  {sel.status !== 'pipeline' && <button className="btn sm" onClick={() => move({ status: 'pipeline' }, 'Moved to pipeline')}>→ Pipeline</button>}
                  <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
                    <input type="date" value={sel.scheduledFor || ''} onChange={e => move({ status: 'scheduled', scheduledFor: e.target.value }, 'Scheduled')} style={{ ...inStyle, width: 'auto', padding: '5px 7px' }} />
                    <span style={{ fontSize: 11, color: 'var(--ink-3)' }}>schedule</span>
                  </span>
                  <button className="btn sm" onClick={() => move({ status: 'posted', postedAt: new Date().toISOString() }, 'Marked posted ✓')}>✓ Posted</button>
                  {sel.status !== 'skipped' && <button className="btn sm" onClick={() => move({ status: 'skipped' }, 'Skipped')}>Skip</button>}
                  {sel.status !== 'draft' && <button className="btn sm" onClick={() => move({ status: 'draft', scheduledFor: null }, 'Back to drafts')}>↩ To drafts</button>}
                  <button className="linkbtn" style={{ marginLeft: 'auto', color: 'var(--rose)' }} onClick={del}>Delete</button>
                </div>
              </div>
            )}
        </div>
      </div>
    </>
  );
}
window.TabLinkedIn = TabLinkedIn;
