/* TryOnTool — upload → preview → email gate → real API generate → result.
   Wired to the Railway backend at same-origin: /api/try-on/upload, /api/try-on/requests. */

const { useState, useRef, useEffect } = React;

const API_BASE = ''; // same-origin — served by the Railway Express app
const PRODUCT_HANDLE = 'majestic';
const PRODUCT_ID = 'majestic-silk-top-black';
const DISCOUNT_CODE = 'HEDONIQ15';
const GARMENT_IMG = 'https://cdn.shopify.com/s/files/1/0898/5611/5017/files/MajesticTopSilk.jpg?v=1772572326';

function TryOnTool() {
  const [stage, setStage] = useState('idle'); // idle | preview | generating | result | error
  const [photoURL, setPhotoURL] = useState(null);
  const [uploadId, setUploadId] = useState(null);
  const [uploading, setUploading] = useState(false);
  const [email, setEmail] = useState('');
  const [dragover, setDragover] = useState(false);
  const [progress, setProgress] = useState(0);
  const [logStep, setLogStep] = useState(0);
  const [elapsed, setElapsed] = useState(0); // seconds since generate started
  const [timeLeft, setTimeLeft] = useState(15 * 60); // 15:00 for discount
  const [resultImageUrl, setResultImageUrl] = useState(null);
  const [errorMessage, setErrorMessage] = useState('');
  const fileRef = useRef(null);

  const logs = [
    'Analyzing body proportions',
    'Mapping pose + lighting',
    'Draping Majestic Silk Top',
    'Matching skin tone + shadows',
    'Finalizing editorial render',
  ];

  // discount countdown once we hit result
  useEffect(() => {
    if (stage !== 'result') return;
    const t = setInterval(() => setTimeLeft(s => Math.max(0, s - 1)), 1000);
    return () => clearInterval(t);
  }, [stage]);

  // Honest progress while the backend renders.
  // fal median render: ~45-60s at 1K. We ramp to 85% over 60s, then crawl to 95% over another 60s,
  // so the bar never looks frozen while the backend is still working. Snaps to 100% when the real
  // poll returns complete.
  useEffect(() => {
    if (stage !== 'generating') return;
    setProgress(0);
    setLogStep(0);
    setElapsed(0);
    const start = Date.now();
    const int = setInterval(() => {
      const ms = Date.now() - start;
      const secs = Math.floor(ms / 1000);
      setElapsed(secs);

      // Two-phase ramp: 0→85% over 60s (fast-feeling), 85→95% over next 60s (slow crawl).
      let p;
      if (ms < 60000) {
        p = (ms / 60000) * 85;
      } else if (ms < 120000) {
        p = 85 + ((ms - 60000) / 60000) * 10;
      } else {
        p = 95; // hold at 95% indefinitely until real result lands
      }
      setProgress(p);
      setLogStep(Math.min(logs.length - 1, Math.floor((p / 100) * logs.length)));
    }, 250);
    return () => clearInterval(int);
  }, [stage]);

  const uploadPhoto = async (file) => {
    setUploading(true);
    setErrorMessage('');
    try {
      const fd = new FormData();
      fd.append('photo', file);
      const res = await fetch(`${API_BASE}/api/try-on/upload`, { method: 'POST', body: fd });
      if (!res.ok) {
        const body = await res.json().catch(() => ({}));
        throw new Error(body.error || 'Upload failed');
      }
      const data = await res.json();
      setUploadId(data.id);
    } catch (err) {
      setErrorMessage(err.message || 'Upload failed');
      setUploadId(null);
    } finally {
      setUploading(false);
    }
  };

  const handleFile = (f) => {
    if (!f) return;
    if (!['image/jpeg', 'image/png'].includes(f.type)) {
      setErrorMessage('Please upload a JPG or PNG.');
      return;
    }
    if (f.size > 10 * 1024 * 1024) {
      setErrorMessage('Image must be under 10 MB.');
      return;
    }
    setErrorMessage('');
    setPhotoURL(URL.createObjectURL(f));
    setStage('preview');
    // kick off upload in the background so the API call overlaps with the email gate
    void uploadPhoto(f);
  };

  const onDrop = (e) => {
    e.preventDefault();
    setDragover(false);
    const f = e.dataTransfer.files && e.dataTransfer.files[0];
    if (f) handleFile(f);
  };

  const pollRequest = async (id) => {
    // 120 polls × 2.5s = 5 min budget. fal median is ~45s, tail can be 2-3 min under load.
    for (let i = 0; i < 120; i++) {
      await new Promise(r => setTimeout(r, 2500));
      try {
        const res = await fetch(`${API_BASE}/api/try-on/requests/${id}`);
        if (!res.ok) continue;
        const d = await res.json();
        if (d.status === 'complete' || d.status === 'failed') return d;
      } catch {
        // transient network error — keep polling
      }
    }
    throw new Error('Generation took longer than expected — please try again.');
  };

  const submit = async (e) => {
    e && e.preventDefault();
    if (!email || !email.includes('@')) return;
    if (!uploadId) {
      setErrorMessage('Still processing your photo — give it a second and try again.');
      return;
    }
    setStage('generating');
    setErrorMessage('');

    try {
      const reqRes = await fetch(`${API_BASE}/api/try-on/requests`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          productId: PRODUCT_ID,
          productHandle: PRODUCT_HANDLE,
          uploadId,
        }),
      });
      if (!reqRes.ok) {
        const body = await reqRes.json().catch(() => ({}));
        throw new Error(body.error || 'Could not start generation');
      }
      const req = await reqRes.json();
      const final = await pollRequest(req.id);
      if (final.status === 'complete' && final.resultImageUrl) {
        setResultImageUrl(final.resultImageUrl);
        setProgress(100);
        setLogStep(logs.length - 1);
        setTimeout(() => setStage('result'), 400);
      } else {
        throw new Error(final.errorMessage || 'Generation failed');
      }
    } catch (err) {
      setErrorMessage(err.message || 'Something went wrong');
      setStage('error');
    }
  };

  const reset = () => {
    setStage('idle');
    setPhotoURL(null);
    setUploadId(null);
    setEmail('');
    setResultImageUrl(null);
    setErrorMessage('');
  };

  const fmtTime = (s) => {
    const m = Math.floor(s / 60);
    const ss = String(s % 60).padStart(2, '0');
    return `${String(m).padStart(2,'0')}:${ss}`;
  };

  const header = (step) => (
    <div className="tool-head">
      <div className="tool-title">⬤ VIRTUAL TRY-ON · BETA</div>
      <div className="tool-step">STEP <b>{step}</b> / 03</div>
    </div>
  );

  if (stage === 'idle') {
    return (
      <div className="tool">
        {header('01')}
        <div
          className={`drop ${dragover ? 'dragover' : ''}`}
          onClick={() => fileRef.current && fileRef.current.click()}
          onDragOver={(e) => { e.preventDefault(); setDragover(true); }}
          onDragLeave={() => setDragover(false)}
          onDrop={onDrop}
        >
          <div className="drop-icon">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
              <path d="M12 5v14M5 12h14"/>
            </svg>
          </div>
          <div className="drop-title">Drop your photo</div>
          <div className="drop-hint">Clear, front-facing · Good lighting · Shoulders visible</div>
          <div className="drop-or">— OR —</div>
          <button className="drop-btn" onClick={(e) => { e.stopPropagation(); fileRef.current && fileRef.current.click(); }}>
            Choose from device
          </button>
          <input
            ref={fileRef}
            type="file"
            accept="image/jpeg,image/png"
            style={{ display: 'none' }}
            onChange={(e) => handleFile(e.target.files[0])}
          />
        </div>
        {errorMessage && (
          <div className="micro-copy" style={{ color: 'var(--accent-hot)', marginTop: 10 }}>{errorMessage}</div>
        )}
        <div className="trust-row">
          <span>
            <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
              <path d="M20 6L9 17l-5-5"/>
            </svg>
            Deleted in 24h
          </span>
          <span>
            <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
              <path d="M20 6L9 17l-5-5"/>
            </svg>
            Private to you
          </span>
          <span>
            <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
              <path d="M20 6L9 17l-5-5"/>
            </svg>
            No watermark
          </span>
        </div>
      </div>
    );
  }

  if (stage === 'preview') {
    return (
      <div className="tool">
        {header('02')}
        <div className="preview-wrap">
          <div className="preview-card">
            <div className="tag">YOU</div>
            <img src={photoURL} alt="You"/>
            <button className="remove" onClick={reset} title="Remove">×</button>
          </div>
          <div className="preview-card garment">
            <div className="tag">GARMENT</div>
            <div
              className="garment-silhouette"
              style={{
                background: `url('${GARMENT_IMG}') center/contain no-repeat`,
              }}
            />
          </div>
        </div>

        <div style={{ marginTop: 14, padding: 14, border: '1px solid var(--line)', background: 'var(--bg-3)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <div>
            <div style={{ fontFamily: 'var(--serif)', fontSize: 18, fontStyle: 'italic' }}>Majestic Silk Top</div>
            <div className="mono" style={{ color: 'var(--ink-mute)', marginTop: 4 }}>Silk · Black · Hedoniq Signature</div>
          </div>
          <div className="mono" style={{ color: 'var(--accent-2)' }}>AED 1,318</div>
        </div>

        <form className="email-gate" onSubmit={submit}>
          <div className="mono" style={{ color: 'var(--ink-dim)' }}>
            ENTER EMAIL — WE'LL SEND YOUR RESULT + 15% OFF
          </div>
          <div className="email-row">
            <input
              type="email"
              required
              placeholder="you@domain.com"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
            />
          </div>
          <button
            type="submit"
            className="cta-primary cta-block"
            disabled={!email.includes('@') || uploading}
          >
            {uploading ? 'Processing photo…' : 'Transform me →'}
          </button>
          {errorMessage && (
            <div className="micro-copy" style={{ color: 'var(--accent-hot)' }}>{errorMessage}</div>
          )}
          <div className="micro-copy">
            No spam. Unsubscribe anytime. By continuing you agree to our <a href="https://hedoniq.store/policies/terms-of-service" target="_blank" rel="noopener">Terms</a> + <a href="https://hedoniq.store/policies/privacy-policy" target="_blank" rel="noopener">Privacy</a>.
          </div>
        </form>
      </div>
    );
  }

  if (stage === 'generating') {
    const statusLine =
      elapsed < 45 ? 'RENDERING YOUR LOOK…' :
      elapsed < 90 ? 'RENDERING · ALMOST THERE' :
      elapsed < 150 ? 'STILL RENDERING · HANG TIGHT' :
      'FINAL TOUCHES · DON\'T CLOSE THIS PAGE';
    return (
      <div className="tool">
        {header('03')}
        <div className="generating">
          <div className="gen-visual">
            <div className="gen-grid"/>
            <div className="gen-silhouette"/>
            <div className="gen-scan"/>
          </div>
          <div className="gen-status">{statusLine}</div>
          <div className="gen-progress">
            <div className="gen-progress-bar" style={{ width: progress + '%' }}/>
          </div>
          <div className="mono" style={{ textAlign: 'center', marginTop: 10, color: 'var(--ink-mute)', letterSpacing: '0.2em' }}>
            {`${elapsed}s elapsed · typical render 45–90s`}
          </div>
          <div className="gen-logs">
            {logs.map((l, i) => {
              const cls = i < logStep ? 'done' : i === logStep ? 'active' : 'pending';
              return <div key={i} className={cls}>{l}</div>;
            })}
          </div>
        </div>
      </div>
    );
  }

  if (stage === 'result') {
    return (
      <div className="tool">
        <div className="tool-head">
          <div className="tool-title" style={{ color: 'var(--accent-2)' }}>⬤ YOUR TRANSFORMATION</div>
          <button onClick={reset} className="mono" style={{ color: 'var(--ink-mute)' }}>↻ TRY AGAIN</button>
        </div>

        <div className="result">
          <div className="result-img">
            <div className="tag">AI · PREVIEW</div>
            <div
              className="result-composite"
              style={resultImageUrl ? {
                background: `url('${resultImageUrl}') center/cover no-repeat`,
              } : undefined}
            />
            <div style={{ position: 'absolute', bottom: 14, left: 14, right: 14, fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 22, color: 'var(--ink)', textShadow: '0 2px 20px rgba(0,0,0,0.8)' }}>
              This is the version of you<br/>that doesn't play it safe.
            </div>
          </div>

          <div className="result-product">
            <div>
              <div className="prod-name">Majestic Silk Top</div>
              <div className="prod-price" style={{ marginTop: 4 }}>
                <span className="strike">AED 1,318</span>
                <b>AED 1,120</b>
              </div>
            </div>
            <div className="mono" style={{ color: 'var(--ink-mute)' }}>−15%</div>
          </div>

          <div className="discount-box">
            <div className="discount-label">UNLOCKED · FIRST-ORDER DISCOUNT</div>
            <div className="discount-code">
              <span>15% off</span>
              <span className="code">{DISCOUNT_CODE}</span>
            </div>
            <div className="discount-timer">
              EXPIRES IN <b>{fmtTime(timeLeft)}</b>
            </div>
          </div>

          <div className="reveal-actions">
            <a
              className="cta-primary cta-block"
              href={`https://hedoniq.store/products/majestic-silk-top-black?discount=${DISCOUNT_CODE}`}
              target="_blank"
              rel="noopener"
            >Claim yours →</a>
            <a
              className="cta-secondary"
              href={resultImageUrl || '#'}
              target="_blank"
              rel="noopener"
              download
            >Share / Download</a>
          </div>

          <div className="micro-copy">
            We've emailed your result to <b style={{ color: 'var(--ink-dim)' }}>{email}</b>
          </div>
        </div>
      </div>
    );
  }

  if (stage === 'error') {
    return (
      <div className="tool">
        {header('—')}
        <div style={{ padding: 20, border: '1px solid var(--line)', background: 'var(--bg-3)' }}>
          <div className="mono" style={{ color: 'var(--accent-hot)', marginBottom: 10 }}>SOMETHING WENT WRONG</div>
          <div className="sub" style={{ marginBottom: 18, color: 'var(--ink-dim)' }}>{errorMessage || 'Please try again in a moment.'}</div>
          <button className="cta-primary cta-block" onClick={reset}>Try again</button>
        </div>
      </div>
    );
  }

  return null;
}

window.TryOnTool = TryOnTool;
