// FindingCard.jsx — one finding, laid out the way you read it:
// the explanation on the left, the code it refers to on the right.
function FindingCard() {
  return (
    <div style={{
      background: 'var(--hh-bg-sunken)',
      border: '1px solid var(--hh-border)',
      borderRadius: 8,
      overflow: 'hidden',
    }}>
      {/* Header */}
      <div style={{
        display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap',
        padding: '12px 16px', borderBottom: '1px solid var(--hh-border)', background: 'var(--hh-surface-1)',
      }}>
        <span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--hh-text)', minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis' }}>
          <span style={{ color: 'var(--hh-text-muted)' }}>HH-3148 ·</span> withdraw_vault/src/lib.rs
        </span>
        <div style={{ display: 'flex', gap: 8, flexShrink: 0 }}>
          <span className="pill pill-mint">poc verified</span>
          <span className="pill pill-violet">critical</span>
        </div>
      </div>

      <div className="finding-split">
        {/* Left: what it is and why it matters. */}
        <div className="finding-prose">
          <CardLabel label="explanation" />
          <p style={{ fontFamily: 'var(--font-sans)', fontSize: 14, lineHeight: 1.65, color: 'var(--hh-text-muted)', margin: '0 0 20px' }}>
            <FTok>authority</FTok> is declared as <FTok>AccountInfo</FTok>, which performs no signer check.
            Anchor only enforces the signer constraint when the field is typed <FTok>Signer</FTok> or bound
            by <FTok>has_one</FTok>. The <FTok>#[account(mut)]</FTok> macro does not, so any account can be
            supplied as the withdrawal authority and drain the vault.
          </p>

          <CardLabel label="location" />
          <p style={{ fontFamily: 'var(--font-mono)', fontSize: 12.5, lineHeight: 1.6, color: 'var(--hh-cyan)', margin: '0 0 20px', wordBreak: 'break-all' }}>
            withdraw_vault/src/lib.rs:39-40
          </p>

          <CardLabel label="evaluation" />
          <dl className="finding-meta">
            <dt>verdict</dt><dd style={{ color: 'var(--hh-text)' }}>exploitable</dd>
            <dt>impact</dt><dd>vault drained without the owner&rsquo;s signature</dd>
            <dt>class</dt><dd>cwe-862 · solana/signer</dd>
          </dl>
        </div>

        {/* Right: the code, and the test that proves it. */}
        <div className="finding-code">
          <CardLabel label="vulnerable code" meta="lib.rs" />
          <div style={{
            padding: '4px 16px 20px',
            fontFamily: 'var(--font-code)', fontWeight: 500, fontSize: 12.5, lineHeight: 1.85,
            color: 'var(--hh-text)', overflowX: 'auto',
          }}>
            <FLine n="34"><FK>#[derive(Accounts)]</FK></FLine>
            <FLine n="35"><FK>pub struct</FK> <FT>Withdraw</FT>{`<'info> {`}</FLine>
            <FLine n="36">{`    #[`}<FS c="#7effa4">account</FS>{`(mut)]`}</FLine>
            <FLine n="37">{`    `}<FK>pub</FK>{` vault: `}<FT>Account</FT>{`<'info, `}<FT>Vault</FT>{`>,`}</FLine>
            <FLine n="38">{` `}</FLine>
            <FLine n="39" hl>{`    `}<FS c="#7d8ea8" italic>{'// never constrained as a signer'}</FS></FLine>
            <FLine n="40" hl>{`    `}<FK>pub</FK>{` authority: `}<FT>AccountInfo</FT>{`<'info>,`}</FLine>
            <FLine n="41">{`    `}<FK>pub</FK>{` token_program: `}<FT>Program</FT>{`<'info, `}<FT>Token</FT>{`>,`}</FLine>
            <FLine n="42">{`}`}</FLine>
          </div>

          <CardLabel label="proof of concept" meta="tests/poc/HH-3148.ts" rule />
          <div style={{
            padding: '4px 16px 20px',
            fontFamily: 'var(--font-code)', fontWeight: 500, fontSize: 12, lineHeight: 1.85,
            color: 'var(--hh-text)', overflowX: 'auto',
          }}>
            <FLine n="12">{`  `}<FK>const</FK>{` attacker = `}<FT>Keypair</FT>{`.generate();`}</FLine>
            <FLine n="13">{`  `}<FK>await</FK>{` program.methods.`}<FS c="#7effa4">withdraw</FS>{`(`}<FS c="#f5b35a">amount</FS>{`)`}</FLine>
            <FLine n="14">{`    .accounts({ vault, authority: attacker.publicKey })`}</FLine>
            <FLine n="15">{`    .rpc(); `}<FS c="#7d8ea8" italic>{'// drained without victim signature'}</FS></FLine>
          </div>
        </div>
      </div>
    </div>
  );
}

function CardLabel({ label, meta, rule }) {
  return (
    <div style={{
      borderTop: rule ? '1px solid var(--hh-border)' : 'none',
      padding: rule ? '16px 16px 4px' : '0 0 8px',
      display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap',
    }}>
      <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--hh-text-muted)' }}>{label}</span>
      {meta && <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--hh-text-muted)' }}>{meta}</span>}
    </div>
  );
}

function FTok({ children }) {
  return <code style={{ background: 'var(--hh-surface-2)', padding: '1px 5px', borderRadius: 4, color: 'var(--hh-cyan)', fontSize: 12 }}>{children}</code>;
}

function FLine({ n, hl, children }) {
  return (
    <div style={{
      display: 'block',
      background: hl ? 'rgba(230,59,74,0.14)' : 'transparent',
      borderLeft: hl ? '2px solid #e63b4a' : '2px solid transparent',
      paddingLeft: 8, marginLeft: -10,
      whiteSpace: 'pre',
    }}>
      <span className="hh-tabular" style={{ color: '#5d6f8a', display: 'inline-block', width: 28, userSelect: 'none' }}>{n}</span>
      {children}
    </div>
  );
}

/* Prefixed to stay clear of the other syntax helpers in the global scope. */
function FK({ children }) { return <span style={{ color: '#b388ff' }}>{children}</span>; }
function FT({ children }) { return <span style={{ color: '#67e4ff' }}>{children}</span>; }
function FS({ c, italic, children }) { return <span style={{ color: c, fontStyle: italic ? 'italic' : 'normal' }}>{children}</span>; }

window.FindingCard = FindingCard;
