import { useMemo } from 'react';
import { ArrowRightLeft, CircleDot, Volleyball } from 'lucide-react';
import { fmt, useT } from '@/lib/i18n';
import { parseEvents, halfTimeScore, type EventKind, type ParsedEvent } from '@/lib/matchEvents';
import type { MatchLiveEvent } from '@/lib/types';

/** Crisp event markers instead of emoji: ball icon for goals, card-shaped
 *  color chips for bookings, arrows for substitutions. */
export function EventIcon({ kind }: { kind: EventKind }) {
  if (kind === 'goal') return <Volleyball size={14} className="shrink-0 text-accent" />;
  if (kind === 'yellow') return <span className="inline-block h-3.5 w-2.5 shrink-0 rounded-[2px] bg-gold" />;
  if (kind === 'red') return <span className="inline-block h-3.5 w-2.5 shrink-0 rounded-[2px] bg-loss" />;
  if (kind === 'sub') return <ArrowRightLeft size={13} className="shrink-0 text-muted" />;
  return <CircleDot size={10} className="shrink-0 text-faint" />;
}

type Row =
  | { t: 'event'; e: ParsedEvent }
  | { t: 'divider'; label: string; score?: string; live?: boolean };

/** Home goals fade in from accent at the top, away goals out to info at the
 *  bottom — the spine itself hints at the side convention. */
const SPINE_GRADIENT =
  'linear-gradient(180deg, color-mix(in oklab, var(--app-accent) 70%, transparent), var(--app-line) 14%, var(--app-line) 86%, color-mix(in oklab, var(--app-info) 70%, transparent))';

function MinutePill({ e }: { e: ParsedEvent }) {
  const t = useT();
  const cls =
    e.kind === 'goal'
      ? e.side === 'away'
        ? 'bg-info text-surface shadow-md'
        : 'bg-accent text-accent-ink shadow-md'
      : e.kind === 'yellow'
        ? 'border-[1.5px] border-gold bg-panel text-gold'
        : e.kind === 'red'
          ? 'border-[1.5px] border-loss bg-panel text-loss'
          : 'border border-line bg-elevated text-muted';
  return (
    <span className={`tnum inline-flex h-[30px] min-w-12 items-center justify-center rounded-full px-2.5 text-[13px] font-semibold ${cls}`}>
      {e.minute != null ? fmt(t.live.minute, { n: e.minute }) : '·'}
    </span>
  );
}

function GoalCard({ e, mobile }: { e: ParsedEvent; mobile?: boolean }) {
  const t = useT();
  const away = e.side === 'away';
  // Side-colored edge faces the spine on desktop; always left on mobile.
  const edge = mobile || away
    ? away ? 'border-l-[3px] border-l-info' : 'border-l-[3px] border-l-accent'
    : 'border-r-[3px] border-r-accent';
  const own = e.detail?.type === 'ownGoal';
  const detailText =
    e.detail?.type === 'assist' ? fmt(t.match.assist, { name: e.detail.name })
    : e.detail?.type === 'penalty' ? t.match.penalty
    : e.detail?.type === 'raw' ? e.detail.text
    : null;
  return (
    <div className={`${mobile ? 'w-full' : 'w-[300px] max-w-full'} rounded-xl border border-line bg-panel-2 p-3 ${edge}`}>
      <div className="flex items-center justify-between gap-2">
        <span className={`text-[10px] font-bold uppercase tracking-wide ${away ? 'text-info' : 'text-accent'}`}>
          {own ? t.match.ownGoal : t.match.goal}
        </span>
        {e.score && (
          <span className={`tnum rounded-md px-1.5 py-0.5 text-xs ${away ? 'bg-info/15 text-info' : 'bg-accent/15 text-accent'}`}>
            {e.score[0]}–{e.score[1]}
          </span>
        )}
      </div>
      <div className={`mt-1 text-base font-bold text-ink ${mobile ? '' : 'truncate'}`}>{e.title}</div>
      {detailText && <div className={`mt-0.5 text-xs text-faint ${mobile ? '' : 'truncate'}`}>{detailText}</div>}
    </div>
  );
}

function MinorChip({ e, mobile }: { e: ParsedEvent; mobile?: boolean }) {
  const side = mobile
    ? e.side === 'away' ? 'border-l-[3px] border-l-info' : 'border-l-[3px] border-l-accent'
    : '';
  return (
    <span className={`inline-flex max-w-full items-center gap-2 rounded-xl border border-line bg-panel px-2.5 py-1.5 ${side}`}>
      <EventIcon kind={e.kind} />
      <span className="truncate text-[13.5px] text-ink-soft">{e.title}</span>
      {e.subOut && <span className="truncate text-[13.5px] text-faint">{e.subOut}</span>}
    </span>
  );
}

/** Neutral happenings (delays, VAR…) sit on the spine like a soft divider. */
function NeutralChip({ e, showMinute }: { e: ParsedEvent; showMinute?: boolean }) {
  const t = useT();
  return (
    <span className="inline-block max-w-full rounded-2xl border border-line bg-elevated px-3.5 py-1.5 text-center text-[11px] text-muted">
      {showMinute !== false && e.minute != null && <span className="tnum">{fmt(t.live.minute, { n: e.minute })} · </span>}
      {e.title}
    </span>
  );
}

function DividerPill({ row }: { row: Extract<Row, { t: 'divider' }> }) {
  return (
    <span
      className={`inline-flex items-center gap-1.5 whitespace-nowrap rounded-full border px-3.5 py-1.5 text-[11px] font-bold uppercase tracking-wider ${
        row.live ? 'border-live/40 bg-elevated text-live' : 'border-line bg-elevated text-muted'
      }`}
    >
      {row.live && <span className="live-dot h-1.5 w-1.5 rounded-full bg-live" />}
      {row.label}
      {row.score && <span className="tnum normal-case text-ink">{row.score}</span>}
    </span>
  );
}

export interface MatchTimelineProps {
  events: MatchLiveEvent[];
  status: 'scheduled' | 'live' | 'finished';
  minute?: number | null;
  homeScore?: number | null;
  awayScore?: number | null;
}

export function MatchTimeline({ events, status, minute, homeScore, awayScore }: MatchTimelineProps) {
  const t = useT();

  const rows = useMemo<Row[]>(() => {
    const parsed = parseEvents(events);
    const out: Row[] = [{ t: 'divider', label: t.match.kickOff }];
    // Half-time divider goes after the last first-half event — only once the
    // match has actually reached the second half.
    const reachedSecondHalf =
      status === 'finished' ||
      (status === 'live' && (minute ?? 0) > 45) ||
      parsed.some((e) => (e.minute ?? 0) > 45);
    let htAfter = -1;
    if (reachedSecondHalf) {
      for (let i = 0; i < parsed.length; i++) {
        const m = parsed[i]?.minute;
        if (m != null && m <= 45) htAfter = i;
      }
    }
    const ht = halfTimeScore(parsed);
    parsed.forEach((e, i) => {
      out.push({ t: 'event', e });
      if (i === htAfter) out.push({ t: 'divider', label: t.match.halfTime, score: `${ht[0]}–${ht[1]}` });
    });
    if (reachedSecondHalf && htAfter === -1) out.splice(1, 0, { t: 'divider', label: t.match.halfTime, score: `${ht[0]}–${ht[1]}` });
    if (status === 'finished') {
      out.push({ t: 'divider', label: t.common.fullTime, score: `${homeScore ?? 0}–${awayScore ?? 0}` });
    } else if (status === 'live') {
      out.push({
        t: 'divider',
        label: minute != null ? `${fmt(t.live.minute, { n: minute })} · ${t.common.liveNow}` : t.common.liveNow,
        live: true,
      });
    }
    return out;
  }, [events, status, minute, homeScore, awayScore, t]);

  return (
    <div>
      {/* Desktop / tablet: center spine, home left · away right */}
      <div className="relative hidden px-2 py-4 sm:block">
        {/* inset so the spine ends behind the kick-off / full-time pills */}
        <div aria-hidden className="absolute bottom-8 left-1/2 top-8 w-0.5 -translate-x-1/2" style={{ background: SPINE_GRADIENT }} />
        {rows.map((row, i) => {
          if (row.t === 'divider') {
            return (
              <div key={i} className="relative z-10 my-2 flex items-center gap-3">
                <span className="h-px flex-1 bg-line" />
                <DividerPill row={row} />
                <span className="h-px flex-1 bg-line" />
              </div>
            );
          }
          const e = row.e;
          if (e.side === null) {
            return (
              <div key={i} className="relative z-10 my-2 flex justify-center">
                <NeutralChip e={e} />
              </div>
            );
          }
          const content = e.kind === 'goal' ? <GoalCard e={e} /> : <MinorChip e={e} />;
          return (
            <div
              key={i}
              className={`relative z-10 grid grid-cols-[minmax(0,1fr)_76px_minmax(0,1fr)] items-center gap-1.5 ${e.kind === 'goal' ? 'my-3.5' : 'my-2'}`}
            >
              <div className="flex justify-end">{e.side === 'home' && content}</div>
              <div className="flex justify-center"><MinutePill e={e} /></div>
              <div className="flex justify-start">{e.side === 'away' && content}</div>
            </div>
          );
        })}
      </div>

      {/* Phones: single left rail, side shown by the colored card edge */}
      <div className="relative py-3 pl-2 pr-3.5 sm:hidden">
        <div aria-hidden className="absolute bottom-7 left-[35px] top-7 w-0.5" style={{ background: SPINE_GRADIENT }} />
        {rows.map((row, i) => {
          if (row.t === 'divider') {
            return (
              <div key={i} className="relative z-10 my-2 flex items-center gap-3">
                <DividerPill row={row} />
                <span className="h-px flex-1 bg-line" />
              </div>
            );
          }
          const e = row.e;
          return (
            <div key={i} className="relative z-10 my-2.5 grid grid-cols-[54px_1fr] items-center gap-2.5">
              <div className="flex justify-center"><MinutePill e={e} /></div>
              <div>
                {e.side === null ? <NeutralChip e={e} showMinute={false} /> : e.kind === 'goal' ? <GoalCard e={e} mobile /> : <MinorChip e={e} mobile />}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}
