'use client';

import { useEffect, useState } from 'react';
import { GradePill } from '@/components/GradeCard';
import PlayerAvatar from '@/components/vyndr/PlayerAvatar';
import BookWordmark from '@/components/vyndr/BookWordmark';
import TierRecord from '@/components/vyndr/TierRecord';
import { buildTierRows } from '@/lib/tierRecord';

/**
 * PublicProfile (A1 Session 10) — the public ledger record for one handle.
 *
 * DATA SEMANTICS: every row here is a REAL settled ledger entry — outcome and
 * actual value. No closing-line value renders on this public surface (Session
 * 65 un-claim). Nothing curated: publishing shows the
 * ENTIRE settled record, misses included. The header NEVER renders a
 * percentage under min_sample (20) settles — it shows RECORD BUILDING.
 *
 * Unknown and unpublished handles arrive as the same 404 — the page renders
 * one indistinguishable not-found state for both.
 */

interface ProfileRow {
  id: string;
  player_name: string;
  sport: string;
  stat: string;
  line: number;
  side: 'over' | 'under';
  locked_odds?: string | null;
  book?: string | null;
  grade: string;
  model_value?: number | null;
  game_date: string;
  closing_line?: number | null;
  clv?: number | null;
  clv_result?: 'beat' | 'faded' | 'flat' | null;
  outcome?: 'hit' | 'miss' | 'push' | null;
  actual_value?: number | null;
  revised_from_grade?: string | null;
}

interface TierBucket { settled: number; hits: number; misses: number; pushes?: number; hit_pct: number | null }

interface ProfileAggregate {
  settled: number;
  hits: number;
  misses: number;
  pushes: number;
  hit_pct: number | null;
  clv_sample: number;
  clv_beat: number;
  beat_close_pct: number | null;
  pending: number;
  // Wave 3 (Addition 2) — per-tier calibration (survives the API + proxy
  // untouched, inside the aggregate). The credibility centerpiece.
  by_tier?: Record<string, TierBucket>;
}

interface ProfilePayload {
  handle: string;
  aggregate: ProfileAggregate | null;
  entries: ProfileRow[];
  min_sample?: number;
  // Wave 5A (D2) — the HOUSE/model profile: the public user_id=NULL record,
  // shareable without a claimed public_profiles row. `label` distinguishes it
  // from a user profile ("VYNDR MODEL · PUBLIC RECORD").
  house?: boolean;
  label?: string;
}

const SPORT_COLOR: Record<string, string> = {
  nba: '#E94B3C',
  mlb: '#1E90FF',
  wnba: '#FFB347',
  soccer: '#7BC96F',
};

export default function PublicProfile({ handle }: { handle: string }) {
  const [data, setData] = useState<ProfilePayload | null>(null);
  const [state, setState] = useState<'loading' | 'ready' | 'notfound'>('loading');

  useEffect(() => {
    let active = true;
    setState('loading');
    fetch(`/api/profiles/${encodeURIComponent(handle)}`)
      .then(async (r) => {
        if (!active) return;
        if (!r.ok) { setState('notfound'); return; }
        const d = await r.json();
        if (!active) return;
        setData(d);
        setState('ready');
      })
      .catch(() => { if (active) setState('notfound'); });
    return () => { active = false; };
  }, [handle]);

  if (state === 'loading') {
    return (
      <section style={{ minHeight: '50vh', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <p className="mono" style={{ color: 'var(--text-tertiary)' }}>Loading record…</p>
      </section>
    );
  }

  if (state === 'notfound' || !data) {
    // Same state for unknown AND unpublished — the API never tells us which.
    return (
      <section style={{ maxWidth: 640, margin: '0 auto', padding: '64px 16px 120px', textAlign: 'center' }}>
        <p className="mono" style={{ fontSize: 12, fontWeight: 800, letterSpacing: '0.12em', color: 'var(--amber, #FFB347)', marginBottom: 10 }}>
          NO RECORD HERE
        </p>
        <h1 style={{ fontSize: 24, fontWeight: 700, marginBottom: 8 }}>This profile does not exist or is not published.</h1>
        <p style={{ color: 'var(--text-secondary)', fontSize: 14 }}>
          VYNDR ledgers are private by default. A record only appears here when its owner publishes it.
        </p>
      </section>
    );
  }

  const agg = data.aggregate;
  const minSample = Number(data.min_sample) > 0 ? Number(data.min_sample) : 20;
  const isHouse = Boolean(data.house);

  return (
    <section style={{ maxWidth: 1100, margin: '0 auto', padding: '32px 16px 120px' }}>
      <header style={{ marginBottom: 20 }}>
        <p className="mono" style={{ fontSize: 11, fontWeight: 700, letterSpacing: '0.12em', color: 'var(--g-a, #00D4A0)', marginBottom: 8 }}>
          {isHouse ? (data.label || 'VYNDR MODEL · PUBLIC RECORD') : 'PUBLIC LEDGER'}
        </p>
        <h1 className="mono" style={{ fontSize: 32, fontWeight: 800, letterSpacing: '-0.02em', marginBottom: 6 }}>
          {isHouse ? 'VYNDR MODEL' : `@${data.handle}`}
        </h1>
        <p style={{ color: 'var(--text-secondary)', fontSize: 15 }}>
          {isHouse
            ? 'The VYNDR model’s public record. Every graded read, wins and misses. Nothing curated.'
            : 'Every settled read. Wins and misses. Nothing curated.'}
        </p>
      </header>

      {/* Record header — never a percentage under min_sample settles. */}
      <RecordHeader agg={agg} minSample={minSample} />

      {/* Wave 3 (Addition 2) — the record BY GRADE TIER, the proof that higher
          grades win more. Same shared component as the dashboard + ledger. */}
      {agg && buildTierRows(agg.by_tier || {}).length > 0 && (
        <div className="surface diagonal-cut" style={{ padding: 20, marginBottom: 20 }}>
          <TierRecord byTier={agg.by_tier} minSample={minSample} dense />
        </div>
      )}

      {data.entries.length === 0 ? (
        <div className="surface diagonal-cut" style={{ padding: 48, textAlign: 'center' }}>
          <p className="mono" style={{ fontSize: 12, fontWeight: 800, letterSpacing: '0.1em', color: 'var(--text-tertiary)', marginBottom: 8 }}>
            NO SETTLED READS YET
          </p>
          <p style={{ color: 'var(--text-secondary)', fontSize: 14 }}>
            Reads land here as they settle against real results.
          </p>
        </div>
      ) : (
        <div style={{ display: 'grid', gap: 12, gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))' }}>
          {data.entries.map((row, i) => (
            <ProfileCard key={row.id} row={row} index={i} />
          ))}
        </div>
      )}
    </section>
  );
}

/**
 * The record HERO (DS4 · billboard — DESIGN-SPEC Part 3 + Part 6 #4). This is
 * the shareable surface Kev pitches partners with. One bold figure among muted
 * context: the HIT RATE as a large mono tabular number, the raw record demoted.
 * Session 65 removed the closing-value figure + verification badge — see the
 * un-claim note inside.
 */
function RecordHeader({ agg, minSample }: { agg: ProfileAggregate | null; minSample: number }) {
  const ready = Boolean(agg && agg.settled >= minSample && agg.hit_pct != null);
  // Session 65 — UN-CLAIM. The closing-value verification badge and the
  // secondary close-beat figure were REMOVED from this public surface. Both
  // read `beat_close_pct`, derived from the legacy overwritable `closing_line`
  // (C4 open). The badge was gated behind CLV_CAPTURE_RELIABLE — one env flag
  // away from re-asserting verification on the same data Session 64 deleted
  // from these rows as untrustworthy. Removal is DISPLAY ONLY: the aggregate,
  // `clvCaptureReliable()` and the whole closing-value data path are untouched,
  // and the earned directional badge stays Analyst+Desk (never public). The
  // claim returns here when closing value genuinely renders here.
  return (
    <div
      className="surface diagonal-cut"
      style={{ padding: 24, marginBottom: 20, border: `1px solid ${ready ? 'var(--g-a, #00D4A0)' : 'var(--border)'}` }}
    >
      {ready && agg ? (
        <>
          <div style={{ display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap', marginBottom: 16 }}>
            <span className="mono" style={{ fontSize: 11, fontWeight: 700, letterSpacing: '0.1em', color: 'var(--text-tertiary)' }}>
              RECORD · LAST 30D
            </span>
          </div>
          {/* HERO figures — hit rate is the largest thing on the page. */}
          <div style={{ display: 'flex', gap: 40, flexWrap: 'wrap', alignItems: 'flex-end' }}>
            <div>
              <div className="mono" style={{ fontSize: 56, fontWeight: 800, lineHeight: 0.95, letterSpacing: '-0.03em', color: 'var(--g-a, #00D4A0)', fontVariantNumeric: 'tabular-nums' }}>
                {agg.hit_pct}%
              </div>
              <div className="mono" style={{ fontSize: 10.5, fontWeight: 700, letterSpacing: '0.12em', color: 'var(--text-tertiary)', marginTop: 4 }}>
                HIT RATE · {agg.hits}-{agg.misses}
              </div>
            </div>
            <div style={{ marginLeft: 'auto' }}>
              <div className="mono" style={{ fontSize: 14, fontWeight: 600, color: 'var(--text-tertiary)', fontVariantNumeric: 'tabular-nums' }}>
                {agg.pending} pending
              </div>
            </div>
          </div>
        </>
      ) : (
        <div>
          <p className="mono" style={{ fontSize: 13, fontWeight: 800, letterSpacing: '0.1em', color: 'var(--amber, #FFB347)', marginBottom: 6 }}>
            RECORD BUILDING
          </p>
          <p style={{ fontSize: 14, color: 'var(--text-secondary)' }}>
            Percentages render at {minSample} settled reads.
            {agg && (
              <span className="mono" style={{ color: 'var(--text-primary)' }}>
                {' '}{agg.settled} settled · {agg.pending} pending
              </span>
            )}
          </p>
        </div>
      )}
    </div>
  );
}

function OutcomeChip({ row }: { row: ProfileRow }) {
  if (!row.outcome) {
    return <span className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)' }}>PENDING</span>;
  }
  const color = row.outcome === 'hit' ? 'var(--g-a, #00D4A0)'
    : row.outcome === 'miss' ? 'var(--miss, #FF6B6B)' : 'var(--text-secondary)';
  const mark = row.outcome === 'hit' ? '✓ HIT' : row.outcome === 'miss' ? '✕ MISS' : '– PUSH';
  return (
    <span className="mono" style={{ fontSize: 12, fontWeight: 700, color }}>
      {mark}{row.actual_value != null ? ` (${row.actual_value})` : ''}
    </span>
  );
}

// Session 64 — the legacy C4 CLV chip was REMOVED from this PUBLIC surface.
// It rendered row.clv/clv_result, built on the overwritable closing_line where
// 637/699 rows had closing == locked, so 522 of its 578 "flat"s encoded a
// CAPTURE FAILURE as a held line. Public profiles now show the settled result
// only. The directional badge is Analyst+Desk and is deliberately NOT added
// here — this surface is public and never receives dclv data.

function ProfileCard({ row, index }: { row: ProfileRow; index: number }) {
  const sportColor = SPORT_COLOR[row.sport] || 'var(--text-secondary)';
  return (
    <article className={`surface diagonal-cut animate-fade-up stagger-${(index % 6) + 1}`} style={{ padding: 16 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 8 }}>
        <span className="mono" style={{ fontSize: 10, fontWeight: 700, padding: '2px 8px', borderRadius: 999, background: `${sportColor}1F`, color: sportColor }}>
          {row.sport.toUpperCase()}
        </span>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
          {row.revised_from_grade && (
            <span className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)', textDecoration: 'line-through' }}>
              {row.revised_from_grade}
            </span>
          )}
          <GradePill grade={row.grade} />
        </span>
      </div>
      {/* Real entity identity (DS0) — headshot / team-colored monogram. */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 4 }}>
        <PlayerAvatar name={row.player_name} sport={row.sport} size={34} />
        <div style={{ minWidth: 0 }}>
          <h3 style={{ fontSize: 15, fontWeight: 600, marginBottom: 1, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{row.player_name}</h3>
          <p className="mono" style={{ fontSize: 12, color: 'var(--text-secondary)', textTransform: 'capitalize', margin: 0 }}>
            {row.side} {row.line} {row.stat.replace(/_/g, ' ')}
          </p>
        </div>
      </div>
      <p className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)', marginBottom: 12 }}>
        {row.book ? <BookWordmark book={row.book} size={11} /> : '—'}{row.locked_odds ? ` · ${row.locked_odds}` : ''} · {row.game_date}
        {row.model_value != null && <span> · MODEL {row.model_value}</span>}
      </p>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 8, flexWrap: 'wrap' }}>
        <OutcomeChip row={row} />
      </div>
    </article>
  );
}
