"use strict";

(function bootPopup() {
  var Common = globalThis.SafeSceneCommon;
  var autoSkipEnabledNode = document.getElementById("autoSkipEnabled");
  var notifyBeforeNode = document.getElementById("notifyBeforeSkipSeconds");
  var resumePaddingNode = document.getElementById("resumePaddingSeconds");
  var tabLabelNode = document.getElementById("tabLabel");
  var updateBannerNode = document.getElementById("updateBanner");
  var updateSummaryNode = document.getElementById("updateSummary");
  var updateButton = document.getElementById("updateButton");
  var statusLineNode = document.getElementById("statusLine");
  var episodeSummaryNode = document.getElementById("episodeSummary");
  var sceneSummaryNode = document.getElementById("sceneSummary");
  var warningSummaryNode = document.getElementById("warningSummary");
  var sceneListNode = document.getElementById("sceneList");
  var providerStatusLineNode = document.getElementById("providerStatusLine");
  var providerSummaryNode = document.getElementById("providerSummary");
  var debugOutputNode = document.getElementById("debugOutput");
  var saveButton = document.getElementById("saveButton");
  var refreshButton = document.getElementById("refreshButton");
  var connectButton = document.getElementById("connectButton");

  function sanitizeDisplayText(value) {
    return String(value || "").replace(/\bnudity\b/gi, "explicit scenes");
  }

  function formatCategoryLabel(value) {
    if (String(value || "").toLowerCase() === "nudity") {
      return "explicit scene";
    }

    return value || "scene";
  }

  function sanitizeDisplayValue(value) {
    if (Array.isArray(value)) {
      return value.map(sanitizeDisplayValue);
    }

    if (!value || typeof value !== "object") {
      return typeof value === "string" ? sanitizeDisplayText(value) : value;
    }

    return Object.keys(value).reduce(function buildSanitized(result, key) {
      var outputKey = key === "nudity" ? "explicitScenes" : key;
      result[outputKey] = sanitizeDisplayValue(value[key]);
      return result;
    }, {});
  }

  function hasSkipitSource(sources) {
    return (Array.isArray(sources) ? sources : []).some(function hasSource(source) {
      return String(source && source.kind || "").indexOf("skipit-") === 0 || String(source && source.name || "") === "Skipit";
    });
  }

  function formatCountSummary(counts) {
    if (!counts) {
      return "";
    }

    var segments = [];
    if (Number(counts.nudity || 0) > 0) {
      segments.push("explicit scenes " + Number(counts.nudity || 0));
    }
    if (Number(counts.sex || 0) > 0) {
      segments.push("sex " + Number(counts.sex || 0));
    }
    if (Number(counts.gore || 0) > 0) {
      segments.push("gore " + Number(counts.gore || 0));
    }

    return segments.join(" • ");
  }

  function setStatus(label, style) {
    statusLineNode.textContent = label;
    statusLineNode.className = "status " + style;
  }

  function setProviderStatus(label, style) {
    providerStatusLineNode.textContent = label;
    providerStatusLineNode.className = "status " + style;
  }

  function renderSettings(settings) {
    autoSkipEnabledNode.checked = Boolean(settings.autoSkipEnabled);
    notifyBeforeNode.value = settings.notifyBeforeSkipSeconds;
    resumePaddingNode.value = settings.resumePaddingSeconds;
  }

  function renderUpdateInfo(updateInfo) {
    if (!updateInfo || !updateInfo.hasUpdate) {
      updateBannerNode.hidden = true;
      return;
    }

    updateBannerNode.hidden = false;
    updateSummaryNode.textContent = sanitizeDisplayText(
      updateInfo.message || "There's an update. Please go to the website."
    ) + (updateInfo.latestVersion ? " Latest version: " + updateInfo.latestVersion + "." : "");
  }

  function renderState(payload) {
    var activeTab = payload.activeTab;
    var resolution = payload.state && payload.state.resolution ? payload.state.resolution : null;
    var contentState = payload.state && payload.state.state ? payload.state.state : null;
    var providerStatus = Object.assign({ skipitConnected: false }, payload.providerStatus || {});
    var updateInfo = payload.updateInfo || null;
    var detected = resolution && resolution.detected ? resolution.detected : null;
    var sceneMatch = resolution && resolution.sceneMatch ? resolution.sceneMatch : null;
    var exactRanges = sceneMatch && Array.isArray(sceneMatch.exactRanges)
      ? sceneMatch.exactRanges
      : [];
    var warningOnly = sceneMatch && Array.isArray(sceneMatch.warningOnly)
      ? sceneMatch.warningOnly
      : [];
    var sources = sceneMatch && Array.isArray(sceneMatch.sources)
      ? sceneMatch.sources
      : [];
    var matchingSceneCount = sceneMatch
      ? Number(sceneMatch.matchingSceneCount || exactRanges.length || 0)
      : 0;

    tabLabelNode.textContent = activeTab ? activeTab.title || activeTab.url : "No active tab";
    sceneListNode.innerHTML = "";
    renderUpdateInfo(updateInfo);

    if (providerStatus.skipitConnected) {
      setProviderStatus("Skipit connected", "good");
      providerSummaryNode.textContent = "ta3meya checks Skipit first, then falls back to VideoSkip, Filmiway, CleanStream, and other sources for exact ranges before warning-only review sources.";
      connectButton.textContent = "Reconnect";
    } else {
      setProviderStatus("Skipit not connected", "warn");
      providerSummaryNode.textContent = "ta3meya checks public exact-range sources like VideoSkip, Filmiway, and CleanStream, then falls back to warning-only review sources. Connecting Skipit can unlock more exact ranges.";
      connectButton.textContent = "Connect";
    }

    if (!resolution) {
      setStatus("No ta3meya data for this tab yet.", "neutral");
      episodeSummaryNode.textContent = "";
      sceneSummaryNode.textContent = "";
      warningSummaryNode.textContent = "";
      debugOutputNode.textContent = JSON.stringify({
        activeTab: activeTab ? {
          title: activeTab.title || "",
          url: activeTab.url || ""
        } : null,
        providerStatus: providerStatus,
        updateInfo: updateInfo
      }, null, 2);
      return;
    }

    if (exactRanges.length) {
      setStatus("Ready to auto-skip", "good");
    } else if (matchingSceneCount > 0) {
      setStatus("External scene data found", "warn");
    } else if (detected) {
      setStatus("Episode detected", "neutral");
    } else {
      setStatus("Could not match episode", "neutral");
    }

    if (detected) {
      episodeSummaryNode.textContent = detected.showTitle +
        " S" + detected.seasonNumber +
        "E" + detected.episodeNumber +
        (detected.episodeTitle ? " • " + detected.episodeTitle : "");
    } else {
      episodeSummaryNode.textContent = resolution.reason || "";
    }

    sceneSummaryNode.textContent = exactRanges.length
      ? exactRanges.length + " explicit scene(s) will be skipped automatically."
      : matchingSceneCount && sources.some(function hasNumericSceneCount(source) { return Number(source.sceneCount || 0) > 0; })
        ? matchingSceneCount + " explicit scene(s) were detected from external sources."
        : warningOnly.length
          ? "Explicit scene warnings were found from external review sources."
        : detected
          ? "No explicit scenes are currently recorded for this episode."
          : "No matching scenes found.";

    warningSummaryNode.textContent = warningOnly.length
      ? warningOnly.map(function joinWarning(entry) {
        return entry.sourceName + ": " + sanitizeDisplayText(entry.summary);
      }).join(" ")
      : "";

    if (exactRanges.length) {
      exactRanges.forEach(function renderRange(range) {
        var itemNode = document.createElement("div");
        itemNode.className = "scene-item";
        itemNode.innerHTML =
          "<strong>" +
          formatCategoryLabel(range.category) +
          " • " +
          Common.formatSeconds(range.startSeconds) +
          "-" +
          Common.formatSeconds(range.endSeconds) +
          "</strong>" +
          "<span>" +
          (range.sourceName || "unknown source") +
          "</span>";
        sceneListNode.appendChild(itemNode);
      });
    }

    if (contentState && Array.isArray(contentState.skippedScenes) && contentState.skippedScenes.length) {
      var skippedSummaryNode = document.createElement("div");
      skippedSummaryNode.className = "scene-item";
      skippedSummaryNode.innerHTML =
        "<strong>" + contentState.skippedScenes.length + " scene(s) skipped this session</strong>" +
        "<span>Most recent source: " + (contentState.skippedScenes[contentState.skippedScenes.length - 1].sourceName || "unknown") + "</span>";
      sceneListNode.appendChild(skippedSummaryNode);
    }

    if (!exactRanges.length && matchingSceneCount) {
      sources.forEach(function renderSource(source) {
        var itemNode = document.createElement("div");
        var countSummary = formatCountSummary(source.counts);
        itemNode.className = "scene-item";
        itemNode.innerHTML =
          "<strong>" + (source.name || "External source") + "</strong>" +
          "<span>" +
          (source.sceneCount ? source.sceneCount + " scene(s)" : "Scene data found") +
          (countSummary ? " • " + countSummary : "") +
          "</span>" +
          "<span>" +
          (String(source.kind || "").indexOf("skipit-") === 0
            ? (providerStatus.skipitConnected
              ? "Exact ranges are not available for this episode yet."
              : "Connect Skipit to turn public counts into exact auto-skip ranges when available.")
            : String(source.kind || "").indexOf("-exact") !== -1
              ? "This source provides exact auto-skip ranges."
              : "This source provides warning-level coverage only.") +
          "</span>";
        sceneListNode.appendChild(itemNode);
      });

      if (!sources.length) {
        var summaryNode = document.createElement("div");
        summaryNode.className = "scene-item";
        summaryNode.innerHTML =
          "<strong>" + matchingSceneCount + " scene(s) recorded</strong>" +
          "<span>" +
          (hasSkipitSource(sources)
            ? (providerStatus.skipitConnected
              ? "Exact ranges are not available for this episode yet."
              : "Connect Skipit to load exact ranges when they exist.")
            : "Only warning-level fallback sources are available for this episode.") +
          "</span>";
        sceneListNode.appendChild(summaryNode);
      }
    }

    debugOutputNode.textContent = JSON.stringify(sanitizeDisplayValue({
      activeTab: activeTab ? {
        title: activeTab.title || "",
        url: activeTab.url || ""
      } : null,
      pageContext: payload.state && payload.state.pageContext ? payload.state.pageContext : null,
      contentDebug: contentState && contentState.debug ? contentState.debug : null,
      resolutionStatus: resolution.status,
      resolutionReason: resolution.reason,
      resolutionMeta: resolution.meta || null,
      parseCandidates: Array.isArray(resolution.parseCandidates) ? resolution.parseCandidates : [],
      detected: detected,
      providerStatus: providerStatus,
      sceneMatch: sceneMatch ? {
        status: sceneMatch.status,
        matchingSceneCount: sceneMatch.matchingSceneCount,
        exactRangeCount: exactRanges.length,
        warningOnly: warningOnly,
        sources: sources
      } : null,
      lastAction: contentState && contentState.lastAction ? contentState.lastAction : null
    }), null, 2);
  }

  async function loadPopupState() {
    var payload = await chrome.runtime.sendMessage({ type: "getPopupState" });
    renderSettings(Object.assign({}, Common.DEFAULT_SETTINGS, payload.settings || {}));
    renderState(payload);
  }

  async function saveSettings() {
    var settings = {
      autoSkipEnabled: autoSkipEnabledNode.checked,
      notifyBeforeSkipSeconds: Number.parseInt(notifyBeforeNode.value, 10) || 0,
      resumePaddingSeconds: Number.parseInt(resumePaddingNode.value, 10) || 0
    };

    await chrome.runtime.sendMessage({
      type: "saveSettings",
      settings: settings
    });

    await loadPopupState();
  }

  saveButton.addEventListener("click", saveSettings);
  refreshButton.addEventListener("click", async function refresh() {
    await chrome.runtime.sendMessage({ type: "refreshActiveTab" });
    await loadPopupState();
  });
  connectButton.addEventListener("click", async function connect() {
    await chrome.runtime.sendMessage({ type: "openSkipitConnect" });
  });
  updateButton.addEventListener("click", async function openUpdate() {
    await chrome.runtime.sendMessage({ type: "openUpdateWebsite" });
  });

  loadPopupState();
}());
