(() => {
  "use strict";

  const boot = window.UI_BUILDER_BOOT || {};
  if (boot.mode !== "runtime") return;

  const state = {
    root: null,
    signature: "",
    timerId: "hockey_game_timer",
    dashboardId: "hockey_penalty_dashboard",
    interval: null,
    resizeObserver: null,
    control: null,
    controlGameId: "",
    controlLoading: false,
    controlFetchedAt: 0,
    periodEditing: false,
  };

  const escapeHtml = (value) => String(value ?? "")
    .replaceAll("&", "&amp;")
    .replaceAll("<", "&lt;")
    .replaceAll(">", "&gt;")
    .replaceAll('"', "&quot;")
    .replaceAll("'", "&#039;");

  function formatDate(value, language) {
    const raw = String(value || "").trim();
    if (!raw) return "Дата не указана";
    const parsed = new Date(`${raw}T12:00:00`);
    if (Number.isNaN(parsed.getTime())) return raw;
    return parsed.toLocaleDateString(language === "en" ? "en-GB" : "ru-RU", {
      day: "2-digit",
      month: "short",
      year: "numeric",
    });
  }

  function formatPenaltyTime(milliseconds) {
    const totalSeconds = Math.max(0, Math.ceil(Number(milliseconds || 0) / 1000));
    const minutes = Math.floor(totalSeconds / 60);
    const seconds = totalSeconds % 60;
    return `${minutes}:${String(seconds).padStart(2, "0")}`;
  }

  function discoverActionIds() {
    const components = window.UIBuilderRuntime?.getConfig?.()?.components || [];
    const timer = components.find((item) => item.action_id === "hockey_game_timer")
      || components.find((item) => item.type === "timer");
    const dashboard = components.find((item) => item.type === "hockey_penalty_dashboard");
    state.timerId = timer?.action_id || "hockey_game_timer";
    state.dashboardId = dashboard?.action_id || "hockey_penalty_dashboard";
  }

  function snapshot() {
    const data = window.UIBuilderRuntime?.getData?.() || {};
    const game = data.hockey?.selected_game || null;
    const tournament = data.hockey?.selected_tournament || null;
    const language = data.hockey?.language?.display
      || localStorage.getItem("hockey.language")
      || "ru";
    const timer = window.UIBuilderRuntime?.getTimer?.(state.timerId) || null;
    const board = window.UIBuilderRuntime?.getHockeyPenaltyBoard?.(state.dashboardId) || {};
    const penalties = (Array.isArray(board.penalties) ? board.penalties : [])
      .filter((event) => (
        event
        && !event.finished
        && (event.player || (event.teamPenalty && ["home", "away"].includes(event.side)))
        && event.infraction
        && event.preset
      ))
      .sort((left, right) => {
        const sideOrder = { home: 0, away: 1 };
        return (sideOrder[left.player?.side || left.side] ?? 2)
          - (sideOrder[right.player?.side || right.side] ?? 2)
          || Number(left.createdAt || 0) - Number(right.createdAt || 0);
      });
    return { data, game, tournament, language, timer, penalties, control: state.control };
  }

  async function controlRequest(path, options = {}) {
    const response = await fetch(`/api/hockey${path}`, {
      cache: "no-store",
      credentials: "same-origin",
      ...options,
      headers: {
        ...(options.body ? { "Content-Type": "application/json" } : {}),
        ...(options.headers || {}),
      },
    });
    let payload = {};
    try { payload = await response.json(); } catch (_) {}
    if (!response.ok) {
      const detail = typeof payload.detail === "string" ? payload.detail : `HTTP ${response.status}`;
      throw new Error(detail);
    }
    return payload;
  }

  async function loadControl(force = false) {
    const data = window.UIBuilderRuntime?.getData?.() || {};
    const gameId = String(data.hockey?.selected_game?.external_id || data.hockey?.selected_game?.id || "").trim();
    const language = data.hockey?.language?.display === "en" ? "en" : "ru";
    if (!gameId) {
      state.control = null;
      state.controlGameId = "";
      return;
    }
    if (state.controlGameId !== gameId) {
      state.control = null;
      state.controlGameId = gameId;
      force = true;
    }
    if (state.controlLoading) return;
    if (!force && Date.now() - state.controlFetchedAt < 1800) return;
    state.controlLoading = true;
    try {
      const previousPeriod = String(state.control?.current_period || "");
      state.control = await controlRequest(`/games/${encodeURIComponent(gameId)}/control?language=${language}`);
      state.controlFetchedAt = Date.now();
      const nextPeriod = String(state.control?.current_period || "");
      if (previousPeriod && nextPeriod && previousPeriod !== nextPeriod) {
        window.UIBuilderRuntime?.patchData?.({ hockey: { game_control: state.control } });
        window.dispatchEvent(new CustomEvent("hockey:game-control-updated", {
          detail: { game_id: gameId, control: state.control, apply_timers: true },
        }));
      }
      render(true);
    } catch (error) {
      console.error("Could not load hockey period state", error);
    } finally {
      state.controlLoading = false;
    }
  }

  async function updatePeriod(gameId, value, language) {
    try {
      state.control = await controlRequest(`/games/${encodeURIComponent(gameId)}/control/period`, {
        method: "PUT",
        body: JSON.stringify({ current_period: value, language }),
      });
      state.controlFetchedAt = Date.now();
      window.UIBuilderRuntime?.patchData?.({ hockey: { game_control: state.control } });
      window.dispatchEvent(new CustomEvent("hockey:game-control-updated", {
        detail: { game_id: gameId, control: state.control, apply_timers: true },
      }));
      render(true);
    } catch (error) {
      console.error("Could not update hockey period", error);
      window.alert(error.message || "Не удалось изменить период");
      await loadControl(true);
    }
  }

  function timerStatus(timer, language) {
    if (!timer) return language === "en" ? "not configured" : "не настроен";
    if (timer.finished) return language === "en" ? "finished" : "завершён";
    if (timer.running) return language === "en" ? "running" : "идёт";
    if (timer.paused) return language === "en" ? "paused" : "пауза";
    return language === "en" ? "stopped" : "остановлен";
  }

  function penaltyMarkup(event, language, teamNames = {}) {
    const side = event.player?.side || event.side || "neutral";
    const teamPenalty = Boolean(event.teamPenalty);
    const number = String(event.player?.number || "").replace(/^#/, "");
    const playerName = teamPenalty
      ? (teamNames[side] || (language === "en" ? "Team penalty" : "Командное удаление"))
      : (event.player?.name || (language === "en" ? "Player" : "Игрок"));
    const infraction = event.infraction?.label
      || event.infraction?.name
      || event.infraction?.id
      || "";
    const accessibleLabel = [playerName, infraction, formatPenaltyTime(event.remainingMs)]
      .filter(Boolean)
      .join(" · ");
    return `
      <article class="hockey-status-penalty side-${escapeHtml(side)} ${teamPenalty ? "is-team-penalty" : ""} ${event.running ? "is-running" : "is-paused"}" aria-label="${escapeHtml(accessibleLabel)}" title="${escapeHtml(accessibleLabel)}">
        <span class="hockey-status-penalty-side" aria-hidden="true"></span>
        <strong>${teamPenalty ? (language === "en" ? "TEAM" : "КОМ") : number ? `#${escapeHtml(number)}` : "—"}</strong>
        <time>${escapeHtml(formatPenaltyTime(event.remainingMs))}</time>
      </article>
    `;
  }

  function render(force = false) {
    if (!state.root || !window.UIBuilderRuntime) return;
    // The header refreshes frequently because the timer changes. Replacing the
    // <select> while its native popup is open closes the popup in Chromium.
    // Freeze this header only for the duration of period selection.
    const periodSelect = state.root.querySelector("[data-hockey-current-period]");
    if (state.periodEditing || periodSelect === document.activeElement) return;
    const value = snapshot();
    const game = value.game;
    const language = value.language === "en" ? "en" : "ru";
    const home = game?.home || {};
    const away = game?.away || {};
    const homeName = home.name || (language === "en" ? "Home team" : "Хозяева");
    const awayName = away.name || (language === "en" ? "Away team" : "Гости");
    const scoreHome = Number.isFinite(Number(home.score)) ? Number(home.score) : 0;
    const scoreAway = Number.isFinite(Number(away.score)) ? Number(away.score) : 0;
    const clock = value.timer?.formatted || "—:—";
    const dateText = formatDate(game?.date, language);
    const startTime = String(game?.time || "").trim();
    const league = value.tournament?.league || value.tournament?.name || "";
    const finishLabel = String(game?.score?.finish_label || "").trim()
      || (String(game?.score?.finish_type || "").toUpperCase() === "SO" ? (language === "en" ? "SO" : "Б")
        : String(game?.score?.finish_type || "").toUpperCase() === "OT" ? (language === "en" ? "OT" : "ОТ") : "");
    const stageKey = String(value.tournament?.stage_key || "").toLowerCase();
    const fallbackPeriodOptions = [
      { value: "1", label: language === "en" ? "1st period" : "1 период" },
      { value: "2", label: language === "en" ? "2nd period" : "2 период" },
      { value: "3", label: language === "en" ? "3rd period" : "3 период" },
      ...(stageKey === "playoff"
        ? [
            { value: "ot1", label: language === "en" ? "Overtime 1" : "1 овертайм" },
            { value: "ot2", label: language === "en" ? "Overtime 2" : "2 овертайм" },
          ]
        : [
            { value: "ot", label: language === "en" ? "Overtime" : "Овертайм" },
            ...(stageKey === "regular"
              ? [{ value: "so", label: language === "en" ? "Shootout" : "Буллиты" }]
              : []),
          ]),
      { value: "finished", label: language === "en" ? "Finished" : "Матч завершён" },
    ];
    const periodOptions = Array.isArray(value.control?.period_options)
      ? value.control.period_options
      : fallbackPeriodOptions;
    const currentPeriod = String(value.control?.current_period || "1");
    const strength = value.control?.strength || {};
    const strengthLabel = String(strength.strength_label || "");
    const strengthAdvantage = String(strength.advantage_side || "");
    const strengthHomeLabel = String(strength.home_label || "");
    const strengthAwayLabel = String(strength.away_label || "");
    const strengthStateLabel = String(strength.state_label || "");
    const signature = JSON.stringify({
      game: game?.external_id || "",
      homeName,
      awayName,
      scoreHome,
      scoreAway,
      dateText,
      startTime,
      league,
      finishLabel,
      currentPeriod,
      strengthLabel,
      strengthAdvantage,
      strengthHomeLabel,
      strengthAwayLabel,
      strengthStateLabel,
      clock,
      timerRunning: Boolean(value.timer?.running),
      timerPaused: Boolean(value.timer?.paused),
      penalties: value.penalties.map((event) => [
        event.id,
        event.player?.name,
        event.player?.number,
        event.player?.side || event.side,
        event.teamPenalty,
        event.infraction?.label,
        event.running,
        formatPenaltyTime(event.remainingMs),
      ]),
      language,
    });
    if (!force && signature === state.signature) return;
    state.signature = signature;

    const penalties = value.penalties.length
      ? value.penalties.map((event) => penaltyMarkup(event, language, { home: homeName, away: awayName })).join("")
      : `<div class="hockey-status-no-penalties">${language === "en" ? "No active penalties" : "Нет активных удалений"}</div>`;
    const advantageTeam = strengthAdvantage === "home" ? homeName : strengthAdvantage === "away" ? awayName : "";
    const advantageText = strengthAdvantage === "home" ? strengthHomeLabel : strengthAdvantage === "away" ? strengthAwayLabel : strengthStateLabel;
    const strengthMarkup = game && strengthLabel ? `
      <article class="hockey-status-strength ${strengthAdvantage ? `side-${escapeHtml(strengthAdvantage)}` : "is-even"}">
        <span>${language === "en" ? "STRENGTH" : "СОСТАВЫ"}</span>
        <strong>${escapeHtml(strengthLabel)}</strong>
        <small>${escapeHtml(advantageText ? `${advantageText}${advantageTeam ? ` · ${advantageTeam}` : ""}` : (language === "en" ? "EVEN" : "РАВНЫЕ"))}</small>
      </article>` : "";

    state.root.classList.toggle("has-game", Boolean(game));
    state.root.innerHTML = `
      <div class="hockey-status-match">
        <div class="hockey-status-team is-home">
          <span>${language === "en" ? "HOME" : "ХОЗЯЕВА"}</span>
          <strong>${escapeHtml(homeName)}</strong>
        </div>
        <div class="hockey-status-score" title="${game ? "" : (language === "en" ? "Select a game" : "Выберите матч")}">
          <strong>${game ? `${scoreHome} : ${scoreAway}` : "— : —"}</strong>
          ${finishLabel ? `<small>${escapeHtml(finishLabel)}</small>` : ""}
        </div>
        <div class="hockey-status-team is-away">
          <span>${language === "en" ? "AWAY" : "ГОСТИ"}</span>
          <strong>${escapeHtml(awayName)}</strong>
        </div>
      </div>
      <div class="hockey-status-meta">
        ${league ? `<span>${escapeHtml(league)}</span>` : ""}
        <strong>${escapeHtml(dateText)}</strong>
        <time>${escapeHtml(startTime || (language === "en" ? "time not set" : "время не указано"))}</time>
      </div>
      <label class="hockey-status-period">
        <span>${language === "en" ? "CURRENT PERIOD" : "ТЕКУЩИЙ ПЕРИОД"}</span>
        <select data-hockey-current-period ${game ? "" : "disabled"}>${periodOptions.map((item) => `<option value="${escapeHtml(item.value)}" ${String(item.value) === currentPeriod ? "selected" : ""}>${escapeHtml(item.label)}</option>`).join("")}</select>
      </label>
      <div class="hockey-status-clock ${value.timer?.running ? "is-running" : "is-paused"}">
        <span>${language === "en" ? "MAIN TIMER" : "ОСНОВНОЙ ТАЙМЕР"}</span>
        <strong>${escapeHtml(clock)}</strong>
        <small>${escapeHtml(timerStatus(value.timer, language))}</small>
      </div>
      <div class="hockey-status-penalties" aria-label="${language === "en" ? "Active penalties" : "Активные удаления"}">
        ${strengthMarkup}
        ${penalties}
      </div>
    `;
    const currentPeriodSelect = state.root.querySelector("[data-hockey-current-period]");
    currentPeriodSelect?.addEventListener("pointerdown", () => { state.periodEditing = true; });
    currentPeriodSelect?.addEventListener("focus", () => { state.periodEditing = true; });
    currentPeriodSelect?.addEventListener("change", (event) => {
      if (!game?.external_id) return;
      updatePeriod(String(game.external_id), event.target.value, language);
    });
    currentPeriodSelect?.addEventListener("blur", () => {
      state.periodEditing = false;
      window.setTimeout(() => render(true), 0);
    });
  }

  function mount() {
    if (state.root) return;
    const topbar = document.querySelector(".runtime-topbar");
    if (!topbar) return;
    const root = document.createElement("section");
    root.id = "hockeyMatchStatusHeader";
    root.className = "hockey-match-status";
    root.setAttribute("aria-label", "Краткое состояние матча");
    root.tabIndex = 0;
    root.title = "Нажмите, чтобы выбрать турнир или матч";
    root.addEventListener("click", (event) => {
      if (!event.target.closest(".hockey-status-match")) return;
      document.querySelector(".runtime-actions .hockey-selected-chip")?.click();
    });
    root.addEventListener("keydown", (event) => {
      if (event.key !== "Enter" && event.key !== " ") return;
      event.preventDefault();
      document.querySelector(".runtime-actions .hockey-selected-chip")?.click();
    });
    topbar.appendChild(root);
    state.root = root;
    discoverActionIds();
    render(true);
    if (typeof ResizeObserver === "function") {
      state.resizeObserver = new ResizeObserver(() => {
        window.UIBuilderRuntime?.refreshLayout?.();
      });
      state.resizeObserver.observe(topbar);
    }
    requestAnimationFrame(() => window.UIBuilderRuntime?.refreshLayout?.());
    state.interval = window.setInterval(() => {
      if (!document.hidden) {
        render();
        loadControl(false);
      }
    }, 250);
  }

  window.addEventListener("hockey:game-selected", () => { loadControl(true); render(true); });
  window.addEventListener("hockey:settings-updated", () => { loadControl(true); render(true); });
  window.addEventListener("hockey:game-control-updated", (event) => {
    const payload = event.detail?.control;
    const gameId = String(event.detail?.game_id || payload?.game_id || "");
    if (!payload || (state.controlGameId && gameId && state.controlGameId !== gameId)) return;
    state.control = payload;
    state.controlFetchedAt = Date.now();
    render(true);
  });
  window.addEventListener("ui-builder:data-patched", () => render(true));
  document.addEventListener("visibilitychange", () => {
    if (!document.hidden) render(true);
  });

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", mount, { once: true });
  } else {
    mount();
  }
  loadControl(true);
})();
