// SignupModal.jsx — collects name + email + password + (optional)
// company name, then triggers the signup → checkout flow:
//
//   1. POST /api/v1/auth/signup  → { account_id, draft_token }
//   2. POST /api/v1/checkout       → { transaction_id, checkout_url }
//   3. Paddle.Checkout.open(...) immediately, before the user sees /app
//
// The user pays nothing yet — Paddle collects a payment method against a
// 5-day free trial. After Paddle redirects back to /app?signup=ok&draft=…,
// the OnboardingScreen pulls the draft, creates the user's first search
// set, and lands them in the dashboard.
//
// `planConfig` is the configurator state (preset id, sources, poll, sets
// count, computed price) — stored verbatim on the server in the
// onboarding_drafts table so it survives the Paddle round-trip.

const { useState, useEffect, useRef } = React;

function SignupModal({ open, onClose, planConfig, planName, planSlug, monthlyPrice }) {
  const [form, setForm] = useState({
    name: '', email: '', password: '', company: '',
  });
  const [errors, setErrors] = useState({});
  const [submitting, setSubmitting] = useState(false);
  const [step, setStep] = useState('details'); // 'details' | 'redirecting'
  const [showPassword, setShowPassword] = useState(false);
  const firstField = useRef(null);

  useEffect(() => {
    if (!open) return;
    setStep('details');
    setErrors({});
    setSubmitting(false);
    const onKey = (e) => { if (e.key === 'Escape' && !submitting) onClose && onClose(); };
    document.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    setTimeout(() => firstField.current && firstField.current.focus(), 50);
    return () => {
      document.removeEventListener('keydown', onKey);
      document.body.style.overflow = '';
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open]);

  if (!open) return null;

  const update = (k) => (e) => setForm(f => ({ ...f, [k]: e.target.value }));

  function validate() {
    const e = {};
    if (!form.name.trim()) e.name = 'Required';
    if (!form.email.trim() || !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(form.email)) e.email = 'Enter a valid email';
    if (!form.password || form.password.length < 8) e.password = 'At least 8 characters';
    if (form.password.length > 128) e.password = 'Too long';
    setErrors(e);
    return Object.keys(e).length === 0;
  }

  // First-charge date copy. Read at render so it updates if the dialog
  // is opened across midnight.
  const trialEnd = (() => {
    const d = new Date();
    d.setDate(d.getDate() + 5);
    return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' });
  })();

  function fmtPrice(eur) {
    if (typeof eur !== 'number') return '';
    return '€' + eur.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  }

  async function onSubmit(e) {
    e.preventDefault();
    if (submitting) return;
    if (!validate()) return;
    setSubmitting(true);
    setErrors({});

    try {
      // 1. Create the account (active by default — Paddle webhook flips
      // it inactive on cancel/past_due). Pass the plan slug so the
      // server attaches the right package_id immediately.
      const signupRes = await fetch('/api/v1/auth/signup', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name:        form.name.trim(),
          email:       form.email.trim().toLowerCase(),
          password:    form.password,
          company:     form.company.trim(),
          plan:        planSlug || 'starter',
          plan_config: planConfig || null,
          // First-touch attribution stashed by landing.html on the user's
          // first visit (null if none). Backend treats it as best-effort.
          attribution: (function () {
            try { return JSON.parse(localStorage.getItem('av_attribution') || 'null'); }
            catch (e) { return null; }
          })(),
        }),
      });
      if (signupRes.status === 409) {
        const j = await signupRes.json().catch(() => ({}));
        const err = (j.errors && j.errors[0]) || {};
        setErrors({ email: err.message || 'Email already registered' });
        return;
      }
      if (!signupRes.ok) {
        const j = await signupRes.json().catch(() => ({}));
        if (j.errors && j.errors.length) {
          const fe = {};
          j.errors.forEach(er => { if (er.field) fe[er.field] = er.message; });
          setErrors(Object.keys(fe).length ? fe : { _form: j.error || 'Signup failed' });
        } else {
          setErrors({ _form: j.error || 'Signup failed' });
        }
        return;
      }
      const signup = await signupRes.json();
      const accountId  = signup.account_id;
      const draftToken = signup.draft_token;

      // 2. Create the checkout. If plan == 'custom', send the config so
      // the server can recompute the price authoritatively. For catalog
      // plans (starter/pro) we don't send config — the server uses the
      // catalog price_id from the packages table.
      setStep('redirecting');
      const checkoutBody = {
        plan:        planSlug || 'starter',
        email:       form.email.trim().toLowerCase(),
        account_id:  accountId,
        draft_token: draftToken,
      };
      if (planSlug === 'custom' && planConfig) {
        checkoutBody.config = {
          sets:     planConfig.sets,
          poll_min: planConfig.poll_min,
          sources:  planConfig.sources,
        };
      }
      const coRes = await fetch('/api/v1/checkout', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(checkoutBody),
      });
      if (!coRes.ok) {
        const j = await coRes.json().catch(() => ({}));
        setStep('details');
        setErrors({ _form: j.error || 'Could not start checkout. Please try again or contact support.' });
        return;
      }
      const co = await coRes.json();
      const returnURL = `/app?signup=ok&draft=${encodeURIComponent(draftToken || '')}&email=${encodeURIComponent(form.email.trim().toLowerCase())}`;
      if (co.transaction_id && typeof Paddle !== 'undefined' && window.__paddleInitialised) {
        window.__autovizCheckout = {
          transactionId: co.transaction_id,
          accountId: accountId,
          returnURL: returnURL,
        };
        Paddle.Checkout.open({ transactionId: co.transaction_id });
      } else if (co.checkout_url) {
        window.location.href = co.checkout_url;
      } else {
        setStep('details');
        setErrors({ _form: 'Checkout did not return a URL. Please contact support.' });
      }
    } catch (err) {
      setStep('details');
      setErrors({ _form: 'Network error. Please try again.' });
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <div className="modal-backdrop" onClick={!submitting ? onClose : undefined}>
      <div className="modal modal--md" onClick={(e) => e.stopPropagation()} role="dialog" aria-modal="true">
        {!submitting && <button className="modal__close" onClick={onClose} aria-label="Close">×</button>}

        {step === 'redirecting' ? (
          <div className="modal__success">
            <h3>Opening secure checkout…</h3>
            <p>Paddle will ask for a payment method to start the trial. No charge today.</p>
          </div>
        ) : (
          <form onSubmit={onSubmit} className="modal__form">
            <h3 className="modal__title">Start your 5-day free trial</h3>
            {planName && (
              <p className="modal__subtitle">
                <strong>{planName} plan</strong>
                {typeof monthlyPrice === 'number' && (
                  <> — {fmtPrice(monthlyPrice)}/month after trial</>
                )}
              </p>
            )}

            <div className="modal__row">
              <label className="modal__field">
                <span>Your name *</span>
                <input
                  ref={firstField}
                  type="text"
                  value={form.name}
                  onChange={update('name')}
                  autoComplete="name"
                  aria-invalid={!!errors.name}
                />
                {errors.name && <em className="modal__err">{errors.name}</em>}
              </label>
              <label className="modal__field">
                <span>Company (optional)</span>
                <input
                  type="text"
                  value={form.company}
                  onChange={update('company')}
                  autoComplete="organization"
                />
              </label>
            </div>

            <label className="modal__field">
              <span>Email *</span>
              <input
                type="email"
                value={form.email}
                onChange={update('email')}
                autoComplete="email"
                aria-invalid={!!errors.email}
              />
              {errors.email && <em className="modal__err">{errors.email}</em>}
            </label>

            <label className="modal__field">
              <span>Password *</span>
              <div className="modal__password">
                <input
                  type={showPassword ? 'text' : 'password'}
                  value={form.password}
                  onChange={update('password')}
                  autoComplete="new-password"
                  autoCapitalize="none"
                  autoCorrect="off"
                  spellCheck={false}
                  placeholder="At least 8 characters"
                  aria-invalid={!!errors.password}
                />
                <button
                  type="button"
                  className="modal__password-toggle"
                  onClick={() => setShowPassword(v => !v)}
                  tabIndex={-1}
                  aria-label={showPassword ? 'Hide password' : 'Show password'}
                >
                  {showPassword ? (
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                      <path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24" />
                      <line x1="1" y1="1" x2="23" y2="23" />
                    </svg>
                  ) : (
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                      <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
                      <circle cx="12" cy="12" r="3" />
                    </svg>
                  )}
                </button>
              </div>
              {errors.password && <em className="modal__err">{errors.password}</em>}
            </label>

            <div className="trial-notice">
              <div className="trial-notice__row"><span>5 days free</span><span>✓</span></div>
              <div className="trial-notice__row"><span>No charge today</span><span>✓</span></div>
              <div className="trial-notice__row"><span>First payment on</span><strong>{trialEnd}</strong></div>
              <div className="trial-notice__row"><span>Cancel anytime in Settings</span><span>✓</span></div>
            </div>

            {errors._form && <p className="modal__err modal__err--bar">{errors._form}</p>}

            <div className="modal__actions">
              <button type="button" className="btn btn--ghost" onClick={onClose} disabled={submitting}>Cancel</button>
              <button type="submit" className="btn btn--primary" disabled={submitting}>
                {submitting ? 'Setting up…' : 'Continue to payment method'}
              </button>
            </div>

            <p className="modal__legal">
              By continuing you agree to the <a href="/terms-of-service" target="_blank" rel="noreferrer">Terms</a>{' '}
              and <a href="/privacy-policy" target="_blank" rel="noreferrer">Privacy Policy</a>. Payment processed by Paddle.
            </p>
          </form>
        )}
      </div>
    </div>
  );
}

Object.assign(window, { SignupModal });
