{% extends "admin/base_site.html" %}
{% load i18n %}

{% block extrastyle %}
{{ block.super }}
<style>
  .release-progress-layout {
    display: flex;
    flex-wrap: wrap;
    gap: 2rem;
    margin-top: 1.5rem;
  }
  .progress-column,
  .log-column {
    flex: 1 1 320px;
    min-width: 280px;
  }
  .progress-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1.25rem;
    padding-bottom: 0.75rem;
  }
  .progress-actions button {
    padding-inline: 1.1rem;
    padding-block: 0.45rem 0.6rem;
  }
  .progress-actions form {
    display: inline;
  }
  .progress-actions button {
    min-width: 8rem;
  }
  .progress-actions .dry-run-form {
    display: flex;
    align-items: center;
    margin-right: 0.75rem;
  }
  .dry-run-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-weight: 600;
  }
  .dry-run-toggle input[type="checkbox"] {
    width: 1.2rem;
    height: 1.2rem;
  }
  .dirty-changes {
    margin: 1.5rem 0;
    padding: 1rem;
    border: 1px solid var(--hairline-color);
    border-radius: 6px;
    background: var(--body-bg);
  }
  .warning-card {
    margin: 1.5rem 0;
    padding: 1rem;
    border: 1px solid var(--hairline-color);
    border-radius: 6px;
    background: rgba(255, 193, 7, 0.15);
  }
  .warning-card h2 {
    margin: 0 0 0.5rem;
  }
  .warning-card ul {
    margin: 0.5rem 0 0;
    padding-left: 1.2rem;
  }
  .warning-card li {
    margin-bottom: 0.5rem;
  }
  .warning-card .warning-message {
    font-weight: 600;
    color: var(--warning-fg, #c09853);
  }
  .warning-card .warning-followups {
    margin: 0.35rem 0 0;
    padding-left: 1.2rem;
    list-style: disc;
  }
  .warning-card .warning-followups li {
    margin-bottom: 0.25rem;
    font-weight: 400;
  }
  .token-card {
    margin: 1.5rem 0;
    padding: 1rem;
    border: 1px solid var(--hairline-color);
    border-radius: 6px;
    background: rgba(13, 110, 253, 0.08);
  }
  .token-card h2 {
    margin: 0 0 0.5rem;
  }
  .token-card p {
    margin: 0.4rem 0 0.8rem;
  }
  .token-card form {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
  }
  .token-card input[type="password"] {
    min-width: 18rem;
    padding: 0.35rem 0.5rem;
  }
  .dirty-changes table {
    width: 100%;
    margin-top: 0.75rem;
    border-collapse: collapse;
  }
  .dirty-changes th,
  .dirty-changes td {
    padding: 0.4rem 0.6rem;
    border-bottom: 1px solid var(--hairline-color);
    text-align: left;
  }
  .dirty-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 1rem;
    align-items: flex-end;
  }
  .dirty-actions form {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    align-items: center;
  }
  .dirty-actions input[type="text"] {
    min-width: 16rem;
    padding: 0.35rem 0.5rem;
  }
  .dirty-error {
    margin-top: 0.75rem;
    color: var(--error-fg, #ba2121);
    font-weight: 600;
  }
  .progress-steps {
    margin: 0 0 1.5rem;
    padding-left: 1.5rem;
  }
  .progress-steps li {
    margin-bottom: 0.5rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }
  .progress-steps li .progress-icon {
    font-size: 1.1em;
  }
  .progress-steps li.status-active .progress-name,
  .progress-steps li.status-paused .progress-name,
  .progress-steps li.status-complete .progress-name {
    font-weight: 600;
  }
  .progress-steps li.status-error .progress-name {
    color: var(--error-fg, #ba2121);
  }
  .progress-steps li.status-blocked .progress-name {
    color: var(--warning-fg, #c09853);
  }
  .log-column {
    background: var(--darkened-bg, rgba(0, 0, 0, 0.05));
    padding: 1rem;
    border-radius: 6px;
  }
  .log-column h2 {
    margin-top: 0;
  }
  .log-text {
    background: var(--body-bg);
    padding: 0.75rem;
    border: 1px solid var(--hairline-color);
    border-radius: 4px;
    white-space: pre-wrap;
    max-height: 400px;
    overflow: auto;
  }
  .log-empty {
    color: var(--body-quiet-color);
    font-style: italic;
  }
  .status-message {
    margin: 1rem 0;
  }
  .status-message.paused {
    color: var(--link-fg);
    font-weight: 600;
  }
</style>
{% endblock %}

{% block nav-breadcrumbs %}
<nav aria-label="{% translate 'Breadcrumbs' %}">
  <div class="breadcrumbs">
    <a href="{% url 'admin:index' %}">{% trans 'Home' %}</a> ›
    {% url 'admin:app_list' 'release' as core_admin_url %}
    <a href="{{ core_admin_url }}">{% trans '2. Business' %}</a> ›
    <a href="{% url 'admin:release_packagerelease_changelist' %}">{% trans 'Package Releases' %}</a> ›
    <a href="{% url 'admin:release_packagerelease_change' release.pk %}">{{ release }}</a> ›
    {{ action|capfirst }}
  </div>
</nav>
{% endblock %}

{% block content %}
<h1>{{ action|capfirst }} {{ release.package.name }} {{ release.version }}</h1>
<div class="release-progress-layout">
  <div class="progress-column">
    <div class="progress-actions">
      <form method="get" class="dry-run-form">
        <input type="hidden" name="set_dry_run" value="1">
        <label class="dry-run-toggle">
          <input type="checkbox" name="dry_run" value="1" {% if dry_run %}checked{% endif %} {% if not dry_run_toggle_enabled %}disabled{% endif %} onchange="this.form.submit()">
          {% trans "Dry Run" %}
        </label>
      </form>
      <form method="get">
        <input type="hidden" name="step" value="{{ current_step }}">
        {% if dry_run %}
        <input type="hidden" name="dry_run" value="1">
        {% endif %}
        <button type="submit" name="start" value="1" {% if is_running or done or error %}disabled{% endif %}>
          {% if can_resume %}
          ▶️ {% trans 'Continue Publish' %}
          {% else %}
          ▶️ {% trans 'Start Publish' %}
          {% endif %}
        </button>
      </form>
      <form method="get">
        <button type="submit" name="pause" value="1" {% if not is_running %}disabled{% endif %}>⏸️ {% trans 'Pause Publish' %}</button>
      </form>
      {% if resume_available %}
      <form method="get">
        <input type="hidden" name="step" value="{{ current_step }}">
        {% if dry_run %}
        <input type="hidden" name="dry_run" value="1">
        {% endif %}
        <button type="submit" name="resume" value="1">⏯️ {% trans 'Resume Publish' %}</button>
      </form>
      {% endif %}
      {% if started %}
      <form method="get">
        <button type="submit" name="restart" value="1">🔄 {% trans 'Restart Publish' %}</button>
      </form>
      {% endif %}
    </div>
    {% if manual_git_push %}
    <p class="status-message paused">
      {% blocktrans with step=manual_git_push.step %}Manual git push required to continue "{{ step }}".{% endblocktrans %}
    </p>
    <p>
      {% trans 'Run' %} <code>{{ manual_git_push_command }}</code>
      {% trans 'then confirm or retry the push below.' %}
    </p>
    {% if manual_git_push_error %}
    <p class="error">{{ manual_git_push_error }}</p>
    {% endif %}
    <div class="progress-actions">
      <form method="get">
        <input type="hidden" name="step" value="{{ current_step }}">
        {% if dry_run %}
        <input type="hidden" name="dry_run" value="1">
        {% endif %}
        <button type="submit" name="manual_push_action" value="retry">🔁 {% trans 'Retry push' %}</button>
      </form>
      <form method="get">
        <input type="hidden" name="step" value="{{ current_step }}">
        {% if dry_run %}
        <input type="hidden" name="dry_run" value="1">
        {% endif %}
        <button type="submit" name="manual_push_action" value="confirm">✅ {% trans 'Manual push completed' %}</button>
      </form>
    </div>
    {% endif %}
    <ol class="progress-steps">
    {% for step in step_states %}
      <li class="status-{{ step.status }}">
        <span class="progress-icon">{{ step.icon }}</span>
        <span class="progress-name">{{ step.name }}</span>
      </li>
    {% endfor %}
    </ol>
    {% if github_credentials_missing and not done %}
    <div class="token-card">
      <h2>🔑 {% trans "GitHub token required" %}</h2>
      {% if github_token_required %}
      <p>{% trans "Publishing paused. Enter a GitHub token to continue. The token is used for this publish session and is not stored in the database." %}</p>
      {% else %}
      <p>{% trans "Enter a GitHub token before starting the publish. The token is used for this publish session and is not stored in the database." %}</p>
      {% endif %}
      <form method="post">
        {% csrf_token %}
        <input type="password" name="github_token" autocomplete="off" placeholder="{% trans 'GitHub token' %}" aria-label="{% trans 'GitHub token' %}">
        {% if github_token_required %}
        <button type="submit" name="set_github_token" value="1">🔁 {% trans "Retry with token" %}</button>
        {% else %}
        <button type="submit" name="set_github_token" value="1">🔑 {% trans "Save token" %}</button>
        {% endif %}
      </form>
    </div>
    {% endif %}
    {% if warnings %}
    <div class="warning-card">
      <h2>⚠️ {% trans "Manual follow-up required" %}</h2>
      <ul>
      {% for warning in warnings %}
        <li>
          <div class="warning-message">{{ warning.message }}</div>
          {% if warning.followups %}
          <ul class="warning-followups">
          {% for note in warning.followups %}
            <li>{{ note }}</li>
          {% endfor %}
          </ul>
          {% endif %}
        </li>
      {% endfor %}
      </ul>
    </div>
    {% endif %}
    {% if paused and started and not done and not error %}
    {% if not github_token_required %}
    <p class="status-message paused">{% trans 'Publishing paused. Press Continue to resume.' %}</p>
    {% endif %}
    {% endif %}
    {% with show_publish_pending_ui=publish_pending and paused and started and not done and not error %}
    {% if show_publish_pending_ui %}
    <p class="status-message paused" id="publish-pending-message" data-poll-url="{{ publish_poll_url }}">
      {% trans "Waiting for GitHub Actions publish to complete. We'll keep checking and notify you when it's done." %}
    </p>
    {% endif %}
    {% if fixtures %}
    <h2>{% trans 'Fixture changes' %}</h2>
    <table>
      <thead>
        <tr>
          <th>{% trans 'Fixture' %}</th>
          <th>{% trans 'Entries' %}</th>
          <th>{% trans 'Models' %}</th>
        </tr>
      </thead>
      <tbody>
      {% for fx in fixtures %}
        <tr>
          <td>{{ fx.path }}</td>
          <td>{{ fx.count }}</td>
          <td>{{ fx.models|join:', ' }}</td>
        </tr>
      {% endfor %}
      </tbody>
    </table>
    {% endif %}
    {% if dirty_files %}
    <div class="dirty-changes">
      <h2>{% trans 'Uncommitted changes detected' %}</h2>
      <p>{% trans 'The repository must be clean before continuing. Review the files below, then discard or commit them.' %}</p>
      <table>
        <thead>
          <tr>
            <th>{% trans 'Status' %}</th>
            <th>{% trans 'Path' %}</th>
          </tr>
        </thead>
        <tbody>
        {% for file in dirty_files %}
          <tr>
            <td>
              {{ file.status_label }}
              {% if file.status_label != file.status %}
              ({{ file.status }})
              {% endif %}
            </td>
            <td>{{ file.path }}</td>
          </tr>
        {% endfor %}
        </tbody>
      </table>
      <div class="dirty-actions">
        <form method="get">
          <input type="hidden" name="step" value="{{ current_step }}">
          <button type="submit" name="dirty_action" value="discard">🧹 {% trans 'Discard local changes' %}</button>
        </form>
        <form method="get">
          <input type="hidden" name="step" value="{{ current_step }}">
          <input type="text" name="dirty_message" value="{{ dirty_commit_message }}" aria-label="{% trans 'Commit message' %}">
          <button type="submit" name="dirty_action" value="commit">💾 {% trans 'Commit changes and continue' %}</button>
        </form>
      </div>
      {% if dirty_commit_error %}
      <p class="dirty-error">{{ dirty_commit_error }}</p>
      {% endif %}
    </div>
    {% endif %}
    {% if error %}
    <p class="error">{{ error }}</p>
    <p class="status-message">{% trans 'Resolve the issue above, then continue to retry this step without restarting.' %}</p>
    {% include "core/partials/release_ack_error_form.html" %}
    {% elif not done %}
    {% if started and next_step is not None %}
    <meta http-equiv="refresh" content="1; url={{ request.path }}?step={{ next_step }}">
    {% endif %}
    {% if started %}
      {% if start_pending %}
      <p class="status-message">{% trans 'Starting publish…' %}</p>
      {% elif paused %}
      {# Paused message shown above #}
      {% else %}
      <p class="status-message">{% trans 'Running…' %}</p>
      {% endif %}
    {% else %}
    <p class="status-message">{% trans 'Waiting to start' %}</p>
    {% endif %}
    {% else %}
    <p>{% trans 'All steps completed.' %}</p>
    {% if release.pypi_url %}
    <p><a href="{{ release.pypi_url }}" target="_blank" rel="noopener">{{ release.pypi_url }}</a></p>
    {% endif %}
    {% if release.github_url %}
    <p><a href="{{ release.github_url }}" target="_blank" rel="noopener">{{ release.github_url }}</a></p>
    {% endif %}
    <div>
      <input type="text" id="logpath" value="{{ log_path }}" readonly>
      <button type="button" onclick="navigator.clipboard.writeText(document.getElementById('logpath').value)">{% trans 'Copy log path' %}</button>
    </div>
    {% if cert_log %}
    <p>{% blocktrans %}Certification logged in {{ cert_log }}{% endblocktrans %}</p>
    {% endif %}
    {% endif %}
    <p>{% trans 'Restarts' %}: {{ restart_count }}</p>
  </div>
  <div class="log-column">
    <h2>{% trans 'Logs' %}</h2>
    {% if show_log %}
      {% if log_content %}
      <pre class="log-text" id="release-log">{{ log_content }}</pre>
      {% else %}
      <p class="log-empty">{% trans 'Logs will appear here as steps progress.' %}</p>
      {% endif %}
    {% else %}
    <p class="log-empty">{% trans 'Logs will appear here after publishing starts.' %}</p>
    {% endif %}
  </div>
</div>
<script>
  (function () {
    const logEl = document.getElementById('release-log');
    if (!logEl) {
      return;
    }

    const scrollToBottom = () => {
      logEl.scrollTop = logEl.scrollHeight;
    };

    scrollToBottom();

    const observer = new MutationObserver(scrollToBottom);
    observer.observe(logEl, { childList: true, characterData: true, subtree: true });
  })();
</script>
{% if show_publish_pending_ui %}
<script>
  (function () {
    const notice = document.getElementById('publish-pending-message');
    if (!notice) {
      return;
    }

    const pollUrl = notice.dataset.pollUrl;
    if (!pollUrl) {
      return;
    }

    const pollDelayMs = 15000;
    let pollTimer = null;

    const schedulePoll = () => {
      pollTimer = window.setTimeout(runPoll, pollDelayMs);
    };

    const runPoll = () => {
      fetch(pollUrl, { headers: { 'X-Requested-With': 'XMLHttpRequest' } })
        .then((response) => (response.ok ? response.json() : null))
        .then((data) => {
          if (!data) {
            schedulePoll();
            return;
          }
          if (data.error) {
            notice.textContent = data.error;
            return;
          }
          if (!data.publish_pending) {
            notice.textContent = "{% trans 'GitHub Actions publish completed. Refreshing…' %}";
            window.location = data.refresh_url || window.location.href;
            return;
          }
          schedulePoll();
        })
        .catch(() => {
          schedulePoll();
        });
    };

    schedulePoll();
  })();
</script>
{% endif %}
{% endwith %}
{% endblock %}
