// upprofiler — /check (pre-post)

const SAMPLE_DRAFTS = {
  empty: { score: 0, verdict: 'paste', reasons: [] },
};

// Heuristic, deterministic faux-scoring tied to keywords
function scoreDraft(text) {
  if (!text || !text.trim()) return null;

  const t = text.toLowerCase();
  let score = 50;
  const positive = [];
  const negative = [];

  // On-pillar signal words (Jasmin's positioning)
  const pillars = [
    ['storytelling', 9, 'On-pillar: storytelling framework'],
    ['linkedin', 6, 'Channel-specific signal'],
    ['dm', 5, 'On-pillar: DM-to-sales'],
    ['profile', 6, 'On-pillar: positioning'],
    ['positioning', 8, 'Core thesis match'],
    ['headline', 6, 'On-pillar: profile mechanics'],
    ['conviction', 7, 'Brand vocabulary'],
    ['founder', 5, 'ICP keyword'],
    ['client', 5, 'ICP keyword'],
    ['offer', 5, 'On-pillar: offer creation'],
    ['signed', 4, 'Outcome language'],
    ['revenue', 5, 'Outcome language'],
    ['link up', 6, 'Brand mention'],
  ];
  pillars.forEach(([kw, w, label]) => {
    if (t.includes(kw)) { score += w; positive.push(label); }
  });

  // Off-pillar / drift signals
  const drift = [
    ['travel', -10, 'Off-pillar: lifestyle drift'],
    ['vacation', -10, 'Off-pillar: leisure'],
    ['vibes', -8, 'Lifestyle drift'],
    ['just thinking', -7, 'Low-conviction opener'],
    ['random', -7, 'No pillar attribution'],
    ['blessed', -8, 'Off-tone'],
    ['hustle', -6, 'Cliché vocabulary'],
    ['grind', -5, 'Cliché vocabulary'],
    ['hot take', -6, 'Cliché framing pulls students not buyers'],
    ['unpopular opinion', -5, 'Engagement-bait framing'],
    ['guys', -3, 'Casual filler'],
  ];
  drift.forEach(([kw, w, label]) => {
    if (t.includes(kw)) { score += w; negative.push(label); }
  });

  // Length signals
  const words = text.trim().split(/\s+/).length;
  if (words < 30) { score -= 6; negative.push('Too short for dwell-time'); }
  else if (words > 60 && words < 220) { score += 4; positive.push('Healthy dwell-time length'); }
  else if (words > 350) { score -= 4; negative.push('Too long, drop-off risk'); }

  // Hook (first line)
  const firstLine = text.trim().split('\n')[0] || '';
  if (firstLine.length < 80 && firstLine.length > 8) { score += 3; positive.push('Tight opening hook'); }
  if (/^[A-Z]/.test(firstLine.trim())) { /* fine */ } else { score -= 2; }

  // Number anchoring
  if (/\d/.test(text)) { score += 4; positive.push('Numeric anchor present'); }

  // Question
  if (text.trim().endsWith('?')) { score += 2; positive.push('CTA question'); }

  // Hashtag spam
  const hashes = (text.match(/#/g) || []).length;
  if (hashes > 5) { score -= 5; negative.push('Hashtag spam · downweighted'); }

  score = Math.max(0, Math.min(100, score));
  return { score, positive, negative, words };
}

function VerdictBadge({ score }) {
  if (score === null) {
    return (
      <div style={{
        display: 'inline-flex', padding: '8px 16px', borderRadius: 100,
        border: '1px dashed var(--line)', color: 'var(--mute)',
        fontFamily: 'var(--font-mono)', fontSize: 12, letterSpacing: '0.12em', textTransform: 'uppercase',
      }}>Awaiting draft</div>
    );
  }
  let label, kind;
  if (score >= 75) { label = '✓ Post it · this slaps'; kind = 'good'; }
  else if (score >= 55) { label = '~ Tighten the hook'; kind = 'warn'; }
  else { label = '✕ Bin it · drifting hard'; kind = 'warn'; }
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 10,
      padding: '12px 22px', borderRadius: 100,
      background: kind === 'good' ? 'rgba(31,171,137,0.1)' : 'rgba(244,165,43,0.12)',
      color: kind === 'good' ? 'var(--good)' : 'var(--warn)',
      border: `1px solid ${kind === 'good' ? 'rgba(31,171,137,0.3)' : 'rgba(244,165,43,0.35)'}`,
      fontFamily: 'var(--font-mono)', fontWeight: 500, fontSize: 13,
      letterSpacing: '0.12em', textTransform: 'uppercase',
    }}>{label}</div>
  );
}

function PageCheck({ onNavigate, score: globalScore }) {
  const [draft, setDraft] = useState(`I've been writing online for 17 years. Today, I run a business in 70+ countries.

Read that again, please. Notice what's missing?

Most of you will focus on the followers. The reach. The vanity.

Here's what I focused on:

1. Posting like the same human every single time. Profile, posts, DMs — same voice.
2. Coaching 300+ founders 1:1. (no courses, no funnels)
3. Saying "no" to 9 out of every 10 brand deals.
4. Giving away the playbook for free, then charging for the work.

That's it. That's the post.

Hope this helps someone today.

— Coach J ❤️

P.S. If you're tired of guessing whether your LinkedIn is working, paste your URL into upprofiler. Honest answer in 90 seconds.`);

  const result = useMemo(() => scoreDraft(draft), [draft]);
  const score = result?.score ?? null;
  const verdictKey = score === null ? 'empty' : score >= 75 ? 'post' : score >= 55 ? 'edge' : 'drift';

  return (
    <div>
      <Nav current="/check" onNavigate={onNavigate} score={globalScore} delta={9} />
      <div className="page">
        <PageHeader
          id="/check"
          name="Score a draft"
          sub="Paste it. Watch the score. I'll tell you straight up — post it, tighten it, or bin it. No fluff."
          tag={{ kind: 'pink', label: 'Daily ritual' }}
          right={<span className="label-mono">v0.2 · Jasmin's framework</span>}
        />

        <div style={{ display: 'grid', gridTemplateColumns: '1.6fr 1fr', gap: 24 }}>
          {/* Composer */}
          <Card id="/check.composer" title="Your draft" tag={{ label: result ? `${result.words} words` : '0 words' }}>
            <textarea
              value={draft}
              onChange={(e) => setDraft(e.target.value)}
              placeholder="Paste your LinkedIn draft here…"
              spellCheck={false}
              style={{
                width: '100%',
                minHeight: 360,
                resize: 'vertical',
                fontFamily: 'var(--font-display)',
                fontSize: 16,
                lineHeight: 1.6,
                color: 'var(--ink)',
                background: 'var(--bg)',
                border: '1px solid var(--line)',
                borderRadius: 8,
                padding: 18,
                outline: 'none',
              }}
              onFocus={(e) => e.target.style.borderColor = 'var(--pink)'}
              onBlur={(e) => e.target.style.borderColor = 'var(--line)'}
            />
            <div className="row between mt-16">
              <div className="row gap-12">
                <button className="btn btn-secondary btn-sm" onClick={() => setDraft('')}>Clear</button>
                <button className="btn btn-secondary btn-sm" onClick={() => setDraft(`Bosnian sunset. Truffle pasta. Espresso that hits different.\n\nSometimes you just need to switch off, vibes only. Back Monday guys.`)}>Try a drifting one</button>
                <button className="btn btn-secondary btn-sm" onClick={() => setDraft(`Jasmin Alić posts 4 times a week. That's it.\n\nMost creators are stressing themselves out:\n\n→ Obsessing over posting times.\n→ Worrying about the algorithm.\n→ Thinking they need to post every single day.\n\nSound familiar?\n\nThe one mechanic that actually decides your reach? Whether your profile and your posts sound like the same human.\n\nI measured it across 300+ Link Up members. The gap between what you claim and what you post is the throttle. Close it and the algorithm starts pushing you.\n\nHere are the 4 moves that signed real client revenue this quarter.\n\nP.S. Read that again, please. ❤️`)}>Try a strong one</button>
              </div>
              <button className="btn btn-primary btn-sm" disabled={!result || score < 55} onClick={() => onNavigate('/check/posted')}>Send to LinkedIn →</button>
            </div>
          </Card>

          {/* Verdict column */}
          <div className="col gap-24">
            <Card id="/check.score" title="Live conviction" tag={{ kind: 'pink', label: 'Live' }}
              style={{ background: 'var(--gradient-hero)' }}>
              <div className="center" style={{ flexDirection: 'column', padding: '24px 0 12px' }}>
                <ScoreRing
                  value={score ?? 0}
                  size={220}
                  strokeWidth={10}
                  showPulse={score !== null}
                  label="Draft score"
                  animateKey={`check-${verdictKey}`}
                />
              </div>
              <div className="center mt-16">
                <VerdictBadge score={score} />
              </div>
              <div style={{ marginTop: 20, paddingTop: 20, borderTop: '1px solid var(--line)' }}>
                <div className="label-mono" style={{ marginBottom: 10 }}>Why this score</div>
                <div style={{ fontSize: 14, color: 'var(--ink-soft)', lineHeight: 1.55 }}>
                  {score === null && 'Paste a draft. I score it the second you stop typing.'}
                  {score !== null && score >= 75 && 'On-pillar, tight hook, real numbers. This is a yes — post it today.'}
                  {score !== null && score >= 55 && score < 75 && 'Solid bones, mixed signals. Tighten the first line or anchor with a number. Then ship it.'}
                  {score !== null && score < 55 && 'This drifts from what your profile claims. The algorithm will quietly bury it and your audience will forget you. Reframe or save the draft for the weekend personal account.'}
                </div>
              </div>
            </Card>

            <Card id="/check.signals" title="Signal breakdown">
              <div className="col gap-16">
                {result?.positive?.length > 0 && (
                  <div>
                    <div className="label-mono" style={{ color: 'var(--good)', marginBottom: 10 }}>+ Lifting</div>
                    <div className="col gap-8">
                      {result.positive.map((p, i) => (
                        <div key={i} className="row gap-8" style={{ fontSize: 13 }}>
                          <span style={{ color: 'var(--good)', fontFamily: 'var(--font-mono)' }}>+</span>
                          <span style={{ color: 'var(--ink-soft)' }}>{p}</span>
                        </div>
                      ))}
                    </div>
                  </div>
                )}
                {result?.negative?.length > 0 && (
                  <div>
                    <div className="label-mono" style={{ color: 'var(--warn)', marginBottom: 10 }}>− Drifting</div>
                    <div className="col gap-8">
                      {result.negative.map((p, i) => (
                        <div key={i} className="row gap-8" style={{ fontSize: 13 }}>
                          <span style={{ color: 'var(--warn)', fontFamily: 'var(--font-mono)' }}>−</span>
                          <span style={{ color: 'var(--ink-soft)' }}>{p}</span>
                        </div>
                      ))}
                    </div>
                  </div>
                )}
                {(!result || (result.positive.length === 0 && result.negative.length === 0)) && (
                  <div className="muted" style={{ fontSize: 13 }}>Signals appear as you type.</div>
                )}
              </div>
            </Card>
          </div>
        </div>

      </div>
      <Footer />
    </div>
  );
}

window.PageCheck = PageCheck;
