'use client';

import { useState } from 'react';
import PropRow, { PropRowProp, PropRowResult, propRowKey, Tier } from '@/components/PropRow';
import { getHeadshotUrl, PLAYER_SILHOUETTE, HeadshotSport } from '@/lib/playerHeadshot';

/**
 * PlayerCard — one player and all their props (Session 19).
 *
 * Slate redesign: previously each prop was an independent row, so a
 * player with 4 props (Pts/Reb/Ast/3PT) appeared as 4 stripes that
 * repeated the player's name. That reads like a spreadsheet, not a
 * sports product. PlayerCard groups: a header with headshot + name +
 * team sits above N PropRow children.
 *
 * Headshot resolution lives in `lib/playerHeadshot.ts`. The `<img>`
 * fall-through swaps to the bundled silhouette if the CDN 404s on a
 * player whose league hasn't published a headshot yet.
 */

export interface PlayerCardProps {
  player: string;
  sport: HeadshotSport;
  team?: string;
  position?: string;
  /** League ID — NBA stats.com ID, WNBA player ID, or MLB people ID. */
  playerId?: string | number | null;
  /** ESPN ID fallback (used when no league ID is known). */
  espnId?: string | number | null;
  /** Pre-cached headshot URL (soccer / API-Football). */
  photoUrl?: string | null;
  props: PropRowProp[];
  gradedProps: Map<string, PropRowResult>;
  loadingKey?: string | null;
  errorByKey?: Record<string, string | undefined>;
  tier?: Tier;
  onGrade: (prop: PropRowProp) => void;
  onUpgrade?: () => void;
}

export default function PlayerCard(props: PlayerCardProps) {
  const {
    player, sport, team, position, playerId, espnId, photoUrl,
    props: propList, gradedProps, loadingKey, errorByKey,
    tier = 'free', onGrade, onUpgrade,
  } = props;

  // Compute the initial headshot URL — onError swaps to silhouette.
  const initialUrl = getHeadshotUrl({
    sport,
    playerId,
    espnId,
    cachedPhotoUrl: photoUrl,
  });
  const [headshotSrc, setHeadshotSrc] = useState(initialUrl);

  const subtitle = [team, position].filter(Boolean).join(' · ');

  return (
    <div
      style={{
        background: 'var(--bg-2, #12121A)',
        borderTop: '1px solid var(--border, #1A1A24)',
      }}
    >
      <div
        style={{
          display: 'flex',
          alignItems: 'center',
          gap: 12,
          padding: '10px 16px',
          background: 'rgba(255,255,255,0.02)',
        }}
      >
        {/* eslint-disable-next-line @next/next/no-img-element */}
        <img
          src={headshotSrc}
          alt={`${player} headshot`}
          width={40}
          height={40}
          loading="lazy"
          onError={() => {
            if (headshotSrc !== PLAYER_SILHOUETTE) setHeadshotSrc(PLAYER_SILHOUETTE);
          }}
          style={{
            width: 40,
            height: 40,
            borderRadius: '50%',
            objectFit: 'cover',
            background: 'var(--bg-elevated, #15151F)',
            border: '1px solid var(--border, #1A1A24)',
            flexShrink: 0,
          }}
        />
        <div style={{ minWidth: 0, flex: 1 }}>
          <div
            style={{
              fontSize: 14,
              fontWeight: 600,
              color: 'var(--text-0, #F0F0F5)',
              letterSpacing: '-0.005em',
              whiteSpace: 'nowrap',
              overflow: 'hidden',
              textOverflow: 'ellipsis',
            }}
          >
            {player}
          </div>
          {subtitle && (
            <div
              className="mono"
              style={{
                marginTop: 2,
                fontSize: 11,
                color: 'var(--text-tertiary, #6B6B7B)',
                letterSpacing: '0.06em',
                textTransform: 'uppercase',
              }}
            >
              {subtitle}
            </div>
          )}
        </div>
        <div
          className="mono"
          style={{
            fontSize: 10,
            color: 'var(--text-tertiary, #6B6B7B)',
            background: 'rgba(255,255,255,0.04)',
            padding: '3px 8px',
            borderRadius: 999,
            whiteSpace: 'nowrap',
          }}
          aria-label={`${propList.length} props for ${player}`}
        >
          {propList.length} prop{propList.length === 1 ? '' : 's'}
        </div>
      </div>
      <ul style={{ listStyle: 'none', padding: 0, margin: 0 }}>
        {propList.map((p) => {
          const key = propRowKey(p);
          return (
            <PropRow
              key={key}
              prop={p}
              result={gradedProps.get(key) ?? null}
              loading={loadingKey === key}
              error={errorByKey?.[key] ?? null}
              tier={tier}
              onRead={onGrade}
              onUpgrade={onUpgrade}
            />
          );
        })}
      </ul>
    </div>
  );
}

/**
 * groupPropsByPlayer — preserves the original prop order (first
 * appearance of a player wins their slot), so the Slate's sort
 * (alphabetical by player) is the actual visual sort.
 */
export function groupPropsByPlayer(propList: PropRowProp[]): Array<{ player: string; props: PropRowProp[] }> {
  const byPlayer = new Map<string, PropRowProp[]>();
  for (const p of propList) {
    const existing = byPlayer.get(p.player);
    if (existing) existing.push(p);
    else byPlayer.set(p.player, [p]);
  }
  return Array.from(byPlayer.entries()).map(([player, props]) => ({ player, props }));
}
