<!DOCTYPE html>

<html>

<head>

  <base target="_top">

  <style>

    body { font-family: Arial, sans-serif; margin: 20px; background-color: #f8f9fa; color: #333; }

    .container { max-width: 1400px; margin: 0 auto; background: white; padding: 25px; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); }

    h2 { color: #1a73e8; margin-top: 0; }

    .box { margin-bottom: 15px; max-width: 500px; }

    

    /* CONTROLS LAYOUT */

    .controls-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; border-bottom: 2px solid #f1f3f4; padding-bottom: 15px; }

    .right-controls { display: flex; align-items: center; gap: 15px; }

    .sort-box { width: auto !important; display: inline-block; padding: 8px; border: 1px solid #ccc; border-radius: 4px; font-size: 14px; }

    input[type="text"], input[type="number"], select { width: 100%; padding: 10px; margin: 5px 0; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; font-size: 16px; }

    button { background-color: #1a73e8; color: white; padding: 12px 20px; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; width: 100%; transition: background-color 0.2s ease; }

    button:hover { filter: brightness(90%); }

    .hidden { display: none !important; }

    

    /* FINALIZE BUTTON TOP HEADER STYLING */

    .finalize-btn { background-color: #e65100; padding: 10px 20px; font-weight: bold; font-size: 15px; letter-spacing: 0.3px; width: auto; margin: 0; }

    .finalize-btn:disabled { background-color: #9e9e9e; cursor: not-allowed; }

    

    /* DASHBOARD SPLIT-SCREEN LAYOUT */

    .dashboard-grid { display: flex; gap: 30px; align-items: flex-start; }

    .left-panel { flex: 7; min-width: 0; }

    .right-panel { flex: 5; min-width: 0; display: flex; flex-direction: column; gap: 20px; }

    

    /* Data Tables */

    table { width: 100%; border-collapse: collapse; margin-top: 10px; }

    th, td { border: 1px solid #ddd; padding: 12px; text-align: left; transition: background-color 0.2s; }

    th { background-color: #f1f3f4; color: #202124; }

    tr:nth-child(even) { background-color: #f8f9fa; }

    

    /* Input Adjustments */

    .text-center { text-align: center; }

    .score-input { width: 80px !important; text-align: center; margin: 0 auto !important; padding: 6px !important; display: block; }

    .score-input:disabled { background-color: #e8eaed !important; color: #5f6368; cursor: not-allowed; }

    .loading { color: #666; font-style: italic; }

    .tie-warning { background-color: #f8d7da !important; border: 2px solid #dc3545 !important; }

    

    /* CHECK-IN STYLES */

    .check-box-input { width: 22px; height: 22px; cursor: pointer; accent-color: #1a73e8; }

    .checked-in-row td { background-color: #d4edda !important; } 

    

    /* STANDINGS CARDS STYLES */

    .leaderboard-card { background: #ffffff; border: 1px solid #e0e0e0; border-radius: 6px; padding: 15px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); }

    .leaderboard-card h4 { margin: 0 0 10px 0; color: #1a73e8; border-bottom: 1px solid #e8f0fe; padding-bottom: 5px; text-transform: uppercase; font-size: 14px; letter-spacing: 0.5px; text-align: center; }

    .leaderboard-table { font-size: 13px; margin-top: 5px; }

    .leaderboard-table th, .leaderboard-table td { padding: 6px 10px; }

    .leaderboard-table tr:nth-child(1) { font-weight: bold; background-color: #fff8e1; }

    .rank-col { width: 45px; font-weight: bold; color: #5f6368; text-align: center !important; }


    /* CUSTOM POP-UP MODAL OVERLAY STYLES */

    .modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: center; z-index: 1000; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; }

    .modal-overlay.active { opacity: 1; pointer-events: auto; }

    .modal-box { background: white; padding: 30px; border-radius: 8px; max-width: 500px; width: 90%; box-shadow: 0 10px 25px rgba(0,0,0,0.2); transform: translateY(-20px); transition: transform 0.3s ease; text-align: center; }

    .modal-overlay.active .modal-box { transform: translateY(0); }

    .modal-box h3 { margin-top: 0; font-size: 22px; }

    .modal-box p { color: #5f6368; font-size: 16px; line-height: 1.5; margin: 15px 0 25px 0; }

    .modal-buttons { display: flex; gap: 15px; justify-content: center; }

    .modal-btn { padding: 12px 24px; border: none; border-radius: 4px; font-size: 16px; font-weight: bold; cursor: pointer; flex: 1; }

    .btn-confirm { background-color: #e65100; color: white; }

    .btn-cancel { background-color: #e8eaed; color: #333; }

    .btn-success { background-color: #1a73e8; color: white; }

  </style>

</head>

<body>


<div class="container">

  <div id="loginSection">

    <h2>Contest Director Portal</h2>

    <p>Please enter your unique Access Token to open your assigned digital score sheet.</p>

    <div class="box">

      <input type="text" id="tokenInput" placeholder="Enter Access Token Here...">

    </div>

    <button id="loginBtn" onclick="login()">Access Score Sheet</button>

    <p id="loginError" style="color: red;"></p>

  </div>


  <div id="portalSection" class="hidden">

    <div class="controls-row">

      <div>

        <h2 id="welcomeText">Welcome</h2>

        <h3 id="assignmentText" style="color: #5f6368; margin: 0;">Loading Assignment...</h3>

      </div>

      

      <div class="right-controls">

        <div id="sortContainer">

          <label for="sortSelect" style="font-weight: bold; font-size: 14px;">Sort Roster: </label>

          <select id="sortSelect" class="sort-box" onchange="applySort()">

            <option value="name">Alphabetical by Name</option>

            <option value="school">By School, then Name</option>

          </select>

        </div>

        

        <button id="clearCheckinsBtn" class="hidden" onclick="showClearCheckinsModal()" style="width: auto; padding: 10px 20px; font-weight: bold; background-color: #dc3545; color: white;">Clear Check-ins</button>

        <button id="toggleViewBtn" class="hidden" onclick="toggleIdView()" style="width: auto; padding: 10px 20px; font-weight: bold; margin-right: 15px;"></button>

        <button id="finalizeBtn" class="finalize-btn hidden" onclick="showFinalizeModal()">🔒 Finalize Results</button>

      </div>

    </div>

    

    <div id="loadingRoster" class="loading hidden">Loading student roster...</div>

    

    <div class="dashboard-grid">

      <div class="left-panel">

        <table id="rosterTable" class="hidden">

          <thead>

            <tr id="tableHeaderRow"></tr>

          </thead>

          <tbody id="rosterBody"></tbody>

        </table>

      </div>

      <div class="right-panel" id="leaderboardContainer"></div>

    </div>

  </div>

</div>


<div id="customModal" class="modal-overlay">

  <div class="modal-box">

    <h3 id="modalTitle" style="color: #e65100;">Confirm Finalization</h3>

    <p id="modalMessage">Are you sure you want to finalize and lock the results?</p>

    <div class="modal-buttons" id="modalButtonsContainer"></div>

  </div>

</div>


<script>

  const API_URL = "https://script.google.com/macros/s/AKfycbzKjS3O_8oUHn1LIRD9i0fQ_5LUSJkv5P8BR_jvcsTeENmnlPtwXlcz9M_lQbfEb_sg/exec";

  

  let globalSettings = { config: {} };

  let localRosterData = []; 

  let idViewState = 'scoring'; 


  async function callBackend(action, data = {}) {

    try {

      const url = API_URL + "?action=" + action + "&data=" + encodeURIComponent(JSON.stringify(data));

      const response = await fetch(url, { method: 'GET', redirect: 'follow', headers: { "Content-Type": "text/plain;charset=utf-8" } });

      if (!response.ok) throw new Error('Network response was not ok');

      return await response.json();

    } catch (error) {

      console.error("Backend Error:", error);

      return { success: false, message: "Network connection error. Try again." };

    }

  }


  window.onload = async function() {

    const settings = await callBackend("getGlobalSettings");

    if(settings) globalSettings = { ...globalSettings, ...settings };

  };


  async function login() {

    const token = document.getElementById('tokenInput').value.trim();

    const errorEl = document.getElementById('loginError');

    const loginBtn = document.getElementById('loginBtn');

    errorEl.innerText = "";

    

    if(!token) { errorEl.innerText = "Token cannot be blank."; return; }


    loginBtn.innerText = "Loading...";

    loginBtn.disabled = true;


    const response = await callBackend("authenticateDirector", { token: token });

    

    if(response.success) {

      document.getElementById('loginSection').classList.add('hidden');

      document.getElementById('portalSection').classList.remove('hidden');

      

      document.getElementById('welcomeText').innerText = "Welcome, " + response.directorName;

      document.getElementById('assignmentText').innerText = "Event: " + response.eventAssignment;

      

      globalSettings.currentEvent = response.eventAssignment;

      globalSettings.config = response.config || { hasTiebreaker: true, hasSizeDivisions: true, hasGradeDivisions: false, hasTeamRankings: true, identifierType: "Name", scoringMethod: "Score" };

      

      if (response.status === "SCORING COMPLETE") {

        const finalizeBtn = document.getElementById('finalizeBtn');

        finalizeBtn.innerText = "🔒 Finalized";

        finalizeBtn.disabled = true;

        globalSettings.isLocked = true;

      } else {

        globalSettings.isLocked = false;

      }

      

      loadRoster(response.eventAssignment);

    } else {

      errorEl.innerText = response.message;

      loginBtn.innerText = "Access Score Sheet";

      loginBtn.disabled = false;

    }

  }


  async function loadRoster(eventName) {

    const loadingEl = document.getElementById('loadingRoster');

    const tableEl = document.getElementById('rosterTable');

    loadingEl.classList.remove('hidden');

    

    const roster = await callBackend("getEventRoster", { eventName: eventName });

    

    loadingEl.classList.add('hidden');

    tableEl.classList.remove('hidden');

    localRosterData = roster || []; 

    

    // FORCE state based on the config fetched from your sheet

    const config = globalSettings.config;

    const isPlacing = (String(config.scoringMethod || "").toLowerCase() === "place");

    const isContestIdMode = (String(config.identifierType || "").toLowerCase() .includes("id"));


    if (isPlacing && isContestIdMode) {

      idViewState = 'roster';

      // Force to Roster (Check-in) view first

      document.getElementById('toggleViewBtn').classList.remove('hidden');

      document.getElementById('sortSelect').value = "name";

      localRosterData.sort((a, b) => (a.lastName || "").localeCompare(b.lastName || ""));

    } else {

      idViewState = 'scoring';

      // Force to Scoring view

      document.getElementById('toggleViewBtn').classList.add('hidden');

      document.getElementById('clearCheckinsBtn').classList.add('hidden');

    }


    renderTableGrid();

  }


  function renderTableGrid() {

    const headerRow = document.getElementById('tableHeaderRow');

    const body = document.getElementById('rosterBody');

    body.innerHTML = "";

    headerRow.innerHTML = "";


    const config = globalSettings.config;

    const isPlacingEvent = (String(config.scoringMethod || "").toLowerCase() === "place");

    const isContestIdMode = (String(config.identifierType || "").toLowerCase() .includes("id"));

    const hasTiebreaker = config.hasTiebreaker;

    let scoreLabel = isPlacingEvent ? "Place" : "Score";


    // 1. UI STATE MANAGEMENT

    if (isPlacingEvent && isContestIdMode) {

      if (idViewState === 'roster') {

        document.getElementById('sortContainer').classList.remove('hidden');

        document.getElementById('leaderboardContainer').style.display = 'none'; 

        document.getElementById('finalizeBtn').classList.add('hidden'); 

        document.getElementById('clearCheckinsBtn').classList.remove('hidden'); 

        

        let btn = document.getElementById('toggleViewBtn');

        btn.innerText = " Go to Score Entry";

        btn.style.backgroundColor = "#1a73e8";

      } else if (idViewState === 'scoring') {

        document.getElementById('sortContainer').classList.add('hidden'); 

        document.getElementById('leaderboardContainer').style.display = 'block'; 

        document.getElementById('clearCheckinsBtn').classList.add('hidden');

        document.getElementById('finalizeBtn').classList.remove('hidden');

        

        let btn = document.getElementById('toggleViewBtn');

        btn.innerText = " Back to ID Roster";

        btn.style.backgroundColor = "#5f6368";


        localRosterData.sort((a, b) => {

          let idA = (a.contestId || a.uniqueId || "").toString();

          let idB = (b.contestId || b.uniqueId || "").toString();

          return idA.localeCompare(idB);

        });

      }

    } else {

      document.getElementById('sortContainer').classList.remove('hidden');

      document.getElementById('leaderboardContainer').style.display = 'block';

      document.getElementById('finalizeBtn').classList.remove('hidden');

      document.getElementById('clearCheckinsBtn').classList.add('hidden');

    }


    // 2. BUILD HEADERS

    let headerHTML = ""; 


    if (isPlacingEvent && isContestIdMode) {

      if (idViewState === 'roster') {

        headerHTML = `<th class="text-center" style="width: 80px;">Checked In</th><th>Student Name</th><th>School</th><th class="text-center">Contest ID</th>`;

      } else {

        headerHTML = `<th class="text-center">Contest ID</th><th class='text-center'>${scoreLabel}</th>`;

      }

    } else {

      let identifierHeader = isContestIdMode ? "Contest ID" : "Student Name";

      headerHTML = `<th>${identifierHeader}</th><th>School</th><th class='text-center'>${scoreLabel}</th>`;

      if (hasTiebreaker && !isPlacingEvent) headerHTML += `<th class='text-center'>Tiebreaker</th>`;

    }

    headerRow.innerHTML = headerHTML;


    let disabledAttribute = globalSettings.isLocked ? "disabled" : "";


    // 3. BUILD ROWS

    localRosterData.forEach(function(student) {

      const row = document.createElement('tr');

      let lookupId = "";

      let leftPanelHTML = "";


      if (isPlacingEvent && isContestIdMode) {

        if (idViewState === 'roster') {

          lookupId = student.uniqueId;

          let displayId = student.contestId || student.uniqueId; 

          let isChecked = student.checkedIn ? "checked" : "";

          

          if (student.checkedIn) row.classList.add("checked-in-row");


          leftPanelHTML = `

            <td class="text-center">

              <input type="checkbox" class="check-box-input" data-check-id="${lookupId}" onchange="toggleCheckIn('${lookupId}', this.checked)" ${isChecked}>

            </td>

            <td>${student.lastName}, ${student.firstName}</td>

            <td>${student.school}</td>

            <td class="text-center" style="font-size: 16px; color: #1a73e8;"><strong>${displayId}</strong></td>

          `;

        } else {

          lookupId = student.uniqueId;

          let displayId = student.contestId || student.uniqueId; 

          leftPanelHTML = `

            <td class="text-center"><strong>${displayId}</strong></td>

            <td class="text-center">

              <input type="number" class="score-input main-score" data-id="${lookupId}" data-type="score" value="${student.score !== undefined ? student.score : ''}" oninput="updateLocalData('${lookupId}', 'score', this.value)" ${disabledAttribute}>

            </td>

          `;

        }

      } else {

        // Standard Events & Name/Place Events

        let identifierCell = "";

        if (isContestIdMode) {

          identifierCell = `<td>${student.uniqueId}</td>`;

          lookupId = student.uniqueId;

        } else {

          identifierCell = `<td>${student.lastName}, ${student.firstName}</td>`;

          lookupId = `${student.lastName}, ${student.firstName}`;

        }

        

        let tiebreakerCell = (hasTiebreaker && !isPlacingEvent) ?

          `

          <td class="text-center">

            <input type="number" class="score-input tie-score" data-id="${lookupId}" data-type="tiebreaker" value="${student.tiebreaker}" oninput="updateLocalData('${lookupId}', 'tiebreaker', this.value)" ${disabledAttribute}>

          </td>` : "";


        leftPanelHTML = `

          ${identifierCell}

          <td>${student.school}</td>

          <td class="text-center">

            <input type="number" class="score-input main-score" data-id="${lookupId}" data-type="score" value="${student.score !== undefined ? student.score : ''}" oninput="updateLocalData('${lookupId}', 'score', this.value)" ${disabledAttribute}>

          </td>

          ${tiebreakerCell}

        `;

      }

      

      row.innerHTML = leftPanelHTML;

      body.appendChild(row);

    });


    if (globalSettings.isLocked) document.getElementById('sortSelect').disabled = true;


    calculateLiveStandings(); 

  }


  function toggleIdView() {

    if (idViewState === 'roster') {

      idViewState = 'scoring';

      renderTableGrid(); 

    } else {

      idViewState = 'roster';

      applySort(); 

    }

  }


  async function toggleCheckIn(lookupId, isChecked) {

    let match = localRosterData.find(s => (s.lastName + ", " + s.firstName) === lookupId || s.uniqueId === lookupId);

    if (match) match.checkedIn = isChecked;

    

    const checkbox = document.querySelector(`input[data-check-id="${lookupId}"]`);

    if (checkbox) {

      const tr = checkbox.closest('tr');

      if (isChecked) tr.classList.add('checked-in-row');

      else tr.classList.remove('checked-in-row');

    }


    await callBackend("saveLiveScore", {

      uniqueId: lookupId,

      inputType: "checkin",

      value: isChecked,

      eventName: globalSettings.currentEvent

    });

  }


  function showClearCheckinsModal() {

    document.getElementById('modalTitle').innerText = "Clear All Check-ins?";

    document.getElementById('modalTitle').style.color = "#dc3545"; 

    document.getElementById('modalMessage').innerText = "Are you sure you want to completely clear all check-ins for this event? This action cannot be undone.";

    document.getElementById('modalButtonsContainer').innerHTML = `

      <button class="modal-btn btn-cancel" onclick="closeModal()">Cancel</button>

      <button class="modal-btn btn-confirm" style="background-color: #dc3545;" onclick="executeClearCheckins()">Yes, Clear All</button>

    `;

    document.getElementById('customModal').classList.add('active');

  }


  async function executeClearCheckins() {

    closeModal();

    const btn = document.getElementById('clearCheckinsBtn');

    btn.innerText = "Clearing...";

    btn.disabled = true;


    const response = await callBackend("clearAllCheckins", { eventName: globalSettings.currentEvent });

    

    if (response.success) {

      localRosterData.forEach(student => student.checkedIn = false);

      renderTableGrid(); 

    } else {

      alert("Error clearing check-ins: " + response.message);

    }

    btn.innerText = "Clear Check-ins";

    btn.disabled = false;

  }


  function applySort() {

    const config = globalSettings.config;

    const isPlacingEvent = (String(config.scoringMethod || "").toLowerCase() === "place");

    

    if (isPlacingEvent && idViewState === 'scoring') return; 


    const sortType = document.getElementById('sortSelect').value;

    if (sortType === 'name') {

      localRosterData.sort((a, b) => (a.lastName || "").localeCompare(b.lastName || ""));

    } else if (sortType === 'school') {

      localRosterData.sort((a, b) => {

        let schoolCompare = (a.school || "").localeCompare(b.school || "");

        if (schoolCompare !== 0) return schoolCompare;

        return (a.lastName || "").localeCompare(b.lastName || ""); 

      });

    }

    renderTableGrid();

  }


  function updateLocalData(lookupId, type, val) {

    let match = localRosterData.find(s => (s.lastName + ", " + s.firstName) === lookupId || s.uniqueId === lookupId);

    if (match) match[type] = val !== "" ? Number(val) : "";

    calculateLiveStandings();

  }


  function calculateLiveStandings() {

    const container = document.getElementById('leaderboardContainer');

    container.innerHTML = ""; 


    const config = globalSettings.config;

    const isPlacingEvent = (String(config.scoringMethod || "").toLowerCase() === "place");

    const isContestIdMode = (String(config.identifierType || "").toLowerCase() .includes("id"));

    

    const hasTiebreaker = config.hasTiebreaker;

    const hasGradeDivisions = config.hasGradeDivisions;

    const hasSizeDivisions = config.hasSizeDivisions !== undefined ? config.hasSizeDivisions : true;

    const hasTeamRankings = config.hasTeamRankings;


    let divGroups = {};

    let divCounts = {};

    

    localRosterData.forEach(s => {

      if (s.score !== "" && !isNaN(s.score)) {

        let d = s.division || "Overall";

        if (!divGroups[d]) divGroups[d] = [];

        divGroups[d].push(s);

      }

    });

    

    for (let d in divGroups) {

      divGroups[d].sort((a, b) => isPlacingEvent ? a.score - b.score : b.score - a.score);

      divCounts[d] = {};

      divGroups[d].forEach(s => {

        divCounts[d][s.score] = (divCounts[d][s.score] || 0) + 1;

      });

    }


    // Tiebreaker Warning Logic

    document.querySelectorAll('.tie-score').forEach(input => {

      if (!hasTiebreaker || isPlacingEvent) {

        input.classList.remove('tie-warning');

        input.placeholder = "";

        return;

      }

      

      const id = input.getAttribute('data-id');

      let student = localRosterData.find(s => (s.lastName + ", " + s.firstName) === id || s.uniqueId === id);


      if (student && student.score !== "") {

        let d = student.division || "Overall";

        let pool = divGroups[d] || [];

        let counts = divCounts[d] || {};

        let rIdx = pool.findIndex(s => s.score === student.score);

        

        if (counts[student.score] > 1 && rIdx < 6 && (student.tiebreaker === "" || student.tiebreaker === null)) {

          input.classList.add('tie-warning');

          input.placeholder = "Tie! *";

        } else {

          input.classList.remove('tie-warning');

          input.placeholder = "";

        }

      } else {

        input.classList.remove('tie-warning');

        input.placeholder = "";

      }

    });


    let masterSequence = [];

    if (hasSizeDivisions) {

       if (hasGradeDivisions) {

         masterSequence = [

           { type: "individual", key: "Large School", subKeys: ["upper", "(11-12)", "11-12"], label: "Large School Upper Individual Top 10" },

           { type: "individual", key: "Large School", subKeys: ["lower", "(9-10)", "9-10"], label: "Large School Lower Individual Top 10" },

           { type: "team", key: "Large School", label: "Large School Overall Team Standings" },

           { type: "individual", key: "Small School", subKeys: ["upper", "(11-12)", "11-12"], label: "Small School Upper Individual Top 10" },

           { type: "individual", key: "Small School", subKeys: ["lower", "(9-10)", "9-10"], label: "Small School Lower Individual Top 10" },

           { type: "team", key: "Small School", label: "Small School Overall Team Standings" }

         ];

       } else {

         masterSequence = [

           { type: "individual", key: "Large School", label: "Large School Individual Top 10" },

           { type: "team", key: "Large School", label: "Large School Overall Team Standings" },

           { type: "individual", key: "Small School", label: "Small School Individual Top 10" },

           { type: "team", key: "Small School", label: "Small School Overall Team Standings" }

         ];

       }

    } else {

       if (hasGradeDivisions) {

         masterSequence = [

           { type: "individual", key: "", subKeys: ["upper", "(11-12)", "11-12"], label: "Upper Individual Top 10" },

           { type: "individual", key: "", subKeys: ["lower", "(9-10)", "9-10"], label: "Lower Individual Top 10" },

           { type: "team", key: "", label: "Overall Team Standings" }

         ];

       } else {

         masterSequence = [

           { type: "individual", key: "", label: "Overall Individual Top 10" },

           { type: "team", key: "", label: "Overall Team Standings" }

         ];

       }

    }


    masterSequence.forEach(section => {

      if (section.type === "team" && !hasTeamRankings) return;


      if (section.type === "individual") {

          let pool = localRosterData.filter(s => {

              if (s.score === "" || isNaN(s.score)) return false;

              let div = (s.division || "").toLowerCase();

              if (section.key !== "" && !div.includes(section.key.toLowerCase())) return false;

              if (section.subKeys) {

                  return section.subKeys.some(sub => div.includes(sub));

              }

              return true;

          });  

        

        pool.sort((a, b) => {

          if (isPlacingEvent) {

             return a.score - b.score; 

          } else {

             if (b.score !== a.score) return b.score - a.score;

             return (b.tiebreaker || 0) - (a.tiebreaker || 0);

          }

        });


        const card = document.createElement('div');

        card.className = "leaderboard-card";

        

        let labelText = section.label;

        if (isPlacingEvent) labelText = labelText.replace("Top 10", "Top 6");

        card.innerHTML = `<h4>${labelText}</h4>`;

        

        if (pool.length === 0) {

          card.innerHTML += `<p style="color: #999; font-size: 13px; margin: 5px 0 0 0; text-align: center;">Waiting for individual ${isPlacingEvent ? 'places' : 'scores'}...</p>`;

        } else {

          let tableHTML = `<table class="leaderboard-table">

                    <thead>

                      <tr><th class="rank-col">Rank</th><th>Student Name</th><th>School</th><th class="text-center">${isPlacingEvent ? 'Place' : 'Score'}</th></tr>

                    </thead>

                    <tbody>`;

          

          let currentRank = 1;

          let displayedCount = 0;

          let displayLimit = isPlacingEvent ? 6 : 10;

          

          for (let k = 0; k < pool.length; k++) {

            if (displayedCount >= displayLimit) break; 

            

            let s = pool[k];

            if (k > 0 && s.score !== pool[k - 1].score) currentRank = k + 1;

            

            // Standings ALWAYS show the Name and School, even for Contest ID placing events

            let displayName = `${s.lastName || "Unknown"}, ${s.firstName || ""}`;

            let tiebreakerString = (!isPlacingEvent && s.tiebreaker !== "" && s.tiebreaker !== 0 && s.tiebreaker !== null && !isNaN(s.tiebreaker)) 

              ? ` <span style="font-size:11px; color:#888;">(${s.tiebreaker})</span>` : "";


            tableHTML += `<tr>

                      <td class="rank-col">#${currentRank}</td>

                      <td>${displayName}</td>

                      <td>${s.school || "—"}</td>

                      <td class="text-center"><strong>${s.score}</strong>${tiebreakerString}</td>

                    </tr>`;

            displayedCount++;

          }

          tableHTML += `</tbody></table>`;

          card.innerHTML += tableHTML;

        }

        container.appendChild(card);


      } else if (section.type === "team") {

        let sizeTierStudents = localRosterData.filter(s => {

             if (s.score === "" || isNaN(s.score)) return false;

             let div = (s.division || "").toLowerCase();

             if (section.key !== "" && !div.includes(section.key.toLowerCase())) return false;

             return true;

        });

        

        let schoolTeams = {};

        

        sizeTierStudents.forEach(s => {

          if (!s.school) return;

          if (!schoolTeams[s.school]) schoolTeams[s.school] = [];

          schoolTeams[s.school].push(s.score);

        });


        let teamPool = [];

        for (let schoolName in schoolTeams) {

          let scores = schoolTeams[schoolName];

          scores.sort((a, b) => b - a);

          let top3 = scores.slice(0, 3);

          let teamTotal = top3.reduce((sum, score) => sum + score, 0);

          teamPool.push({ school: schoolName, totalScore: teamTotal, studentCount: scores.length });

        }

        teamPool.sort((a, b) => b.totalScore - a.totalScore);


        const card = document.createElement('div');

        card.className = "leaderboard-card";

        card.innerHTML = `<h4>${section.label}</h4>`;

        

        if (teamPool.length === 0) {

          card.innerHTML += `<p style="color: #999; font-size: 13px; margin: 5px 0 0 0; text-align: center;">Waiting for team calculations...</p>`;

        } else {

          let tableHTML = `<table class="leaderboard-table">

                    <thead>

                      <tr><th class="rank-col">Rank</th><th>School Name</th><th class="text-center">Count</th><th class="text-center">Team Total</th></tr>

                    </thead>

                    <tbody>`;

          let teamLimit = Math.min(teamPool.length, 5);

          for (let t = 0; t < teamLimit; t++) {

            let team = teamPool[t];

            tableHTML += `<tr>

                      <td class="rank-col">#${t + 1}</td>

                      <td>${team.school}</td>

                      <td class="text-center" style="color: #666;">${team.studentCount}</td>

                      <td class="text-center"><strong>${team.totalScore}</strong></td>

                    </tr>`;

          }

          tableHTML += `</tbody></table>`;

          card.innerHTML += tableHTML;

        }

        container.appendChild(card);

      }

    });

  }


  function showFinalizeModal() {

    const config = globalSettings.config;

    const isPlacingEvent = (String(config.scoringMethod || "").toLowerCase() === "place");


    const outstandingTies = document.querySelectorAll('.tie-warning');

    if (outstandingTies.length > 0 && config.hasTiebreaker && !isPlacingEvent) {

      document.getElementById('modalTitle').innerText = "⚠️ Unresolved Ties Detected";

      document.getElementById('modalTitle').style.color = "#dc3545";

      document.getElementById('modalMessage').innerText = "You have missing tiebreaker scores highlighted in red inside the top 6 positions. Please resolve them on your entry sheet before finalizing.";

      document.getElementById('modalButtonsContainer').innerHTML = `<button class="modal-btn btn-cancel" onclick="closeModal()">Go Back</button>`;

    } else {

      document.getElementById('modalTitle').innerText = "Lock & Finalize Results?";

      document.getElementById('modalTitle').style.color = "#e65100";

      document.getElementById('modalMessage').innerText = "Are you sure you want to finalize and lock the results? This will submit your standings to the tab room and disable further score editing.";

      document.getElementById('modalButtonsContainer').innerHTML = `

        <button class="modal-btn btn-cancel" onclick="closeModal()">Cancel</button>

        <button class="modal-btn btn-confirm" style="background-color: #e65100;" onclick="executeFinalize()">Yes, Finalize</button>

      `;

    }

    document.getElementById('customModal').classList.add('active');

  }


  function closeModal() {

    document.getElementById('customModal').classList.remove('active');

  }


  async function executeFinalize() {

    closeModal();

    const finalizeBtn = document.getElementById('finalizeBtn');

    finalizeBtn.innerText = "Submitting...";

    finalizeBtn.disabled = true;


    const status = await callBackend("lockAndFinalizeEvent", { eventName: globalSettings.currentEvent });


    if (status.success) {

      finalizeBtn.innerText = "🔒 Finalized";

      document.querySelectorAll('.score-input').forEach(input => input.disabled = true);

      document.getElementById('sortSelect').disabled = true;

      

      document.getElementById('modalTitle').innerText = "🎉 Results Submitted!";

      document.getElementById('modalTitle').style.color = "#1a73e8";

      document.getElementById('modalMessage').innerText = "Success! You have submitted your scores to the Contest Coordinator to publish. You're all set!";

      document.getElementById('modalButtonsContainer').innerHTML = `<button class="modal-btn btn-success" onclick="closeModal()">Got It</button>`;

      document.getElementById('customModal').classList.add('active');

    } else {

      finalizeBtn.innerText = "🔒 Finalize Results";

      finalizeBtn.disabled = false;

      alert("Submission Error: " + status.message);

    }

  }


  document.getElementById('rosterBody').addEventListener('change', async function(e) {

    if (e.target.classList.contains('main-score') || e.target.classList.contains('tie-score')) {

      const uniqueId = e.target.getAttribute('data-id');

      const inputType = e.target.getAttribute('data-type'); 

      const value = e.target.value;

      

      // --- NEW MIN/MAX VALIDATION LOGIC ---

      if (inputType === "score" && value !== "") {

        const numVal = Number(value);

        const min = globalSettings.config.minScore;

        const max = globalSettings.config.maxScore;

        

        // Check if min/max exist in the config, and if the value breaks the rules

        if ((min !== "" && numVal < min) || (max !== "" && numVal > max)) {

          // Trigger the friendly custom modal

          document.getElementById('modalTitle').innerText = "⚠️ Out of Range";

          document.getElementById('modalTitle').style.color = "#dc3545"; // Red color

          document.getElementById('modalMessage').innerText = `The score entered (${numVal}) is outside the allowed range of ${min} to ${max} for this event. Please enter a valid score.`;

          document.getElementById('modalButtonsContainer').innerHTML = `<button class="modal-btn btn-cancel" onclick="closeModal()">Got It</button>`;

          document.getElementById('customModal').classList.add('active');

          

          // Clear the bad input and flash the box red

          e.target.value = ""; 

          e.target.style.backgroundColor = '#f8d7da'; 

          setTimeout(() => { e.target.style.backgroundColor = 'white'; }, 1000);

          

          return; // Stop the function here so the bad score NEVER reaches the spreadsheet

        }

      }

      // --- END VALIDATION LOGIC ---

      

      e.target.style.backgroundColor = '#fff3cd';


      const status = await callBackend("saveLiveScore", {

        uniqueId: uniqueId,

        inputType: inputType,

        value: value,

        eventName: globalSettings.currentEvent

      });


      if(status.success) {

        e.target.style.backgroundColor = '#d4edda';

        setTimeout(() => { e.target.style.backgroundColor = 'white'; }, 1000);

      } else {

        e.target.style.backgroundColor = '#f8d7da';

        alert("Error saving: " + status.message);

      }

    }

  });


  // --- ENTER KEY NAVIGATION (Jumps to next row) ---

  document.addEventListener('keydown', function(e) {

    if (e.key === 'Enter' && e.target.classList.contains('score-input')) {

      e.preventDefault(); 

      

      // Determine if they are in the Main Score column or Tiebreaker column

      const selector = e.target.classList.contains('main-score') ? '.main-score' : '.tie-score';

      

      // Get all active inputs in that specific column

      const inputs = Array.from(document.querySelectorAll(selector)).filter(input => !input.disabled);

      const currentIndex = inputs.indexOf(e.target);

      

      // If there is a next row, move focus down and select the text for easy overwriting

      if (currentIndex > -1 && currentIndex < inputs.length - 1) {

        inputs[currentIndex + 1].focus();

        inputs[currentIndex + 1].select();

      }

    }

  });


  // --- ENTER KEY LOGIN ---

  document.getElementById('tokenInput').addEventListener('keydown', function(e) {

    if (e.key === 'Enter') {

      e.preventDefault();

      login();

    }

  });

</script>


</body>

</html>