<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>QR Generator</title>
  <link rel="icon" type="image/png" href="qr.png">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"/>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.3.0/fabric.min.js"></script>
</head>

<body>
<div class="container-fluid py-4">
  <div class="row">
    <div class="col-md-4">
      <input type="file" id="background" class="form-control mb-2"/>
      <button id="uploadBackground" class="btn btn-info w-100 mb-2">
        <span class="spinner-border spinner-border-sm d-none me-2" role="status" aria-hidden="true" id="uploadSpinner"></span>
        Upload Background
      </button>
      <label>Start Number</label><input type="number" id="startNum" class="form-control mb-2" value="1"/>
      <label>End Number</label><input type="number" id="endNum" class="form-control mb-2" value="5"/>
      <label>Increment</label><input type="number" id="increment" class="form-control mb-2" value="1"/>
      <label>Leading Zeros</label><input type="number" id="leadingZeros" class="form-control mb-2" value="3"/>
      <div class="form-check mb-2">
        <input type="checkbox" class="form-check-input" id="showText" checked/>
        <label class="form-check-label" for="showText">Show number under QR</label>
      </div>

      <label for="textColor">Text Color</label>
      <input type="color" id="textColor" class="form-control mb-2" value="#000000"/>


      <button id="addQR" class="btn btn-success w-100 mb-2">Add QR</button>
      <button id="generateZip" class="btn btn-primary w-100">Generate ZIP</button>
    </div>
    <div class="col-md-8">
      <div style="overflow: auto; border: 1px solid #ccc;">
        <canvas id="qrCanvas"></canvas>
      </div>
    </div>
  </div>
</div>

<!-- Loading Modal -->
<div class="modal fade" id="loadingModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content p-4 text-center">
      <div class="spinner-border text-primary mb-3" role="status" style="width: 3rem; height: 3rem;">
        <span class="visually-hidden">Generating...</span>
      </div>
      <h5>Generating ZIP, please wait...</h5>
      <div class="progress mt-3" style="height: 20px;">
        <div id="progressBar" class="progress-bar progress-bar-striped progress-bar-animated"
             role="progressbar" style="width: 0%;">0%</div>
      </div>
    </div>
  </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>

<script>
  const canvas = new fabric.Canvas('qrCanvas');
  let backgroundFile = null, backgroundImageName = '', canvasWidth = canvas.getWidth(), canvasHeight = canvas.getHeight();

  document.getElementById('background').addEventListener('change', e => backgroundFile = e.target.files[0]);

  document.getElementById('uploadBackground').addEventListener('click', () => {
    if (!backgroundFile) return alert('Choose image');
  
    const spinner = document.getElementById('uploadSpinner');
    spinner.classList.remove('d-none'); // Show spinner

    const formData = new FormData();
    formData.append('background', backgroundFile);

    fetch('/upload', { method: 'POST', body: formData })
      .then(res => res.json())
      .then(data => {
        backgroundImageName = data.filename;

        const imgWidth = data.width;
        const imgHeight = data.height;
        const containerMaxWidth = 800;
        const scale = containerMaxWidth / imgWidth;

        const newWidth = Math.round(imgWidth * scale);
        const newHeight = Math.round(imgHeight * scale);

        canvas.setWidth(newWidth);
        canvas.setHeight(newHeight);

        fabric.Image.fromURL(data.url, function (img) {
          canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas), {
            scaleX: scale,
            scaleY: scale
          });
        });

        canvasWidth = newWidth;
        canvasHeight = newHeight;
      })
      .catch(err => console.error(err))
      .finally(() => {
        spinner.classList.add('d-none'); // Hide spinner
      });
  });

  document.getElementById('addQR').addEventListener('click', () => {
    const qr = new fabric.Rect({
      left: 100, top: 100, width: 100, height: 100,
      fill: 'white', stroke: 'black', strokeWidth: 1,
      hasControls: true, hasBorders: true, type: 'qr'
    });
    canvas.add(qr);
  });

  document.getElementById('generateZip').addEventListener('click', () => {
    const startNum = parseInt(document.getElementById('startNum').value);
    const endNum = parseInt(document.getElementById('endNum').value);
    const increment = parseInt(document.getElementById('increment').value);
    const showText = document.getElementById('showText').checked;
    const leadingZeros = parseInt(document.getElementById('leadingZeros').value);


    const qrData = canvas.getObjects().filter(o => o.type === 'qr').map(o => ({
      x: o.left,
      y: o.top,
      width: o.width * o.scaleX,
      height: o.height * o.scaleY
    }));

    // Show modal
    const modal = new bootstrap.Modal(document.getElementById('loadingModal'));
    modal.show();

    const progressBar = document.getElementById('progressBar');
    let progress = 0;
    progressBar.style.width = '0%';
    progressBar.textContent = '0%';

    const fakeProgress = setInterval(() => {
      if (progress < 95) {
        progress += Math.random() * 5;
        const p = Math.min(Math.floor(progress), 95);
        progressBar.style.width = `${p}%`;
        progressBar.textContent = `${p}%`;
      }
    }, 200);

    const textColor = document.getElementById('textColor').value;
    
    fetch('/generate', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        image: backgroundImageName,
        qrData, startNum, endNum, increment, showText,
        canvasWidth, canvasHeight,
        leadingZeros,
        textColor
      })
    })
      .then(res => res.blob())
      .then(blob => {
        clearInterval(fakeProgress);
        progressBar.style.width = '100%';
        progressBar.textContent = '100%';

        setTimeout(() => {
          modal.hide();
          const a = document.createElement('a');
          a.href = URL.createObjectURL(blob);
          a.download = 'qr_images.zip';
          a.click();
        }, 500);
      })
      .catch(err => {
        clearInterval(fakeProgress);
        progressBar.style.width = '100%';
        progressBar.classList.remove('bg-primary');
        progressBar.classList.add('bg-danger');
        progressBar.textContent = 'Error!';
        console.error(err);
        setTimeout(() => modal.hide(), 2000);
      });
  });
</script>
</body>
</html>
