<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Dashboard – PixelSage</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
  <nav class="navbar">
    <div class="container navbar-inner">
      <a href="{{ url_for('index') }}" class="logo">Pixel<span>Sage</span></a>
      <ul class="nav-links">
        <li><span style="color:var(--text-muted);font-size:0.9rem;">{{ current_user.username }}</span></li>
        <li><a href="{{ url_for('logout') }}">Logout</a></li>
      </ul>
    </div>
  </nav>

  {% with messages = get_flashed_messages(with_categories=true) %}
    {% if messages %}
      <div class="flash-container">
        {% for category, message in messages %}
          <div class="flash flash-{{ category }}">{{ message }}</div>
        {% endfor %}
      </div>
    {% endif %}
  {% endwith %}

  <main class="dashboard container">
    <header class="dashboard-header">
      <h1>Processing Studio</h1>
      <p>Upload an image, choose an operation, and preview results in real time.</p>
    </header>

    <div class="glass controls" style="padding:1.5rem;margin-bottom:1.5rem;">
      <div class="drop-zone" id="dropZone">
        <input type="file" id="imageInput" accept="image/png,image/jpeg,image/jpg,image/webp">
        <p><strong>Drop an image here</strong> or click to browse</p>
        <p style="font-size:0.8rem;color:var(--text-muted);margin-top:0.5rem;">JPG, PNG · Max 16 MB</p>
      </div>

      <div class="form-group" style="margin-top:1rem;margin-bottom:0;">
        <label class="form-label" for="operation">Operation</label>
        <select class="form-select" id="operation">
          {% for key, label in operations.items() %}
            <option value="{{ key }}">{{ label }}</option>
          {% endfor %}
        </select>
      </div>

      <div class="param-group" id="affineParams">
        <p style="font-size:0.85rem;color:var(--text-muted);margin:0 0 0.75rem;">Affine parameters</p>
        <div class="param-row">
          <div>
            <label>Rotation (°) <span class="range-value" id="angleVal">15</span></label>
            <input type="range" id="angle" name="angle" min="-180" max="180" value="15">
          </div>
          <div>
            <label>Scale <span class="range-value" id="scaleVal">1.0</span></label>
            <input type="range" id="scale" name="scale" min="0.5" max="2" step="0.1" value="1.0">
          </div>
          <div>
            <label>Translate X <span class="range-value" id="txVal">0</span></label>
            <input type="range" id="tx" name="tx" min="-200" max="200" value="0">
          </div>
          <div>
            <label>Translate Y <span class="range-value" id="tyVal">0</span></label>
            <input type="range" id="ty" name="ty" min="-200" max="200" value="0">
          </div>
        </div>
      </div>

      <div class="param-group" id="blurParams">
        <p style="font-size:0.85rem;color:var(--text-muted);margin:0 0 0.75rem;">Blur kernel size (odd)</p>
        <div>
          <label>Kernel <span class="range-value" id="blurVal">15</span></label>
          <input type="range" id="blur_ksize" name="blur_ksize" min="3" max="51" step="2" value="15">
        </div>
      </div>

      <div class="action-bar">
        <button type="button" class="btn btn-primary" id="processBtn" disabled>Process Image</button>
        <a href="#" class="btn btn-secondary" id="downloadBtn" style="display:none;">Download Result</a>
      </div>
    </div>

    <div class="workspace">
      <div class="panel glass">
        <h3 class="panel-title">Original</h3>
        <div class="preview-box" id="originalPreview">
          <div class="preview-placeholder" id="originalPlaceholder">
            <p>No image selected</p>
            <p style="font-size:0.8rem;">Use demo: <a href="#" id="loadDemo">sample landscape</a></p>
          </div>
          <img id="originalImg" alt="Original" style="display:none;">
        </div>
      </div>

      <div class="panel glass">
        <h3 class="panel-title">Processed</h3>
        <div class="preview-box" id="resultPreview">
          <div class="processing-overlay" id="processingOverlay">
            <div class="spinner"></div>
            <span style="font-size:0.85rem;color:var(--text-muted);">Processing…</span>
          </div>
          <div class="preview-placeholder" id="resultPlaceholder">
            <p>Result will appear here</p>
          </div>
          <img id="resultImg" alt="Processed" style="display:none;">
        </div>
        <div class="result-meta" id="resultMeta" style="display:none;">
          <span id="resultOperation"></span>
          <span class="time-badge" id="resultTime"></span>
        </div>
      </div>
    </div>

    <section class="history-section glass" style="padding:1.5rem;">
      <h2 class="font-display">Recent Operations</h2>
      {% if history %}
        <div class="history-table-wrap">
          <table class="history-table">
            <thead>
              <tr>
                <th>Operation</th>
                <th>Original File</th>
                <th>Time (s)</th>
                <th>Date</th>
              </tr>
            </thead>
            <tbody id="historyBody">
              {% for item in history %}
                <tr>
                  <td>{{ item.operation_name }}</td>
                  <td>{{ item.original_filename }}</td>
                  <td>{{ item.processing_time }}</td>
                  <td>{{ item.created_at[:19].replace('T', ' ') }} UTC</td>
                </tr>
              {% endfor %}
            </tbody>
          </table>
        </div>
      {% else %}
        <p class="history-empty">No operations yet. Process your first image above.</p>
      {% endif %}
    </section>
  </main>

  <footer class="footer">
    <p>&copy; 2026 PixelSage · Real-time OpenCV processing</p>
  </footer>

  <script>
    const dropZone = document.getElementById('dropZone');
    const imageInput = document.getElementById('imageInput');
    const operationSelect = document.getElementById('operation');
    const processBtn = document.getElementById('processBtn');
    const downloadBtn = document.getElementById('downloadBtn');
    const originalImg = document.getElementById('originalImg');
    const originalPlaceholder = document.getElementById('originalPlaceholder');
    const resultImg = document.getElementById('resultImg');
    const resultPlaceholder = document.getElementById('resultPlaceholder');
    const processingOverlay = document.getElementById('processingOverlay');
    const resultMeta = document.getElementById('resultMeta');
    const resultOperation = document.getElementById('resultOperation');
    const resultTime = document.getElementById('resultTime');
    const affineParams = document.getElementById('affineParams');
    const blurParams = document.getElementById('blurParams');
    const historyBody = document.getElementById('historyBody');

    let selectedFile = null;
    let debounceTimer = null;

    const DEMO_URL = 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800&h=600&fit=crop';

    function updateParamVisibility() {
      const op = operationSelect.value;
      affineParams.classList.toggle('active', op === 'affine');
      blurParams.classList.toggle('active', op === 'gaussian_blur');
    }

    function bindRange(id, labelId, formatter = v => v) {
      const el = document.getElementById(id);
      const label = document.getElementById(labelId);
      if (!el || !label) return;
      el.addEventListener('input', () => {
        label.textContent = formatter(el.value);
        scheduleProcess();
      });
    }

    bindRange('angle', 'angleVal');
    bindRange('scale', 'scaleVal', v => parseFloat(v).toFixed(1));
    bindRange('tx', 'txVal');
    bindRange('ty', 'tyVal');
    bindRange('blur_ksize', 'blurVal');

    operationSelect.addEventListener('change', () => {
      updateParamVisibility();
      scheduleProcess();
    });

    dropZone.addEventListener('click', () => imageInput.click());

    dropZone.addEventListener('dragover', (e) => {
      e.preventDefault();
      dropZone.classList.add('dragover');
    });

    dropZone.addEventListener('dragleave', () => dropZone.classList.remove('dragover'));

    dropZone.addEventListener('drop', (e) => {
      e.preventDefault();
      dropZone.classList.remove('dragover');
      if (e.dataTransfer.files.length) handleFile(e.dataTransfer.files[0]);
    });

    imageInput.addEventListener('change', () => {
      if (imageInput.files.length) handleFile(imageInput.files[0]);
    });

    function handleFile(file) {
      if (!file.type.match(/^image\/(jpeg|png|jpg|webp)$/)) {
        alert('Please upload a JPG or PNG image.');
        return;
      }
      selectedFile = file;
      const url = URL.createObjectURL(file);
      originalImg.src = url;
      originalImg.style.display = 'block';
      originalPlaceholder.style.display = 'none';
      processBtn.disabled = false;
      scheduleProcess();
    }

    document.getElementById('loadDemo').addEventListener('click', async (e) => {
      e.preventDefault();
      try {
        const res = await fetch(DEMO_URL);
        const blob = await res.blob();
        handleFile(new File([blob], 'demo_landscape.jpg', { type: 'image/jpeg' }));
      } catch {
        alert('Could not load demo image. Check your connection.');
      }
    });

    processBtn.addEventListener('click', () => processImage());

    function scheduleProcess() {
      if (!selectedFile) return;
      clearTimeout(debounceTimer);
      debounceTimer = setTimeout(processImage, 400);
    }

    async function processImage() {
      if (!selectedFile) return;

      const formData = new FormData();
      formData.append('image', selectedFile);
      formData.append('operation', operationSelect.value);
      formData.append('angle', document.getElementById('angle').value);
      formData.append('scale', document.getElementById('scale').value);
      formData.append('tx', document.getElementById('tx').value);
      formData.append('ty', document.getElementById('ty').value);
      formData.append('blur_ksize', document.getElementById('blur_ksize').value);

      processingOverlay.classList.add('active');
      processBtn.disabled = true;

      try {
        const res = await fetch('{{ url_for("api_process") }}', {
          method: 'POST',
          body: formData,
        });
        const data = await res.json();

        if (!res.ok) {
          throw new Error(data.error || 'Processing failed');
        }

        resultImg.src = data.result_url + '?t=' + Date.now();
        resultImg.style.display = 'block';
        resultPlaceholder.style.display = 'none';
        resultMeta.style.display = 'flex';
        resultOperation.textContent = data.operation;
        resultTime.textContent = data.processing_time + 's';

        downloadBtn.href = data.download_url;
        downloadBtn.style.display = 'inline-flex';

        prependHistoryRow(data.operation, selectedFile.name, data.processing_time);
      } catch (err) {
        alert(err.message);
      } finally {
        processingOverlay.classList.remove('active');
        processBtn.disabled = false;
      }
    }

    function prependHistoryRow(operation, filename, time) {
      const empty = document.querySelector('.history-empty');
      if (empty) {
        empty.closest('.history-section').innerHTML = `
          <h2 class="font-display">Recent Operations</h2>
          <div class="history-table-wrap">
            <table class="history-table">
              <thead>
                <tr><th>Operation</th><th>Original File</th><th>Time (s)</th><th>Date</th></tr>
              </thead>
              <tbody id="historyBody"></tbody>
            </table>
          </div>`;
      }

      const tbody = document.getElementById('historyBody');
      if (!tbody) return;

      const now = new Date().toISOString().slice(0, 19).replace('T', ' ') + ' UTC';
      const tr = document.createElement('tr');
      tr.innerHTML = `
        <td>${operation}</td>
        <td>${filename}</td>
        <td>${time}</td>
        <td>${now}</td>`;
      tbody.prepend(tr);

      while (tbody.children.length > 10) {
        tbody.removeChild(tbody.lastChild);
      }
    }

    updateParamVisibility();

    setTimeout(() => {
      document.querySelectorAll('.flash').forEach(el => {
        el.style.opacity = '0';
        el.style.transition = 'opacity 0.4s';
        setTimeout(() => el.remove(), 400);
      });
    }, 4500);
  </script>
</body>
</html>
