import React, { useState, useEffect, useMemo, useRef, useContext } from 'react';
import { Search, ChevronLeft, ChevronRight, Shield, Download, RotateCcw, Loader2 } from 'lucide-react';
import { getShortName } from '../utils/teams';
import { PlayerContext } from '../PlayerContext';

// --- BASELINE INPUT WITH LIVE AUTO-SAVE ---
// --- BASELINE INPUT WITH LIVE AUTO-SAVE & SNAP-PROOF MEMORY ---
const BaselineInput = ({ player, handleUpdate }) => {
  const [val, setVal] = useState(player.baseline_xMins != null ? Math.round(player.baseline_xMins) : '');

  useEffect(() => {
    setVal(player.baseline_xMins != null ? Math.round(player.baseline_xMins) : '');
  }, [player.baseline_xMins]);

  return (
    <input
      type="number"
      value={val}
      onChange={(e) => setVal(e.target.value)}
      onBlur={() => {
        let num = val === '' ? 0 : parseInt(val, 10);
        num = Math.max(0, Math.min(90, num)); // CAP FIX: Locks between 0 and 90
        setVal(num);
        handleUpdate(player.ID, 'baseline', null, num);
      }}
      onKeyDown={(e) => e.key === 'Enter' && e.target.blur()}
      className="w-12 bg-transparent text-center font-mono text-sm font-bold text-emerald-400 focus:outline-none focus:bg-slate-950/80 focus:ring-1 ring-emerald-500 rounded py-1 hover:bg-slate-800/50 transition-colors cursor-text [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
    />
  );
};

// --- DGW CHILD INPUT WITH LIVE AUTO-SAVE ---
const SafeChildInput = ({ initialValue, onSave }) => {
  const [val, setVal] = useState(initialValue);
  useEffect(() => setVal(initialValue), [initialValue]);
  return (
    <input
      type="number"
      value={val}
      onChange={(e) => setVal(e.target.value)}
      onBlur={() => {
        let num = val === '' ? 0 : parseFloat(val);
        num = Math.max(0, Math.min(90, num)); // CAP FIX
        setVal(num);
        onSave(num);
      }}
      onKeyDown={(e) => e.key === 'Enter' && e.target.blur()}
      className="w-12 bg-slate-950 text-center font-mono text-xs font-bold text-indigo-400 rounded py-1 outline-none focus:ring-1 ring-indigo-500 border border-slate-800 [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
    />
  );
};

// --- GW INPUT WITH LIVE AUTO-SAVE & DGW POPOVER ---
// --- GW INPUT WITH SAFE FRONTEND SAVING ---
// --- GW INPUT WITH SAFE FRONTEND SAVING ---
const GwMinsInput = ({ player, gw, handleUpdate }) => {
  const { effectiveFixtures, sessionEdits, globalXmins } = useContext(PlayerContext);
  const [showPopover, setShowPopover] = useState(false);
  const [isFocused, setIsFocused] = useState(false);
  const popoverRef = useRef(null);

  const [val, setVal] = useState(player[`${gw}_xMins`] != null ? Math.round(player[`${gw}_xMins`]) : '');

  useEffect(() => {
    setVal(player[`${gw}_xMins`] != null ? Math.round(player[`${gw}_xMins`]) : '');
  }, [player[`${gw}_xMins`]]);

  useEffect(() => {
    const handleClickOutside = (event) => {
      if (popoverRef.current && !popoverRef.current.contains(event.target)) setShowPopover(false);
    };
    if (showPopover) document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, [showPopover]);

  const matches = [];
  if (player.match_projections) {
    Object.entries(player.match_projections).forEach(([mId, mData]) => {
      const override = effectiveFixtures?.[mId];
      // THE FIX: Force Number() conversion so strings like "1" don't break the math!
      if (override && override[gw] > 0) matches.push({ ...mData, id: mId, prob: Number(override[gw]) });
      else if (!override && String(mData.default_gw) === String(gw)) matches.push({ ...mData, id: mId, prob: 1.0 });
    });
  }

  const hasMultiple = matches.length > 1 || (matches.length === 1 && Math.abs(matches[0].prob - 1.0) > 0.001);
  const isBlank = matches.length === 0;

  const TEAM_SHORTS = {
    1: "ARS", 2: "AVL", 3: "BUR", 4: "BOU", 5: "BRE",
    6: "BHA", 7: "CHE", 8: "CRY", 9: "EVE", 10: "FUL",
    11: "LEE", 12: "LIV", 13: "MCI", 14: "MUN", 15: "NEW",
    16: "NFO", 17: "SUN", 18: "TOT", 19: "WHU", 20: "WOL"
  };

  if (isBlank) return <span className="text-[10px] font-bold text-slate-600">-</span>;
  const hoverFixtureText = matches.map(m => `${TEAM_SHORTS[m.opponent_team_id] || m.opponent_team_id} ${m.is_home ? '(H)' : '(A)'}`).join(" & ");

  const handleParentSave = (newVal) => {
    let numVal = newVal === '' ? 0 : parseFloat(newVal);
    numVal = Math.max(0, Math.min(90, numVal)); // CAP FIX
    const currentAvg = Math.round(player[`${gw}_xMins`] || 0);
    if (numVal === currentAvg) {
      setVal(numVal);
      return;
    }
    setVal(numVal); // Snaps the UI instantly

    if (hasMultiple) {
      const edits = {};
      matches.forEach(m => { edits[m.id] = numVal; });
      handleUpdate(player.ID, 'batch', edits, null);
    } else {
      handleUpdate(player.ID, 'single', gw, numVal);
    }
  };

  return (
    <div className="relative flex justify-center w-full pl-2" ref={popoverRef} title={hoverFixtureText}>
      {isFocused && !hasMultiple && !isBlank && (
        <div className="absolute bottom-full mb-1 left-1/2 -translate-x-1/2 bg-slate-800 text-indigo-300 text-[10px] font-bold px-2 py-0.5 rounded shadow-xl border border-indigo-500/30 whitespace-nowrap z-tooltip pointer-events-none animate-in fade-in zoom-in-95">
          {hoverFixtureText}
        </div>
      )}
      <input
        type="number"
        title={hoverFixtureText}
        value={val}
        onClick={() => hasMultiple && setShowPopover(true)}
        onFocus={() => !hasMultiple && setIsFocused(true)}
        onChange={(e) => !hasMultiple && setVal(e.target.value)}
        onBlur={(e) => {
          if (!hasMultiple) {
            setIsFocused(false); // Hides tooltip when you click away
            handleParentSave(e.target.value);
          }
        }}
        onKeyDown={(e) => e.key === 'Enter' && e.target.blur()}
        className={`w-12 bg-transparent text-center font-mono text-sm font-bold rounded py-1 outline-none transition-colors ${hasMultiple ? 'text-indigo-300 hover:bg-slate-800/50 cursor-pointer focus:ring-1 ring-indigo-500' : 'text-emerald-400 focus:bg-slate-950/80 focus:ring-1 ring-emerald-500 hover:bg-slate-800/50'} [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none`}
      />

      {showPopover && hasMultiple && (
        <div className="absolute top-0 right-full mr-2 w-48 bg-slate-900 border border-indigo-500/50 rounded-lg shadow-2xl z-popover flex flex-col overflow-hidden animate-in fade-in zoom-in-95">
          <div className="bg-indigo-950/50 text-[9px] font-bold text-indigo-300 uppercase tracking-widest p-2 border-b border-indigo-500/30 flex justify-between items-center">
            <span>Edit Match Splits</span>
            <button onClick={(e) => { e.stopPropagation(); setShowPopover(false); }} className="text-indigo-400 hover:text-white text-xs">✕</button>
          </div>
          <div className="p-2 flex flex-col gap-2">
            {matches.map(m => {
              const oppName = TEAM_SHORTS[m.opponent_team_id] || m.opponent_team_id || "OPP";
              const fixLabel = m.is_home ? `${oppName} (H)` : `${oppName} (A)`;
              const globalMatchMins = globalXmins?.[player.ID]?.[m.id];
              const sessionVal = sessionEdits?.[player.ID]?.[`${m.id}_xMins`];
              const currentMins = Math.round(sessionVal !== undefined ? Number(sessionVal) : (globalMatchMins !== undefined ? Number(globalMatchMins) : m.xMins));

              return (
                <div key={m.id} className="flex items-center justify-between gap-2">
                  <span className="text-[10px] font-bold text-slate-300 truncate flex-1">{fixLabel} <span className="opacity-50">({Math.round(m.prob * 100)}%)</span></span>
                  <SafeChildInput
                    initialValue={currentMins}
                    onSave={(newVal) => handleUpdate(player.ID, 'single', m.id, newVal)}
                  />
                </div>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
};
export default function ProjectionsTable() {
  const {
    globalPlayers: players, setGlobalPlayers, isLoadingDB,
    projSearchTerm: searchTerm, setProjSearchTerm: setSearchTerm,
    sessionEdits, setSessionEdits, manualOverrides, effectiveFixtures, setOriginalPlayers, globalXmins
  } = useContext(PlayerContext);

  const [sortConfig, setSortConfig] = useState({ key: 'Total Points', direction: 'desc' });
  const [currentPage, setCurrentPage] = useState(1);
  const itemsPerPage = typeof window !== 'undefined' && window.innerWidth < 768 ? 15 : 50;

  const tableContainerRef = useRef(null);
  useEffect(() => {
    if (tableContainerRef.current) {
      tableContainerRef.current.scrollTo({ top: 0, behavior: 'smooth' });
    }
  }, [currentPage]);

  const [isAdmin, setIsAdmin] = useState(false);
  const [adminPassword, setAdminPassword] = useState('');
  const [showAdminLogin, setShowAdminLogin] = useState(false);
  const [clickCount, setClickCount] = useState(0);
  const clickTimeoutRef = useRef(null);

  const handleSecretClick = () => {
    setClickCount((prev) => {
      const newCount = prev + 1;
      if (newCount === 5) { setShowAdminLogin(!showAdminLogin); return 0; }
      return newCount;
    });
    if (clickTimeoutRef.current) clearTimeout(clickTimeoutRef.current);
    clickTimeoutRef.current = setTimeout(() => setClickCount(0), 1000);
  };

  const gameweeks = useMemo(() => {
    if (!players || players.length === 0) return [];
    const gwSet = new Set();
    Object.keys(players[0]).forEach(k => {
      if (/^\d+_Pts$/.test(k)) {
        const num = parseInt(k.split('_')[0], 10);
        if (num >= 1 && num <= 38) gwSet.add(num);
      }
    });
    return Array.from(gwSet).sort((a, b) => a - b);
  }, [players]);

  const getDynamicTotal = (p) => gameweeks.reduce((sum, gw) => sum + (Number(p[`${gw}_Pts`]) || 0), 0);
  const getDynamicAvg = (p) => gameweeks.length > 0 ? getDynamicTotal(p) / gameweeks.length : 0;

  const handleUpdate = async (playerId, type, gw, valueStr) => {
    const value = type === 'baseline' ? parseInt(valueStr, 10) || 0 : parseFloat(valueStr) || 0;

    // 1. Grab the active baseline from memory so Python doesn't forget it!
    const activeBaseline = sessionEdits[playerId]?.baseline_xMins;

    // 2. Prevent Python Crash: Separate Match IDs (13_vs_1) from real Gameweeks (34)
    const realGwEdits = {};
    if (type === 'batch') {
      Object.keys(gw).forEach(k => { realGwEdits[k] = gw[k]; });
    } else if (type === 'single') {
      realGwEdits[gw] = value;
    }

    // 3. Update local React memory instantly (handles DGW splits perfectly)
    setSessionEdits(prev => {
      const next = { ...prev };
      if (!next[playerId]) next[playerId] = {};

      if (type === 'baseline') {
        next[playerId]['baseline_xMins'] = value;
      } else if (type === 'batch') {
        Object.keys(gw).forEach(k => { next[playerId][`${k}_xMins`] = gw[k]; });
      } else {
        next[playerId][`${gw}_xMins`] = value;
      }

      const token = localStorage.getItem('fpl_token');
      if (token) {
        fetch('https://anayshukla-fpl-solver.hf.space/api/auth/save_session', {
          method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
          body: JSON.stringify({ saved_edits: { ...next, _solver_overrides: manualOverrides } })
        });
      }
      return next;
    });

    // 4. If this is a DGW match split ('13_vs_1'), STOP HERE. Don't crash Python!

    try {
      const payload = { player_id: playerId, is_admin: isAdmin, admin_password: adminPassword, gw_edits: realGwEdits };

      // 5. Prevent Reset Bug: ALWAYS send the baseline to Python!
      if (type === 'baseline') {
        payload.baseline_edit = value;
      } else if (activeBaseline !== undefined) {
        payload.baseline_edit = activeBaseline;
      }

      const res = await fetch('https://anayshukla-fpl-solver.hf.space/api/player/update', {
        method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload)
      });
      if (!res.ok) { if (res.status === 401) { alert("Invalid Admin Password!"); setIsAdmin(false); } throw new Error('Backend recalculation failed'); }

      const updatedRow = await res.json();

      // 6. Merge Python's exact decayed math into the table
      if (setGlobalPlayers) {
        setGlobalPlayers(prev => prev.map(p => {
          const newBaseline = type === 'baseline' ? (valueStr === '' ? null : value) : (activeBaseline !== undefined ? activeBaseline : p.baseline_xMins);

          if (p.ID === playerId) {
            // THE FIX: Protect the original match dictionary so Python doesn't wipe out the DGW tags!
            const pristineMatches = p.match_projections;
            return { ...p, ...updatedRow, match_projections: pristineMatches, baseline_xMins: newBaseline };
          }
          return p;
        }));
      }

      // 7. Lock Python's curve into memory (from your old working file)
      if (type === 'baseline') {
        setSessionEdits(prev => {
          const next = { ...prev };
          gameweeks.forEach(g => {
            next[playerId][`${g}_xMins`] = updatedRow[`${g}_xMins`];
            next[playerId][`${g}_Pts`] = updatedRow[`${g}_Pts`];
          });
          return next;
        });
      }

    } catch (err) { console.error("Recalculation error:", err); }
  };

  const resetPlayer = async (playerId) => {
    try {
      const res = await fetch('https://anayshukla-fpl-solver.hf.space/api/projections');
      const freshData = await res.json();
      const cleanPlayer = freshData.find(p => p.ID === playerId);
      if (cleanPlayer && setGlobalPlayers) {

        // THE FLICKER FIX: Apply the UI math interceptor instantly before merging the reset player!
        if (cleanPlayer.match_projections) {
          gameweeks.forEach(g => {
            cleanPlayer[`${g}_Pts`] = 0;
            cleanPlayer[`${g}_xMins`] = 0;
            cleanPlayer[`${g}_probSum`] = 0;
          });
          Object.entries(cleanPlayer.match_projections).forEach(([mId, mData]) => {
            const pts = mData.Pts !== undefined ? mData.Pts : (mData.points || 0);
            const mins = mData.xMins !== undefined ? mData.xMins : (mData.mins || 0);
            const override = effectiveFixtures?.[mId];
            if (override) {
              Object.entries(override).forEach(([gwStr, prob]) => {
                if (prob > 0) {
                  cleanPlayer[`${gwStr}_Pts`] = (cleanPlayer[`${gwStr}_Pts`] || 0) + (pts * prob);
                  cleanPlayer[`${gwStr}_xMins`] = (cleanPlayer[`${gwStr}_xMins`] || 0) + (mins * prob);
                  cleanPlayer[`${gwStr}_probSum`] = (cleanPlayer[`${gwStr}_probSum`] || 0) + prob;
                }
              });
            } else {
              const defGw = mData.default_gw;
              if (defGw) {
                cleanPlayer[`${defGw}_Pts`] = (cleanPlayer[`${defGw}_Pts`] || 0) + pts;
                cleanPlayer[`${defGw}_xMins`] = (cleanPlayer[`${defGw}_xMins`] || 0) + mins;
                cleanPlayer[`${defGw}_probSum`] = (cleanPlayer[`${defGw}_probSum`] || 0) + 1.0;
              }
            }
          });
          gameweeks.forEach(g => {
            if (cleanPlayer[`${g}_probSum`] > 0) {
              cleanPlayer[`${g}_xMins`] = cleanPlayer[`${g}_xMins`] / cleanPlayer[`${g}_probSum`];
            }
          });
        }

        setGlobalPlayers(prev => prev.map(p => p.ID === playerId ? cleanPlayer : p));
        if (setOriginalPlayers) {
          setOriginalPlayers(prev => prev.map(p => p.ID === playerId ? cleanPlayer : p));
        }
        setSessionEdits(prev => {
          const newEdits = { ...prev };
          delete newEdits[playerId];
          const token = localStorage.getItem('fpl_token');
          if (token) {
            fetch('https://anayshukla-fpl-solver.hf.space/api/auth/save_session', {
              method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
              body: JSON.stringify({ saved_edits: { ...newEdits, _solver_overrides: manualOverrides } })
            });
          }
          return newEdits;
        });
      }
    } catch (e) { console.error("Failed to reset player", e); }
  };

  const resetAll = async () => {
    try {
      const res = await fetch('https://anayshukla-fpl-solver.hf.space/api/projections');
      const freshData = await res.json();
      if (setGlobalPlayers) setGlobalPlayers(freshData);
      setSessionEdits(prev => {
        const token = localStorage.getItem('fpl_token');
        if (token) {
          fetch('https://anayshukla-fpl-solver.hf.space/api/auth/save_session', {
            method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
            body: JSON.stringify({ saved_edits: { _solver_overrides: manualOverrides } })
          });
        }
        return {};
      });
    } catch (e) { console.error("Failed to reset all", e); }
  };

  const downloadCSV = () => {
    if (!players || players.length === 0) return;
    const headers = ["Pos", "ID", "Name", "BV", "SV", "Team"];
    gameweeks.forEach(gw => {
      headers.push(`${gw}_xMins`, `${gw}_Pts`);
    });
    headers.push("Total Points", "Average Points");

    let csvContent = "data:text/csv;charset=utf-8,";
    csvContent += headers.join(",") + "\n";

    const escapeCsv = (str) => {
      if (str == null) return "";
      const s = String(str);
      return s.includes(",") ? `"${s}"` : s;
    };

    sortedAndFilteredData.forEach(p => {
      const row = [
        p.Pos,
        p.ID,
        escapeCsv(p.Name),
        p.BV,
        p.SV !== undefined ? p.SV : p.BV,
        escapeCsv(p.Team)
      ];
      gameweeks.forEach(gw => {
        const mins = Number(p[`${gw}_xMins`]) || 0;
        const pts = Number(p[`${gw}_Pts`]) || 0;
        row.push(Math.round(mins));
        row.push(pts.toFixed(2));
      });
      row.push(getDynamicTotal(p).toFixed(2));
      row.push(getDynamicAvg(p).toFixed(2));
      csvContent += row.join(",") + "\n";
    });

    const encodedUri = encodeURI(csvContent);
    const link = document.createElement("a");
    link.setAttribute("href", encodedUri);
    link.setAttribute("download", `luigis_mansion.csv`);

    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  };

  const handleSort = (key) => {
    let direction = 'desc';
    if (sortConfig.key === key && sortConfig.direction === 'desc') direction = 'asc';
    setSortConfig({ key, direction });
  };

  const sortedAndFilteredData = useMemo(() => {
    if (!players) return [];

    // Add the special character normalizer
    const cleanString = (str) => str ? str.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase() : "";
    const cleanSearch = cleanString(searchTerm);

    let filtered = searchTerm ? players.filter(p => cleanString(p.Name).includes(cleanSearch)) : [...players];

    return filtered.sort((a, b) => {
      let valA = sortConfig.key === 'Total Points' ? getDynamicTotal(a) : (sortConfig.key === 'Average Points' ? getDynamicAvg(a) : a[sortConfig.key]);
      let valB = sortConfig.key === 'Total Points' ? getDynamicTotal(b) : (sortConfig.key === 'Average Points' ? getDynamicAvg(b) : b[sortConfig.key]);
      if (sortConfig.key === 'Team') { valA = getShortName(valA); valB = getShortName(valB); }
      if (valA < valB) return sortConfig.direction === 'asc' ? -1 : 1;
      if (valA > valB) return sortConfig.direction === 'asc' ? 1 : -1;
      return 0;
    });
  }, [players, sortConfig, searchTerm, gameweeks]);

  useEffect(() => setCurrentPage(1), [searchTerm, sortConfig]);

  const totalPages = Math.ceil(sortedAndFilteredData.length / itemsPerPage);
  const paginatedData = sortedAndFilteredData.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage);

  const getMinsColor = (mins) => `rgba(52, 211, 153, ${Math.min(mins / 90, 1) * 0.4})`;
  const getPtsColor = (pts) => pts <= 0 ? 'transparent' : `rgba(16, 185, 129, ${Math.min(pts / 10, 1) * 0.6})`;

  if (isLoadingDB) return <div className="flex items-center justify-center h-64"><Loader2 size={32} className="animate-spin text-emerald-500" /></div>;

  const displayedPlayers = useMemo(() => {
    return paginatedData.map(p => {
      if (!p.match_projections) return p;
      const cloned = { ...p };

      gameweeks.forEach(g => {
        cloned[`${g}_Pts`] = 0;
        cloned[`${g}_xMins`] = 0;
        cloned[`${g}_probSum`] = 0;
      });

      const manualBaseline = sessionEdits[p.ID]?.baseline_xMins;

      Object.entries(p.match_projections).forEach(([mId, mData]) => {
        const override = effectiveFixtures?.[mId];

        let manualMins = sessionEdits[p.ID]?.[`${mId}_xMins`];
        const globalMatchMins = globalXmins?.[p.ID]?.[mId];
        if (manualMins === undefined) {
          if (globalMatchMins !== undefined) {
            manualMins = globalMatchMins;
          } else {
            let activeGw = override ? Object.keys(override).find(g => override[g] > 0) : mData.default_gw;
            if (activeGw) manualMins = sessionEdits[p.ID]?.[`${activeGw}_xMins`] ?? globalXmins?.[p.ID]?.[activeGw];
          }
        }

        // Safely get the unedited minutes from the backend
        const origMins = mData.xMins !== undefined ? mData.xMins : (mData.mins || 0);
        let activeMins = origMins;

        // THE DECAY FIX: Use a ratio to preserve the backend curve instead of flattening it
        if (manualMins !== undefined) {
          activeMins = Number(manualMins);
        } else if (manualBaseline !== undefined) {
          const origBase = p.baseline_xMins || 90;
          const ratio = origBase > 0 ? (Number(manualBaseline) / origBase) : 1.0;
          activeMins = Math.min((origMins * ratio), 90);
        }

        const scaling = (activeMins > 0 && origMins > 0) ? (activeMins / origMins) : (activeMins === 0 ? 0 : 1);
        const basePts = mData.Pts !== undefined ? mData.Pts : (mData.points || 0);
        const aPts = basePts * scaling;

        if (override) {
          Object.entries(override).forEach(([gwStr, prob]) => {
            if (prob > 0) {
              cloned[`${gwStr}_Pts`] = (cloned[`${gwStr}_Pts`] || 0) + (aPts * prob);
              cloned[`${gwStr}_xMins`] = (cloned[`${gwStr}_xMins`] || 0) + (activeMins * prob);
              cloned[`${gwStr}_probSum`] = (cloned[`${gwStr}_probSum`] || 0) + prob;
            }
          });
        } else {
          const defGw = mData.default_gw;
          if (defGw) {
            cloned[`${defGw}_Pts`] = (cloned[`${defGw}_Pts`] || 0) + aPts;
            cloned[`${defGw}_xMins`] = (cloned[`${defGw}_xMins`] || 0) + activeMins;
            cloned[`${defGw}_probSum`] = (cloned[`${defGw}_probSum`] || 0) + 1.0;
          }
        }
      });

      gameweeks.forEach(g => {
        if (cloned[`${g}_probSum`] > 0) {
          cloned[`${g}_xMins`] = cloned[`${g}_xMins`] / cloned[`${g}_probSum`];
        }
      });

      return cloned;
    });
  }, [paginatedData, sessionEdits, effectiveFixtures, gameweeks]);

  return (
    <div className="space-y-4 w-full">
      <div className="flex flex-col md:flex-row justify-between items-center gap-4 bg-slate-900/40 p-4 rounded-xl border border-slate-800 backdrop-blur-sm shadow-sm">
        <div className="flex gap-4 items-center">
          <div className="relative w-72 flex items-center">
            <div className="absolute left-0 w-10 h-full flex items-center justify-center cursor-pointer z-dropdown" onClick={handleSecretClick}>
              <Search className="text-slate-500 pointer-events-none" size={18} />
            </div>
            <input type="text" placeholder="Search players..." value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} className="w-full bg-slate-950/80 border border-slate-700 rounded-lg py-2 pl-10 pr-10 text-sm text-slate-200 focus:outline-none focus:border-luigi-400" />
            {isAdmin && <Shield size={14} className="absolute right-3 text-luigi-500" title="Admin Mode Active" />}
          </div>
          {showAdminLogin && !isAdmin && (
            <div className="flex gap-2 animate-in fade-in slide-in-from-left-4 duration-300">
              <input type="password" placeholder="Admin Pass" value={adminPassword} onChange={(e) => setAdminPassword(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && setIsAdmin(true)} className="bg-slate-950 border border-slate-700 rounded py-1.5 px-3 text-sm w-32 focus:outline-none focus:border-luigi-400 text-slate-200" />
              <button onClick={() => setIsAdmin(true)} className="bg-slate-700 hover:bg-slate-600 px-3 rounded text-sm text-white transition-colors">Login</button>
            </div>
          )}
        </div>
        <div className="flex gap-3">
          {Object.keys(sessionEdits).length > 0 && (
            <button onClick={resetAll} className="flex items-center gap-2 px-3 py-2 text-sm bg-red-900/30 text-red-400 border border-red-900/50 rounded-lg hover:bg-red-900/50 transition-colors"><RotateCcw size={16} /> Reset to Default</button>
          )}
          <button onClick={downloadCSV} className="flex items-center gap-2 px-4 py-2 text-sm bg-luigi-500 text-slate-950 font-bold rounded-lg hover:bg-luigi-400 transition-colors shadow-lg shadow-luigi-500/20"><Download size={16} /> Export CSV</button>
        </div>
      </div>

      <div ref={tableContainerRef} className="rounded-xl border border-slate-800 bg-slate-900/40 backdrop-blur-sm shadow-xl max-h-[70vh] overflow-y-auto overflow-x-auto [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar]:h-2 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:bg-slate-700/50 [&::-webkit-scrollbar-thumb]:rounded-full hover:[&::-webkit-scrollbar-thumb]:bg-slate-600/80">
        <table className="w-full text-sm text-left text-slate-300 relative">
          <thead className="text-[11px] text-slate-400 uppercase bg-slate-950 border-b border-slate-800 sticky top-0 z-sticky shadow-sm">
            <tr>
              <th onClick={() => handleSort('Pos')} className="px-3 py-4 cursor-pointer hover:text-slate-200 bg-slate-950 text-center whitespace-nowrap">Pos</th>
              <th onClick={() => handleSort('Name')} className="px-3 py-4 cursor-pointer hover:text-slate-200 bg-slate-950 whitespace-nowrap">Name</th>
              <th onClick={() => handleSort('Team')} className="px-3 py-4 cursor-pointer hover:text-slate-200 bg-slate-950 whitespace-nowrap">Team</th>
              <th onClick={() => handleSort('BV')} className="px-3 py-4 cursor-pointer hover:text-slate-200 bg-slate-950 text-center whitespace-nowrap">Cost</th>
              <th onClick={() => handleSort('baseline_xMins')} className="px-2 py-3 text-center border-l border-slate-800/50 bg-slate-900/50 cursor-pointer">
                <div className="flex flex-col items-center gap-1"><span className="text-emerald-400 font-bold tracking-wider">Baseline</span><div className="flex w-full text-[10px] text-slate-500 justify-center px-1">xMins</div></div>
              </th>
              {gameweeks.map(gw => (
                <th key={gw} className="px-2 py-3 text-center border-l border-slate-800/50 bg-slate-950">
                  <div className="flex flex-col items-center gap-1">
                    <span className="text-luigi-400 font-bold tracking-wider">GW{gw}</span>
                    <div className="flex w-full text-[10px] text-slate-500 justify-around px-1 gap-2">
                      <span className="cursor-pointer hover:text-slate-300" onClick={() => handleSort(`${gw}_xMins`)}>xMins</span>
                      <span className="cursor-pointer hover:text-slate-300" onClick={() => handleSort(`${gw}_Pts`)}>xPts</span>
                    </div>
                  </div>
                </th>
              ))}
              <th onClick={() => handleSort('Total Points')} className="px-3 py-4 text-right cursor-pointer hover:text-slate-200 text-luigi-400 border-l border-slate-800/50 bg-slate-950 whitespace-nowrap">Total</th>
              <th className="px-3 py-4 text-center bg-slate-950 border-l border-slate-800/50 whitespace-nowrap">Reset</th>
            </tr>
          </thead>

          <tbody className="divide-y divide-slate-800/50">
            {displayedPlayers.map((player) => (
              <tr key={player.ID} className={`transition-colors group ${sessionEdits[player.ID] ? 'bg-luigi-900/10' : 'hover:bg-slate-800/30'}`}>
                <td className="px-3 py-2 font-medium text-slate-500 text-center whitespace-nowrap">{player.Pos}</td>
                <td className="px-3 py-2 font-bold text-slate-100 truncate max-w-[160px]">{player.Name}</td>
                <td className="px-3 py-2 text-slate-400 font-bold text-center">{getShortName(player.Team)}</td>
                <td className="px-3 py-2 text-center whitespace-nowrap">{player.BV}</td>

                <td className="p-0 border-l border-slate-800/30 bg-slate-900/30">
                  <div className="w-full h-full p-1.5 flex items-center justify-center">
                    <BaselineInput
                      player={player}
                      handleUpdate={handleUpdate}
                    />
                  </div>
                </td>

                {gameweeks.map(gw => (
                  <td key={gw} className="p-0 border-l border-slate-800/30">
                    <div className="flex h-full items-stretch">
                      <div className="relative w-1/2 p-2 border-r border-slate-800/20 flex items-center justify-center" style={{ backgroundColor: getMinsColor(player[`${gw}_xMins`]) }}>
                        <GwMinsInput
                          player={player}
                          gw={gw}
                          handleUpdate={handleUpdate}
                        />

                        {/* TAG FIX: Tiny, padded, and pointer-events-none so it never blocks clicks */}
                        {player[`${gw}_probSum`] > 1.01 && (
                          <span className="absolute top-0 right-0 text-[7px] leading-none py-[2px] px-1 bg-indigo-500/90 text-white rounded-bl font-black tracking-tighter pointer-events-none" title={`DGW`}>
                            DGW
                          </span>
                        )}
                        {player[`${gw}_probSum`] < 0.99 && player[`${gw}_probSum`] > 0.01 && (
                          <span className="absolute top-0 right-0 text-[7px] leading-none py-[2px] px-1 bg-orange-500/90 text-white rounded-bl font-black pointer-events-none" title="Odds of the fixture happening">
                            %
                          </span>
                        )}
                      </div>
                      <div className="w-1/2 p-2 text-center font-mono text-sm font-bold flex items-center justify-center" style={{ backgroundColor: getPtsColor(player[`${gw}_Pts`]) }}>
                        <span className="drop-shadow-md">{Number(player[`${gw}_Pts`]).toFixed(2)}</span>
                      </div>
                    </div>
                  </td>
                ))}

                <td className="px-3 py-2 text-right font-bold text-luigi-400 font-mono border-l border-slate-800/30 bg-slate-900/20 group-hover:bg-transparent">{getDynamicTotal(player).toFixed(2)}</td>
                <td className="px-2 py-2 text-center border-l border-slate-800/30">
                  {sessionEdits[player.ID] && (
                    <button onClick={() => resetPlayer(player.ID)} className="p-1 text-slate-500 hover:text-red-400 transition-colors" title="Reset Player">
                      <RotateCcw size={16} />
                    </button>
                  )}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
      {totalPages > 1 && (
        <div className="flex items-center justify-between px-4 py-3 bg-slate-900/40 border border-slate-800 rounded-xl mt-2">
          <span className="text-sm text-slate-400">
            Showing <span className="font-bold text-slate-200">{(currentPage - 1) * itemsPerPage + 1}</span> to <span className="font-bold text-slate-200">{Math.min(currentPage * itemsPerPage, sortedAndFilteredData.length)}</span> of <span className="font-bold text-slate-200">{sortedAndFilteredData.length}</span> players
          </span>
          <div className="flex gap-2">
            <button onClick={() => setCurrentPage(p => Math.max(1, p - 1))} disabled={currentPage === 1} className="p-1.5 rounded-lg bg-slate-800 text-slate-300 hover:bg-slate-700 disabled:opacity-50 transition-colors">
              <ChevronLeft size={20} />
            </button>
            <button onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))} disabled={currentPage === totalPages} className="p-1.5 rounded-lg bg-slate-800 text-slate-300 hover:bg-slate-700 disabled:opacity-50 transition-colors">
              <ChevronRight size={20} />
            </button>
          </div>
        </div>
      )}
    </div>
  );
}