{% extends "pages/base.html" %}
{% load i18n %}

{% block title %}{{ stream.name }} | {% trans "Video" %}{% endblock %}

{% block content %}
<div class="container py-5">
  <div class="row justify-content-center">
    <div class="col-lg-8">
      <div class="d-flex align-items-center justify-content-between mb-3">
        <div>
          <p class="text-muted mb-1">{% trans "Live stream" %}</p>
          <h1 class="h3 mb-0">{{ stream.name }}</h1>
        </div>
        {% if request.user.is_staff %}
        <div class="btn-group" role="group">
          <a class="btn btn-outline-primary" href="{{ stream.get_admin_url }}">
            {% trans "Configure" %}
          </a>
          <a class="btn btn-outline-secondary" href="{% url 'video:mjpeg-debug' stream.slug %}">
            {% trans "Debug stream" %}
          </a>
        </div>
        {% endif %}
      </div>
      <div
        class="ratio ratio-16x9 bg-dark rounded shadow-sm d-flex align-items-center justify-content-center overflow-hidden"
        data-mjpeg-probe-url="{% url 'video:mjpeg-probe' stream.slug %}"
      >
        <img
          src="{{ stream_url }}"
          class="img-fluid w-100 h-100 object-fit-cover"
          alt="{% trans 'Live video stream' %}"
          data-stream-url="{{ stream_url }}"
        >
      </div>
      <p class="mt-3 text-muted">
        {% trans "This stream serves Motion JPEG frames directly from the configured device." %}
      </p>
    </div>
  </div>
</div>
<script>
  (() => {
    const container = document.querySelector("[data-mjpeg-probe-url]");
    if (!container) {
      return;
    }
    const probeUrl = container.dataset.mjpegProbeUrl;
    const streamImage = container.querySelector("img");
    const streamUrl = streamImage?.dataset.streamUrl || streamImage?.getAttribute("src");
    let probeTimer = null;
    let retryTimer = null;
    let retryDelay = 3000;
    const maxRetryDelay = 30000;
    const initialRetryDelay = 3000;

    const sendProbe = () => {
      if (!probeUrl) {
        return;
      }
      fetch(probeUrl, { cache: "no-store" }).catch((error) => {
        console.error("MJPEG probe request failed:", error);
      });
    };

    const startProbing = () => {
      if (probeTimer) {
        return;
      }
      sendProbe();
      probeTimer = window.setInterval(sendProbe, 6000);
    };

    const stopProbing = () => {
      if (!probeTimer) {
        return;
      }
      window.clearInterval(probeTimer);
      probeTimer = null;
    };

    const stopRetry = () => {
      if (!retryTimer) {
        return;
      }
      window.clearTimeout(retryTimer);
      retryTimer = null;
    };

    const refreshStream = () => {
      if (!streamImage || !streamUrl) {
        return;
      }
      const separator = streamUrl.includes("?") ? "&" : "?";
      streamImage.src = `${streamUrl}${separator}reload=${Date.now()}`;
    };

    const scheduleRetry = (delay = 3000) => {
      if (retryTimer) {
        return;
      }
      retryTimer = window.setTimeout(() => {
        retryTimer = null;
        refreshStream();
      }, delay);
    };

    const handleVisibility = () => {
      if (document.visibilityState === "visible") {
        startProbing();
        refreshStream();
      } else {
        stopProbing();
        stopRetry();
      }
    };

    if (streamImage) {
      streamImage.addEventListener("error", () => {
        if (document.visibilityState !== "visible") {
          return;
        }
        scheduleRetry(retryDelay);
        retryDelay = Math.min(retryDelay * 2, maxRetryDelay);
        startProbing();
      });
      streamImage.addEventListener("load", () => {
        stopRetry();
        retryDelay = initialRetryDelay;
      });
    }

    handleVisibility();
    document.addEventListener("visibilitychange", handleVisibility);
    window.addEventListener("beforeunload", () => {
      stopRetry();
      stopProbing();
    });
  })();
</script>
{% endblock %}
