import React, { useContext, memo } from "react";
import { Plus, RotateCcw } from "lucide-react";
import { getShortName } from "../utils/teams";
import { getPlayerPrice } from "../utils/fplLogic";
import { PlayerContext, FixturesContext } from "../PlayerContext";

// Fixed card dimensions — these are design-space pixels (before PitchView scaling).
// Sized to be prominent and legible on desktop, scaling gracefully on mobile via
// the PitchView scale transform. Keeps proportions consistent across devices.
const CARD_W = 108;
const CARD_H = 108; // photo card height only (label strip is separate, in flow below)

// Badge sizing — using percentage of card width ensures badges scale proportionally
// with the card rather than being fixed pixels that iOS may try to inflate.
// 15% of 88px = ~13px at design scale — large enough to read and tap comfortably.
const BADGE_PCT = 0.25;

export const PlayerCardVisual = ({
  player,
  isBench,
  captainId,
  viceId,
  handleCapChange,
  playerCardGWs,
  fixtures,
  activeGW,
  onPlayerClick,
  onUndo,
  onSolverUndo,
  activeChipType,
}) => {
  if (player.isBlank) {
    return (
      <div className="flex flex-col items-center" style={{ width: CARD_W }}>
        <div
          onClick={() => onPlayerClick(player)}
          style={{ width: CARD_W, height: CARD_H }}
          className="relative flex flex-col items-center justify-center cursor-pointer border-2 border-dashed border-slate-500 bg-slate-900/60 rounded-xl hover:bg-slate-800 hover:border-emerald-400 transition-all z-20 shadow-inner group"
        >
          {player.replacedPlayer && (
            <div
              className="absolute left-[2px] top-[2px] flex flex-col gap-[1px] z-40 pointer-events-auto"
              style={{
                WebkitTextSizeAdjust: "none",
                textSizeAdjust: "none",
                fontSize: 0,
              }}
            >
              <div
                role="button"
                tabIndex={0}
                onPointerDown={(e) => e.stopPropagation()}
                onClick={(e) => onUndo(e, player.ID, player.replacedPlayer)}
                style={{
                  width: CARD_W * BADGE_PCT,
                  height: CARD_W * BADGE_PCT,
                  minWidth: 0,
                  minHeight: 0,
                  touchAction: "manipulation",
                }}
                className="flex items-center justify-center rounded-full bg-red-600 hover:bg-red-500 text-white transition-colors border border-red-400 shadow-lg cursor-pointer select-none"
                title="Undo transfer"
              >
                <RotateCcw size={7} strokeWidth={2.5} />
              </div>
            </div>
          )}
          <Plus className="text-slate-500 group-hover:text-emerald-400 transition-colors mb-1" size={24} />
          <span className="text-[10px] font-black text-slate-500 group-hover:text-emerald-400 uppercase tracking-widest">
            {player.Pos}
          </span>
        </div>
        {/* Placeholder label area so blank slots have identical height to real cards */}
        <div style={{ height: 55 }} />
      </div>
    );
  }

  const isCap = player.ID === captainId;
  const isVice = player.ID === viceId;
  const photoUrl = player.photo
    ? `https://wsrv.nl/?url=resources.premierleague.com/premierleague25/photos/players/110x140/${player.photo.replace(".jpg", ".png")}&output=webp&w=110&q=75`
    : "";

  const effectiveFixtures = useContext(FixturesContext);

  const TEAM_MAP = {
    "Arsenal": 1, "Aston Villa": 2, "Burnley": 3, "Bournemouth": 4, "AFC Bournemouth": 4, "Brentford": 5,
    "Brighton": 6, "Brighton and Hove Albion": 6, "Chelsea": 7, "Crystal Palace": 8, "Everton": 9, "Fulham": 10,
    "Leeds": 11, "Leeds United": 11, "Liverpool": 12, "Man City": 13, "Manchester City": 13,
    "Man Utd": 14, "Manchester United": 14, "Newcastle": 15, "Newcastle United": 15,
    "Nott'm Forest": 16, "Nottingham Forest": 16, "Sunderland": 17,
    "Spurs": 18, "Tottenham": 18, "Tottenham Hotspur": 18,
    "West Ham": 19, "West Ham United": 19, "Wolves": 20, "Wolverhampton Wanderers": 20
  };

  const getActiveMatches = (teamName, gw) => {
    if (!fixtures || !fixtures.length || !gw) return [];
    const activeMatches = [];
    fixtures.forEach(m => {
      if (m.home_team !== teamName && m.away_team !== teamName) return;
      const hId = m.home_team_id || TEAM_MAP[m.home_team] || m.home_team;
      const aId = m.away_team_id || TEAM_MAP[m.away_team] || m.away_team;
      const matchId = `${hId}_vs_${aId}`;
      const override = effectiveFixtures?.[matchId];
      if (override) {
        if (Number(override[gw]) >= 0.01) activeMatches.push({ ...m, prob: Number(override[gw]) });
      } else if (String(m.GW) === String(gw)) {
        activeMatches.push({ ...m, prob: 1.0 });
      }
    });
    return activeMatches;
  };

  const currentGwMatches = getActiveMatches(player.Team, activeGW);
  const isBlankThisGw = currentGwMatches.length === 0;

  const renderFixtures = (teamName, gw) => {
    const activeMatches = gw === activeGW ? currentGwMatches : getActiveMatches(teamName, gw);
    if (activeMatches.length === 0) {
      return <span className="text-[9px] font-bold text-slate-600">BLANK</span>;
    }
    return activeMatches.map((m, idx) => {
      const isHome = m.home_team === teamName;
      const oppName = getShortName(isHome ? m.away_team : m.home_team);
      const loc = isHome ? "H" : "A";
      const isGhost = m.prob < 1;
      return (
        <React.Fragment key={idx}>
          <span
            title={isGhost ? `${Math.round(m.prob * 100)}% chance of playing in GW${gw}` : undefined}
            className={`inline-flex items-center whitespace-nowrap ${isGhost ? "text-indigo-200 cursor-help" : "text-slate-200"}`}
          >
            <span className="text-[8px] font-black tracking-tighter leading-none">{oppName}</span>
            <span className={`text-[8px] font-bold ml-[1px] leading-none ${isGhost ? "text-indigo-400" : "text-slate-400"}`}>
              ({loc})
            </span>
            {isGhost && (
              <span
                className="text-[6px] font-black text-indigo-100 ml-[2px] bg-indigo-500/50 px-[2px] py-[1px] rounded-[2px] border border-indigo-400/40 tracking-tighter shadow-sm flex items-center justify-center"
                style={{ lineHeight: 1 }}
              >
                {Math.round(m.prob * 100)}%
              </span>
            )}
          </span>
          {idx < activeMatches.length - 1 && (
            <span className="text-[6px] text-slate-500 mx-[2px] flex items-center leading-none">•</span>
          )}
        </React.Fragment>
      );
    });
  };

  // EV text sizes — primary GW gets the strongest visual weight, subsequent
  // GWs taper down. Sized for comfortable reading at the larger card scale.
  const evStyles = [
    "text-emerald-400 text-[13px] font-extrabold",
    "text-emerald-500 text-[11px] font-bold",
    "text-emerald-600 text-[9px] font-semibold",
  ];

  const isTransferIn = Boolean(player.replacedPlayer || onSolverUndo);

  return (
    /*
      OUTER WRAPPER — this is what the row gap acts on.
      Width is exactly CARD_W so the gap math in PitchView is predictable.
      The wrapper is a flex-col: [photo card] then [label strip].
    */
    <div
      onClick={() => onPlayerClick(player)}
      className="relative flex flex-col items-center cursor-grab"
      style={{ width: CARD_W }}
    >
      {/* ── PHOTO CARD ── fixed size, photo is % of this div specifically */}
      <div
        className={`relative flex-shrink-0 rounded-[10px] transition-transform duration-200 transform-gpu overflow-visible
          ${isTransferIn
            ? "bg-gradient-to-t from-cyan-900/60 via-cyan-900/5 to-transparent -translate-y-2 shadow-[0_20px_16px_-8px_rgba(0,0,0,0.8)] z-30"
            : "bg-transparent z-10"
          }
          ${isBench ? (activeChipType === "bb" ? "opacity-85" : "opacity-50") : "opacity-100"}
        `}
        style={{ width: CARD_W, height: CARD_H }}
      >
        {/*
          C / V / Reset stack.
          Key fixes for mobile responsiveness:
          1. Use <div role="button"> instead of <button> — buttons have browser-enforced
             minimum touch targets that cause the "huge badges" issue on iOS/mobile.
          2. Size badges as percentage of card width so they scale proportionally.
          3. Use touch-action: manipulation to prevent double-tap zoom interference.
          4. -webkit-text-size-adjust: none (not 100%) fully disables text inflation.
          5. appearance: none and explicit min-width/min-height: 0 to override defaults.
        */}
        <div
          className="absolute left-[2px] top-[2px] flex flex-col gap-[1px] z-40 pointer-events-auto"
          style={{
            WebkitTextSizeAdjust: "none",
            textSizeAdjust: "none",
            fontSize: 0, // container has no font size — children set their own
          }}
        >
          {!isBench && handleCapChange && (
            <>
              <div
                role="button"
                tabIndex={0}
                onPointerDown={(e) => e.stopPropagation()}
                onClick={(e) => { e.stopPropagation(); handleCapChange(player.ID, "C"); }}
                style={{
                  width: CARD_W * BADGE_PCT,
                  height: CARD_W * BADGE_PCT,
                  minWidth: 0,
                  minHeight: 0,
                  touchAction: "manipulation",
                }}
                className={`flex items-center justify-center rounded-full text-[7px] font-bold leading-none transition-colors shadow-md transform-gpu cursor-pointer select-none
                  ${isCap
                    ? activeChipType === "tc"
                      ? "bg-purple-500 text-white border border-purple-300"
                      : "bg-yellow-400 text-slate-900 border border-white"
                    : "bg-slate-900/90 text-slate-400 border border-slate-700 hover:text-yellow-400"
                  }`}
              >
                {isCap && activeChipType === "tc" ? "TC" : "C"}
              </div>
              <div
                role="button"
                tabIndex={0}
                onPointerDown={(e) => e.stopPropagation()}
                onClick={(e) => { e.stopPropagation(); handleCapChange(player.ID, "V"); }}
                style={{
                  width: CARD_W * BADGE_PCT,
                  height: CARD_W * BADGE_PCT,
                  minWidth: 0,
                  minHeight: 0,
                  touchAction: "manipulation",
                }}
                className={`flex items-center justify-center rounded-full text-[7px] font-bold leading-none transition-colors shadow-md cursor-pointer select-none
                  ${isVice ? "bg-slate-300 text-slate-900 border border-white" : "bg-slate-900/90 text-slate-400 border border-slate-700 hover:text-white"}`}
              >
                V
              </div>
            </>
          )}
          {onSolverUndo ? (
            <div
              role="button"
              tabIndex={0}
              onPointerDown={(e) => e.stopPropagation()}
              onClick={(e) => { e.stopPropagation(); onSolverUndo(player); }}
              style={{
                width: CARD_W * BADGE_PCT,
                height: CARD_W * BADGE_PCT,
                minWidth: 0,
                minHeight: 0,
                touchAction: "manipulation",
              }}
              className="flex items-center justify-center rounded-full bg-red-600 hover:bg-red-500 text-white transform-gpu transition-colors border border-red-400 shadow-md cursor-pointer select-none"
            >
              <RotateCcw size={7} strokeWidth={2.5} />
            </div>
          ) : player.replacedPlayer ? (
            <div
              role="button"
              tabIndex={0}
              onPointerDown={(e) => e.stopPropagation()}
              onClick={(e) => onUndo(e, player.ID, player.replacedPlayer)}
              style={{
                width: CARD_W * BADGE_PCT,
                height: CARD_W * BADGE_PCT,
                minWidth: 0,
                minHeight: 0,
                touchAction: "manipulation",
              }}
              className="flex items-center justify-center rounded-full bg-red-600 hover:bg-red-500 text-white transform-gpu transition-colors border border-red-400 shadow-md cursor-pointer select-none"
            >
              <RotateCcw size={7} strokeWidth={2.5} />
            </div>
          ) : null}
        </div>

        {/* EV numbers — top-right corner. Primary GW most prominent,
            subsequent GWs taper down. Anti-inflation styles applied. */}
        <div
          className="absolute right-[3px] top-[2px] flex flex-col items-end z-30 pointer-events-none drop-shadow-[0_1px_2px_rgba(0,0,0,0.8)]"
          style={{
            WebkitTextSizeAdjust: "none",
            textSizeAdjust: "none",
          }}
        >
          {playerCardGWs.map((gw, i) => (
            <span key={gw} className={`${evStyles[i]} leading-tight tabular-nums`}>
              {Number(player[`${gw}_Pts`] || 0).toFixed(2)}
            </span>
          ))}
        </div>

        {/* Player photo — bottom-[-8px] lets the player's body dip into the name strip */}
        {photoUrl ? (
          <img
            src={photoUrl}
            alt={player.Name}
            loading="lazy"
            decoding="async"
            draggable="false"
            className={`absolute bottom-[-8px] w-full object-contain pointer-events-none z-10 transform-gpu`}
            style={{ height: "95%" }}
          />
        ) : (
          <div
            className={`absolute bottom-[-8px] w-full object-contain pointer-events-none z-10 transform-gpu`}
            style={{ height: "70%" }}
          />
        )}
      </div>

      {/*
        LABEL STRIP — in normal flow below the photo card.
        Width is 110% of CARD_W (≈92px @ design) so the strip slightly
        overhangs the card for that classic FPL look, while still fitting
        comfortably inside the CARD_GAP (24px) so neighbouring labels never
        collide on any viewport.
        WebkitTextSizeAdjust: "100%" prevents iOS Safari from inflating the
        small label text — without this the name/stats wrap or overflow on
        mobile.
      */}
      <div
        draggable="false"
        className={`flex flex-col items-center z-30 pointer-events-none mt-[1px] flex-shrink-0 ${isBench ? "opacity-80" : "opacity-100"}`}
        style={{
          width: "100%",
          WebkitTextSizeAdjust: "none",
          textSizeAdjust: "none",
        }}
      >
        <div className={`w-full text-center py-[3px] truncate px-1 font-bold text-[9px] leading-tight rounded-t shadow-md
          ${isTransferIn ? "bg-cyan-600 text-white" : "bg-slate-950 text-slate-100 border border-slate-700"}`}>
          {player.Name}
        </div>
        <div className="w-full bg-slate-200 border-x border-slate-700 flex justify-center items-center gap-1 py-[3px] shadow-inner">
          <span className={`text-[9px] font-black flex items-baseline gap-[2px] leading-none ${isBlankThisGw ? "text-slate-400" : "text-slate-800"}`}>
            {isBlankThisGw ? "-" : (player[`${activeGW}_xMins`] ?? 90)}
            <span className="text-[9px] font-bold text-slate-500 uppercase tracking-tight">xMins</span>
          </span>
          <span className="text-slate-400 font-light text-[9px] leading-none">|</span>
          <span className="text-[9px] font-black text-emerald-700 leading-none">
            £{getPlayerPrice(player).toFixed(1)}
          </span>
        </div>
        <div className="w-full bg-slate-900 border-x border-b border-slate-700 flex items-center rounded-b shadow-md px-0.5 overflow-hidden" style={{ height: 19 }}>
          <div className="flex items-center justify-center w-full whitespace-nowrap overflow-hidden">
            {renderFixtures(player.Team, activeGW)}
          </div>
        </div>
      </div>
    </div>
  );
};

export default memo(PlayerCardVisual);
