// QR Code Generator — real spec-compliant QR encoding via the `qrcode` lib (CDN).
// Renders to a canvas with configurable colors, error-correction level, size,
// and quiet-zone margin. Output is a downloadable PNG.

const QR_LIB_URL = 'https://cdn.jsdelivr.net/npm/qrcode@1.5.3/build/qrcode.min.js';

async function ensureQR() {
  if (window.QRCode && window.QRCode.toCanvas) return window.QRCode;
  await window.loadScript(QR_LIB_URL);
  return window.QRCode;
}

window.TOOL_HANDLERS['qr-generator'] = function QrGeneratorTool() {
  const [text, setText] = React.useState('https://example.com');
  const [fg, setFg] = React.useState('#111111');
  const [bg, setBg] = React.useState('#ffffff');
  const [size, setSize] = React.useState(320);
  const [ecc, setEcc] = React.useState('M');
  const [margin, setMargin] = React.useState(2);
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState('');
  const canvasRef = React.useRef(null);

  const render = React.useCallback(async () => {
    setErr('');
    const canvas = canvasRef.current;
    if (!canvas) return;
    if (!text || !text.trim()) {
      const ctx = canvas.getContext('2d');
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      return;
    }
    setBusy(true);
    try {
      const QR = await ensureQR();
      await QR.toCanvas(canvas, text, {
        width: size,
        margin,
        errorCorrectionLevel: ecc,
        color: { dark: fg, light: bg },
      });
    } catch (e) {
      setErr(e.message || String(e));
    } finally {
      setBusy(false);
    }
  }, [text, fg, bg, size, ecc, margin]);

  React.useEffect(() => {
    const id = setTimeout(render, 80);
    return () => clearTimeout(id);
  }, [render]);

  const download = () => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    canvas.toBlob((blob) => {
      if (blob) window.downloadBlob(blob, 'qr-code.png');
    }, 'image/png');
    window.mmTrackComplete?.('qr-generator', { success: true });
  };

  return (
    <div className="mini-tool">
      <div className="cmp-preview" style={{ gridTemplateColumns: '1fr 1fr', alignItems: 'start' }}>
        <div>
          <label className="mini-label">Text or URL</label>
          <textarea
            className="mini-input"
            style={{ minHeight: 90, resize: 'vertical' }}
            value={text}
            onChange={(e) => setText(e.target.value)}
            placeholder="https://example.com or any text up to ~2.9 KB"
          />

          <div className="mini-row" style={{ marginTop: 12 }}>
            <div className="mini-field" style={{ flex: 1 }}>
              <label className="mini-label">Foreground</label>
              <input type="color" className="mini-input" value={fg}
                     onChange={(e) => setFg(e.target.value)} style={{ height: 36, padding: 4 }} />
            </div>
            <div className="mini-field" style={{ flex: 1 }}>
              <label className="mini-label">Background</label>
              <input type="color" className="mini-input" value={bg}
                     onChange={(e) => setBg(e.target.value)} style={{ height: 36, padding: 4 }} />
            </div>
          </div>

          <div className="mini-row" style={{ marginTop: 12 }}>
            <div className="mini-field" style={{ flex: 1 }}>
              <label className="mini-label">Error correction</label>
              <select className="mini-input" value={ecc} onChange={(e) => setEcc(e.target.value)}>
                <option value="L">Low (~7%)</option>
                <option value="M">Medium (~15%)</option>
                <option value="Q">Quartile (~25%)</option>
                <option value="H">High (~30%)</option>
              </select>
            </div>
            <div className="mini-field" style={{ flex: 1 }}>
              <label className="mini-label">Size (px)</label>
              <input type="number" className="mini-input" min="120" max="1024" step="40"
                     value={size}
                     onChange={(e) => setSize(Math.max(120, Math.min(1024, Number(e.target.value) || 320)))} />
            </div>
            <div className="mini-field" style={{ flex: 1 }}>
              <label className="mini-label">Quiet zone</label>
              <input type="number" className="mini-input" min="0" max="8"
                     value={margin}
                     onChange={(e) => setMargin(Math.max(0, Math.min(8, Number(e.target.value) || 0)))} />
            </div>
          </div>

          {err && <div style={{ color: '#c8321f', marginTop: 10 }}>Error: {err}</div>}
          <div className="cmp-meta" style={{ marginTop: 10 }}>
            Higher error correction keeps the code scannable when partly covered (e.g. a logo overlay), at the cost of denser modules.
          </div>
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 12 }}>
          <div style={{ background: bg, padding: 8, borderRadius: 8, boxShadow: 'var(--id-shadow-md)' }}>
            <canvas ref={canvasRef} width={size} height={size}
                    style={{ display: 'block', maxWidth: '100%', height: 'auto' }} />
          </div>
          <div className="cmp-meta">{busy ? 'Rendering…' : `${size}×${size} · ECC ${ecc}`}</div>
        </div>
      </div>

      <div className="cmp-actions">
        <button className="btn btn-primary" onClick={download} disabled={busy || !text.trim()}>
          <window.Icon name="download" size={16} /> Download PNG
        </button>
      </div>
    </div>
  );
};
