/* global React */
// Luna Persona Hermetica — Auth (real backend via /api/*).
// Same public interface as the localStorage prototype this replaces:
//   window.getCurrentUser, useCurrentUser, loginUser, registerUser, logoutUser
//   + components: LoginPage, AccountPage, MyDataPage, HistoryPage, CartPage, AccountMenuLink

const AC = {
  bg: 'rgb(6,11,24)',
  bgDeep: 'rgb(21,19,49)',
  gold: '#E6C79C',
  goldDark: '#9E7B4B',
  lavender: 'rgb(186,171,212)',
  muted: 'rgb(78,70,114)',
  white: 'rgb(255,255,255)'
};

// ─────────────────────────────────────────────────────────────
// Module-level user cache + fetch helper
// ─────────────────────────────────────────────────────────────
let _cachedUser = undefined; // undefined = not loaded; null = anonymous; object = user
let _userPromise = null;

function _emitAuthChange() {
  try { window.dispatchEvent(new CustomEvent('luna-auth-change')); } catch (_) {}
}

async function _loadCurrentUser() {
  if (_userPromise) return _userPromise;
  _userPromise = fetch('/api/auth/me', { credentials: 'include' })
    .then((r) => r.json())
    .then(({ user }) => { _cachedUser = user || null; _emitAuthChange(); return _cachedUser; })
    .catch(() => { _cachedUser = null; _emitAuthChange(); return null; })
    .finally(() => { _userPromise = null; });
  return _userPromise;
}

// Kick off load on script init so subsequent sync getCurrentUser() has data soon.
if (typeof window !== 'undefined') _loadCurrentUser();

function getCurrentUser() {
  if (_cachedUser === undefined) { _loadCurrentUser(); return null; }
  return _cachedUser;
}

function useCurrentUser() {
  // Tri-state: undefined = still fetching /api/auth/me, null = anonymous, object = user.
  // Callers MUST distinguish undefined from null before redirecting, or the page will
  // bounce to login.html before the session check completes.
  const [user, setUser] = React.useState(() => _cachedUser);
  React.useEffect(() => {
    if (_cachedUser === undefined) {
      _loadCurrentUser().then((u) => setUser(u));
    }
    const onChange = () => setUser(_cachedUser);
    window.addEventListener('luna-auth-change', onChange);
    window.addEventListener('storage', onChange);
    return () => {
      window.removeEventListener('luna-auth-change', onChange);
      window.removeEventListener('storage', onChange);
    };
  }, []);
  return user;
}

// ─────────────────────────────────────────────────────────────
// API actions (async). Return { ok, user?, error? } for back-compat with the
// old sync prototype which had the same shape. Callers must `await`.
// ─────────────────────────────────────────────────────────────
async function loginUser(email, password) {
  try {
    const r = await fetch('/api/auth/login', {
      method: 'POST', credentials: 'include',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email, password })
    });
    const body = await r.json();
    if (!r.ok) return { ok: false, error: body.error || 'Logowanie nie powiodło się.' };
    _cachedUser = body.user; _emitAuthChange();
    return { ok: true, user: body.user };
  } catch (e) { return { ok: false, error: e.message }; }
}

async function registerUser(name, email, password) {
  try {
    const r = await fetch('/api/auth/signup', {
      method: 'POST', credentials: 'include',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ name, email, password })
    });
    const body = await r.json();
    if (!r.ok) return { ok: false, error: body.error || 'Rejestracja nie powiodła się.' };
    _cachedUser = body.user; _emitAuthChange();
    return { ok: true, user: body.user };
  } catch (e) { return { ok: false, error: e.message }; }
}

async function logoutUser() {
  try { await fetch('/api/auth/logout', { method: 'POST', credentials: 'include' }); } catch (_) {}
  _cachedUser = null; _emitAuthChange();
  try { window.location.href = 'index.html'; } catch (_) {}
}

async function updateProfile({ name, surname, email }) {
  const r = await fetch('/api/auth/profile', {
    method: 'POST', credentials: 'include',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ action: 'update', name, surname, email })
  });
  const body = await r.json();
  if (!r.ok) return { ok: false, error: body.error || 'Zapis nie powiódł się.' };
  _cachedUser = body.user; _emitAuthChange();
  return { ok: true, user: body.user };
}

async function changePassword(currentPassword, newPassword) {
  const r = await fetch('/api/auth/profile', {
    method: 'POST', credentials: 'include',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ action: 'password', currentPassword, newPassword })
  });
  const body = await r.json();
  if (!r.ok) return { ok: false, error: body.error || 'Zmiana hasła nie powiodła się.' };
  return { ok: true };
}

async function fetchOrders() {
  const r = await fetch('/api/orders', { credentials: 'include' });
  const body = await r.json();
  if (!r.ok) throw new Error(body.error || 'Nie udało się pobrać zamówień.');
  return body.orders || [];
}

async function fetchCart() {
  const r = await fetch('/api/cart', { credentials: 'include' });
  const body = await r.json();
  if (!r.ok) throw new Error(body.error || 'Nie udało się pobrać koszyka.');
  return body.items || [];
}

async function saveCart(items) {
  const r = await fetch('/api/cart', {
    method: 'PUT', credentials: 'include',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ items })
  });
  const body = await r.json();
  if (!r.ok) throw new Error(body.error || 'Zapis koszyka nie powiódł się.');
  return body.items || [];
}

async function checkout() {
  // Creates a Stripe Checkout Session server-side and redirects to Stripe.
  // Server pulls items from the DB cart, so client cannot tamper with prices.
  const r = await fetch('/api/checkout', {
    method: 'POST', credentials: 'include',
    headers: { 'Content-Type': 'application/json' }
  });
  const body = await r.json();
  if (!r.ok) return { ok: false, error: body.error || 'Nie udało się rozpocząć płatności.' };
  // Redirect to Stripe-hosted Checkout page
  window.location.href = body.url;
  return { ok: true, sessionId: body.sessionId, url: body.url };
}

// ─────────────────────────────────────────────────────────────
// LoginPage
// ─────────────────────────────────────────────────────────────
function LoginPage() {
  const [mode, setMode] = React.useState('login');
  const [name, setName] = React.useState('');
  const [email, setEmail] = React.useState('');
  const [password, setPassword] = React.useState('');
  const [error, setError] = React.useState('');
  const [success, setSuccess] = React.useState('');
  const [busy, setBusy] = React.useState(false);

  React.useEffect(() => { setError(''); setSuccess(''); }, [mode]);

  const onSubmit = async (e) => {
    e.preventDefault();
    setError(''); setSuccess(''); setBusy(true);
    const res = mode === 'login'
      ? await loginUser(email, password)
      : await registerUser(name, email, password);
    setBusy(false);
    if (!res.ok) { setError(res.error); return; }
    setSuccess(mode === 'login' ? 'Zalogowano. Przekierowywanie…' : 'Konto utworzone. Przekierowywanie…');
    setTimeout(() => { window.location.href = 'moje-konto.html'; }, 600);
  };

  const inputStyle = {
    padding: '14px 18px', borderRadius: 8,
    background: 'rgba(21,19,49,0.6)',
    border: `1px solid ${AC.muted}`,
    fontFamily: 'Nunito', fontSize: 16, color: AC.white,
    outline: 'none', transition: 'border-color .2s'
  };

  return (
    <section style={{
      position: 'relative', background: AC.bg,
      padding: '160px 24px 100px', overflow: 'hidden'
    }}>
      <div style={{ maxWidth: 520, margin: '0 auto' }}>
        <div style={{ textAlign: 'center', marginBottom: 36 }}>
          <div style={{
            fontFamily: 'Nunito', fontWeight: 700, fontSize: 14,
            letterSpacing: '0.2em', color: AC.muted, marginBottom: 16
          }}>{mode === 'login' ? 'LOGOWANIE' : 'REJESTRACJA'}</div>
          <h1 style={{
            margin: 0, fontFamily: 'Playfair Display', fontWeight: 400, fontSize: 44,
            lineHeight: 1.15, letterSpacing: '-0.022em', color: AC.white
          }}>{mode === 'login' ? 'Witaj ponownie' : 'Załóż konto'}</h1>
          <p style={{
            margin: '16px 0 0', fontFamily: 'Nunito', fontSize: 16, lineHeight: 1.6,
            color: AC.lavender
          }}>{mode === 'login'
            ? 'Zaloguj się, aby zobaczyć swoje konto, zamówienia i historię konsultacji.'
            : 'Załóż konto, aby śledzić swoje zamówienia i wracać do swoich konsultacji.'}</p>
        </div>

        <div style={{
          display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 0,
          border: `1px solid ${AC.muted}`, borderRadius: 8,
          padding: 4, marginBottom: 24
        }}>
          {['login', 'register'].map((m) =>
            <button key={m} type="button" onClick={() => setMode(m)} style={{
              padding: '12px 16px', borderRadius: 6,
              border: 'none',
              background: mode === m ? 'rgba(230,199,156,0.12)' : 'transparent',
              color: mode === m ? AC.gold : AC.lavender,
              fontFamily: 'Nunito', fontWeight: 600, fontSize: 14,
              letterSpacing: '0.06em', cursor: 'pointer',
              transition: 'background .2s, color .2s'
            }}>{m === 'login' ? 'Zaloguj się' : 'Załóż konto'}</button>
          )}
        </div>

        <form onSubmit={onSubmit} style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          {mode === 'register' &&
            <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
              <span style={{
                fontFamily: 'Nunito', fontSize: 13, letterSpacing: '0.1em',
                textTransform: 'uppercase', color: AC.muted, fontWeight: 600
              }}>Imię</span>
              <input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder="Twoje imię" style={inputStyle} autoComplete="given-name" />
            </label>
          }
          <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            <span style={{
              fontFamily: 'Nunito', fontSize: 13, letterSpacing: '0.1em',
              textTransform: 'uppercase', color: AC.muted, fontWeight: 600
            }}>Adres e-mail</span>
            <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="np. anna@example.com" style={inputStyle} autoComplete="email" required />
          </label>
          <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            <span style={{
              fontFamily: 'Nunito', fontSize: 13, letterSpacing: '0.1em',
              textTransform: 'uppercase', color: AC.muted, fontWeight: 600
            }}>Hasło</span>
            <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder={mode === 'register' ? 'min. 8 znaków' : '•••••••'} style={inputStyle} autoComplete={mode === 'register' ? 'new-password' : 'current-password'} required />
          </label>

          {error && <div style={{ fontFamily: 'Nunito', fontSize: 14, color: '#f49b9b' }}>{error}</div>}
          {success && <div style={{ fontFamily: 'Nunito', fontSize: 14, color: AC.gold }}>{success}</div>}

          <div style={{ marginTop: 8 }}>
            <BtnMain disabled={busy}>{busy ? '...' : (mode === 'login' ? 'Zaloguj się' : 'Załóż konto')}</BtnMain>
          </div>
        </form>

        <p style={{
          margin: '24px 0 0', textAlign: 'center',
          fontFamily: 'Nunito', fontSize: 14, color: AC.muted
        }}>
          {mode === 'login' ? 'Nie masz konta? ' : 'Masz już konto? '}
          <button type="button" onClick={() => setMode(mode === 'login' ? 'register' : 'login')} style={{
            background: 'none', border: 'none', padding: 0,
            fontFamily: 'Nunito', fontSize: 14, color: AC.gold,
            cursor: 'pointer', textDecoration: 'underline'
          }}>{mode === 'login' ? 'Załóż je teraz' : 'Zaloguj się'}</button>
        </p>
      </div>
    </section>);
}

// ─────────────────────────────────────────────────────────────
// AccountPage
// ─────────────────────────────────────────────────────────────
function AccountPage() {
  const user = useCurrentUser();
  React.useEffect(() => {
    if (user === null) window.location.href = 'login.html';
  }, [user]);
  if (!user) return null;

  const items = [
    { title: 'Moje dane', body: 'Sprawdź i zaktualizuj dane swojego konta.', cta: 'Edytuj profil', href: 'moje-dane.html' },
    { title: 'Historia zakupów', body: 'Wszystkie Twoje dotychczasowe zamówienia i konsultacje.', cta: 'Zobacz historię', href: 'historia-zakupow.html' },
    { title: 'Koszyk', body: 'Usługi i konsultacje czekające na płatność.', cta: 'Przejdź do koszyka', href: 'koszyk.html' }
  ];

  return (
    <section style={{
      position: 'relative', background: AC.bg,
      padding: '160px 24px 100px', overflow: 'hidden'
    }}>
      <div style={{ maxWidth: 960, margin: '0 auto' }}>
        <div style={{ textAlign: 'center', marginBottom: 56 }}>
          <div style={{
            fontFamily: 'Nunito', fontWeight: 700, fontSize: 14,
            letterSpacing: '0.2em', color: AC.muted, marginBottom: 16
          }}>MOJE KONTO</div>
          <h1 style={{
            margin: 0, fontFamily: 'Playfair Display', fontWeight: 400, fontSize: 44,
            lineHeight: 1.15, letterSpacing: '-0.022em', color: AC.white
          }}>Witaj, {user.name || user.email}</h1>
          <p style={{
            margin: '16px 0 0', fontFamily: 'Nunito', fontSize: 16, lineHeight: 1.6,
            color: AC.lavender
          }}>Tutaj znajdziesz wszystko, co zapisaliśmy dla Ciebie w jednym miejscu.</p>
        </div>

        <div style={{
          display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 24
        }}>
          {items.map((it, i) =>
            <div key={i} style={{
              padding: 28, borderRadius: 16,
              border: `1px solid ${AC.muted}`,
              background: 'rgba(21,19,49,0.45)',
              display: 'flex', flexDirection: 'column', gap: 12
            }}>
              <h3 style={{
                margin: 0, fontFamily: 'Playfair Display', fontWeight: 400, fontSize: 24,
                color: AC.white, letterSpacing: '-0.022em'
              }}>{it.title}</h3>
              <p style={{
                margin: 0, fontFamily: 'Nunito', fontSize: 15, lineHeight: 1.6,
                color: AC.lavender, flex: 1
              }}>{it.body}</p>
              <div>
                <BtnSecond small href={it.href}>{it.cta}</BtnSecond>
              </div>
            </div>
          )}
        </div>

        <div style={{
          marginTop: 48, paddingTop: 32,
          borderTop: `1px solid ${AC.muted}`,
          display: 'flex', justifyContent: 'center', gap: 16, flexWrap: 'wrap',
          alignItems: 'center'
        }}>
          <span style={{ fontFamily: 'Nunito', fontSize: 14, color: AC.muted }}>
            Zalogowano jako <span style={{ color: AC.white }}>{user.email}</span>
          </span>
          <button onClick={logoutUser} style={{
            background: 'none', border: 'none', padding: 0,
            fontFamily: 'Nunito', fontWeight: 700, fontSize: 14,
            color: AC.gold, cursor: 'pointer', textDecoration: 'underline'
          }}>Wyloguj się</button>
        </div>
      </div>
    </section>);
}

// ─────────────────────────────────────────────────────────────
// AccountMenuLink
// ─────────────────────────────────────────────────────────────
function AccountMenuLink() {
  const user = useCurrentUser();
  const [open, setOpen] = React.useState(false);
  const wrapRef = React.useRef(null);

  React.useEffect(() => {
    if (!open) return;
    const onDocClick = (e) => {
      if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
    };
    document.addEventListener('mousedown', onDocClick);
    return () => document.removeEventListener('mousedown', onDocClick);
  }, [open]);

  if (!user) {
    return (
      <a href="login.html" style={{
        fontFamily: 'Nunito', fontWeight: 500, fontSize: 14,
        color: AC.lavender, textDecoration: 'none', transition: 'color .2s'
      }}
      onMouseEnter={(e) => e.currentTarget.style.color = AC.gold}
      onMouseLeave={(e) => e.currentTarget.style.color = AC.lavender}>
        Zaloguj się
      </a>);
  }

  const menuItems = [
    { label: 'Moje konto', href: 'moje-konto.html' },
    { label: 'Moje dane', href: 'moje-dane.html' },
    { label: 'Historia zakupów', href: 'historia-zakupow.html' },
    { label: 'Koszyk', href: 'koszyk.html' }
  ];

  return (
    <div ref={wrapRef} style={{ position: 'relative' }}>
      <button onClick={() => setOpen((v) => !v)} style={{
        background: 'none', border: 'none', padding: 0, cursor: 'pointer',
        fontFamily: 'Nunito', fontWeight: 500, fontSize: 14,
        color: open ? AC.gold : AC.lavender, transition: 'color .2s',
        display: 'inline-flex', alignItems: 'center', gap: 6
      }}
      onMouseEnter={(e) => e.currentTarget.style.color = AC.gold}
      onMouseLeave={(e) => { if (!open) e.currentTarget.style.color = AC.lavender; }}>
        Moje konto
        <span style={{
          fontSize: 10, opacity: 0.8,
          transform: open ? 'rotate(180deg)' : 'none',
          transition: 'transform .2s'
        }}>▾</span>
      </button>

      <div style={{
        position: 'absolute', top: 'calc(100% + 14px)', right: 0,
        minWidth: 220,
        background: 'rgba(6,11,24,0.96)',
        border: `1px solid ${AC.muted}`,
        backdropFilter: 'blur(40px)', WebkitBackdropFilter: 'blur(40px)',
        borderRadius: 12,
        padding: 8,
        opacity: open ? 1 : 0,
        transform: open ? 'translateY(0)' : 'translateY(-4px)',
        pointerEvents: open ? 'auto' : 'none',
        transition: 'opacity .2s, transform .2s',
        zIndex: 110,
        display: 'flex', flexDirection: 'column'
      }}>
        <div style={{
          padding: '12px 14px 14px',
          borderBottom: `1px solid ${AC.muted}`,
          fontFamily: 'Nunito', fontSize: 12, color: AC.muted, letterSpacing: '0.05em'
        }}>
          Zalogowano jako<br />
          <span style={{ color: AC.white, fontSize: 13 }}>{user.email}</span>
        </div>
        {menuItems.map((mi) =>
          <a key={mi.label} href={mi.href} style={{
            padding: '12px 14px', borderRadius: 8,
            fontFamily: 'Nunito', fontSize: 14, fontWeight: 500,
            color: AC.lavender, textDecoration: 'none',
            transition: 'background .15s, color .15s'
          }}
          onMouseEnter={(e) => { e.currentTarget.style.background = 'rgba(230,199,156,0.08)'; e.currentTarget.style.color = AC.gold; }}
          onMouseLeave={(e) => { e.currentTarget.style.background = 'transparent'; e.currentTarget.style.color = AC.lavender; }}>
            {mi.label}
          </a>
        )}
        <button onClick={logoutUser} style={{
          margin: 0, padding: '12px 14px', borderRadius: 8,
          background: 'none', border: 'none',
          fontFamily: 'Nunito', fontSize: 14, fontWeight: 500,
          color: AC.gold, cursor: 'pointer', textAlign: 'left',
          transition: 'background .15s'
        }}
        onMouseEnter={(e) => e.currentTarget.style.background = 'rgba(230,199,156,0.08)'}
        onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
          Wyloguj się
        </button>
      </div>
    </div>);
}

// ─────────────────────────────────────────────────────────────
// MyDataPage — edit profile (name, surname, email, change password)
// ─────────────────────────────────────────────────────────────
function _splitName(full) {
  // Split "Imię Nazwisko (...)" into { name, surname }
  if (!full) return { name: '', surname: '' };
  const parts = String(full).trim().split(/\s+/);
  if (parts.length === 1) return { name: parts[0], surname: '' };
  return { name: parts[0], surname: parts.slice(1).join(' ') };
}

function MyDataPage() {
  const user = useCurrentUser();
  const [name, setName] = React.useState('');
  const [surname, setSurname] = React.useState('');
  const [email, setEmail] = React.useState('');
  const [currentPwd, setCurrentPwd] = React.useState('');
  const [newPwd, setNewPwd] = React.useState('');
  const [newPwd2, setNewPwd2] = React.useState('');
  const [profileMsg, setProfileMsg] = React.useState(null);
  const [pwdMsg, setPwdMsg] = React.useState(null);

  React.useEffect(() => {
    if (user === null) { window.location.href = 'login.html'; return; }
    if (!user) return;
    const { name: n, surname: s } = _splitName(user.name);
    setName(n);
    setSurname(s);
    setEmail(user.email || '');
  }, [user && user.email, user && user.name]);

  if (!user) return null;

  const inputStyle = {
    padding: '14px 18px', borderRadius: 8,
    background: 'rgba(21,19,49,0.6)',
    border: `1px solid ${AC.muted}`,
    fontFamily: 'Nunito', fontSize: 16, color: AC.white,
    outline: 'none', transition: 'border-color .2s'
  };

  const saveProfile = async (e) => {
    e.preventDefault();
    setProfileMsg(null);
    const res = await updateProfile({ name, surname, email });
    setProfileMsg(res.ok ? { ok: true, text: 'Dane zapisane.' } : { ok: false, text: res.error });
  };

  const submitChangePwd = async (e) => {
    e.preventDefault();
    setPwdMsg(null);
    if (!newPwd || newPwd.length < 8) { setPwdMsg({ ok: false, text: 'Nowe hasło musi mieć minimum 8 znaków.' }); return; }
    if (newPwd !== newPwd2) { setPwdMsg({ ok: false, text: 'Nowe hasła nie są zgodne.' }); return; }
    const res = await changePassword(currentPwd, newPwd);
    if (res.ok) {
      setCurrentPwd(''); setNewPwd(''); setNewPwd2('');
      setPwdMsg({ ok: true, text: 'Hasło zostało zmienione.' });
    } else {
      setPwdMsg({ ok: false, text: res.error });
    }
  };

  const Card = ({ title, children }) =>
    <div style={{
      padding: 32, borderRadius: 16,
      border: `1px solid ${AC.muted}`,
      background: 'rgba(21,19,49,0.45)',
      display: 'flex', flexDirection: 'column', gap: 18
    }}>
      <h2 style={{
        margin: 0, fontFamily: 'Playfair Display', fontWeight: 400, fontSize: 26,
        color: AC.white, letterSpacing: '-0.022em'
      }}>{title}</h2>
      {children}
    </div>;

  const Label = ({ children }) =>
    <span style={{
      fontFamily: 'Nunito', fontSize: 13, letterSpacing: '0.1em',
      textTransform: 'uppercase', color: AC.muted, fontWeight: 600
    }}>{children}</span>;

  return (
    <section style={{
      position: 'relative', background: AC.bg,
      padding: '160px 24px 100px', overflow: 'hidden'
    }}>
      <div style={{ maxWidth: 760, margin: '0 auto' }}>
        <div style={{ textAlign: 'center', marginBottom: 48 }}>
          <div style={{
            fontFamily: 'Nunito', fontWeight: 700, fontSize: 14,
            letterSpacing: '0.2em', color: AC.muted, marginBottom: 16
          }}>MOJE DANE</div>
          <h1 style={{
            margin: 0, fontFamily: 'Playfair Display', fontWeight: 400, fontSize: 44,
            lineHeight: 1.15, letterSpacing: '-0.022em', color: AC.white
          }}>Edytuj dane konta</h1>
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>
          <Card title="Dane podstawowe">
            <form onSubmit={saveProfile} style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
              <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                <Label>Imię</Label>
                <input type="text" value={name} onChange={(e) => setName(e.target.value)} style={inputStyle} />
              </label>
              <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                <Label>Nazwisko</Label>
                <input type="text" value={surname} onChange={(e) => setSurname(e.target.value)} style={inputStyle} />
              </label>
              <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                <Label>Adres e-mail</Label>
                <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} style={inputStyle} />
              </label>
              {profileMsg &&
                <div style={{
                  fontFamily: 'Nunito', fontSize: 14,
                  color: profileMsg.ok ? AC.gold : '#f49b9b'
                }}>{profileMsg.text}</div>
              }
              <div style={{ marginTop: 6 }}>
                <BtnMain>Zapisz zmiany</BtnMain>
              </div>
            </form>
          </Card>

          <Card title="Zmiana hasła">
            <form onSubmit={submitChangePwd} style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
              <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                <Label>Aktualne hasło</Label>
                <input type="password" value={currentPwd} onChange={(e) => setCurrentPwd(e.target.value)} style={inputStyle} autoComplete="current-password" />
              </label>
              <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                <Label>Nowe hasło (min. 8 znaków)</Label>
                <input type="password" value={newPwd} onChange={(e) => setNewPwd(e.target.value)} style={inputStyle} autoComplete="new-password" />
              </label>
              <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                <Label>Powtórz nowe hasło</Label>
                <input type="password" value={newPwd2} onChange={(e) => setNewPwd2(e.target.value)} style={inputStyle} autoComplete="new-password" />
              </label>
              {pwdMsg &&
                <div style={{
                  fontFamily: 'Nunito', fontSize: 14,
                  color: pwdMsg.ok ? AC.gold : '#f49b9b'
                }}>{pwdMsg.text}</div>
              }
              <div style={{ marginTop: 6 }}>
                <BtnMain>Zmień hasło</BtnMain>
              </div>
            </form>
          </Card>
        </div>
      </div>
    </section>);
}

// ─────────────────────────────────────────────────────────────
// HistoryPage — real orders from /api/orders
// ─────────────────────────────────────────────────────────────
function _formatDate(iso) {
  if (!iso) return '';
  const d = new Date(iso);
  const dd = String(d.getDate()).padStart(2, '0');
  const mm = String(d.getMonth() + 1).padStart(2, '0');
  return `${dd}.${mm}.${d.getFullYear()}`;
}
function _shortOrderId(uuid) {
  if (!uuid) return '';
  return 'LP-' + String(uuid).slice(0, 8).toUpperCase();
}

function HistoryPage() {
  const user = useCurrentUser();
  const [orders, setOrders] = React.useState(null);
  const [error, setError] = React.useState('');

  React.useEffect(() => {
    if (user === null) { window.location.href = 'login.html'; return; }
    if (!user) return;
    fetchOrders().then(setOrders).catch((e) => setError(e.message));
  }, [user && user.email]);

  if (!user) return null;

  return (
    <section style={{
      position: 'relative', background: AC.bg,
      padding: '160px 24px 100px', overflow: 'hidden'
    }}>
      <div style={{ maxWidth: 1000, margin: '0 auto' }}>
        <div style={{ textAlign: 'center', marginBottom: 48 }}>
          <div style={{
            fontFamily: 'Nunito', fontWeight: 700, fontSize: 14,
            letterSpacing: '0.2em', color: AC.muted, marginBottom: 16
          }}>HISTORIA ZAKUPÓW</div>
          <h1 style={{
            margin: 0, fontFamily: 'Playfair Display', fontWeight: 400, fontSize: 44,
            lineHeight: 1.15, letterSpacing: '-0.022em', color: AC.white
          }}>Twoje zamówienia</h1>
          <p style={{
            margin: '16px 0 0', fontFamily: 'Nunito', fontSize: 16, lineHeight: 1.6,
            color: AC.lavender
          }}>Lista wszystkich konsultacji i usług, które do tej pory zamówiłaś / zamówiłeś.</p>
        </div>

        {error && <div style={{ color: '#f49b9b', textAlign: 'center', marginBottom: 24 }}>{error}</div>}

        {orders === null ? (
          <div style={{ textAlign: 'center', color: AC.lavender, fontFamily: 'Nunito' }}>Wczytywanie...</div>
        ) : orders.length === 0 ? (
          <div style={{
            padding: '60px 24px', textAlign: 'center',
            border: `1px dashed ${AC.muted}`, borderRadius: 16
          }}>
            <p style={{ margin: 0, fontFamily: 'Nunito', fontSize: 15, color: AC.lavender }}>
              Nie masz jeszcze żadnych zamówień. <a href="index.html#uslugi" style={{ color: AC.gold }}>Zobacz nasze usługi</a>.
            </p>
          </div>
        ) : (
          <div style={{
            border: `1px solid ${AC.muted}`, borderRadius: 16,
            background: 'rgba(21,19,49,0.45)', overflow: 'hidden'
          }}>
            <div style={{
              display: 'grid',
              gridTemplateColumns: '1fr 1.4fr 1.4fr 1fr 1fr',
              padding: '16px 24px',
              borderBottom: `1px solid ${AC.muted}`,
              fontFamily: 'Nunito', fontSize: 12, letterSpacing: '0.15em',
              color: AC.muted, textTransform: 'uppercase', fontWeight: 600
            }}>
              <div>Nr zamówienia</div>
              <div>Usługi</div>
              <div>Status</div>
              <div>Data</div>
              <div style={{ textAlign: 'right' }}>Kwota</div>
            </div>
            {orders.map((o, i) => {
              const itemsArr = Array.isArray(o.items) ? o.items : [];
              const services = itemsArr.map((it) => it.service || it.title || it.id).filter(Boolean).join(', ');
              return (
                <div key={o.id} style={{
                  display: 'grid',
                  gridTemplateColumns: '1fr 1.4fr 1.4fr 1fr 1fr',
                  padding: '20px 24px',
                  borderBottom: i < orders.length - 1 ? `1px solid ${AC.muted}` : 'none',
                  fontFamily: 'Nunito', fontSize: 15,
                  color: AC.lavender, alignItems: 'center'
                }}>
                  <div style={{ color: AC.muted, fontSize: 13 }}>{_shortOrderId(o.id)}</div>
                  <div style={{ color: AC.white }}>{services || '—'}</div>
                  <div>{o.status}</div>
                  <div>{_formatDate(o.created_at)}</div>
                  <div style={{ textAlign: 'right', color: AC.gold, fontWeight: 600 }}>
                    {((o.total_cents || 0) / 100).toFixed(2)} zł
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>
    </section>);
}

// ─────────────────────────────────────────────────────────────
// CartPage — DB-backed cart with checkout that creates an order
// ─────────────────────────────────────────────────────────────
function CartPage() {
  const user = useCurrentUser();
  const [items, setItems] = React.useState(null);
  const [error, setError] = React.useState('');
  const [checkoutMsg, setCheckoutMsg] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const [successOrder, setSuccessOrder] = React.useState(null);

  // Show post-Stripe return status. /koszyk.html?status=success means user finished payment;
  // ?status=cancel means they backed out. Order status flips via webhook, not here.
  React.useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const status = params.get('status');
    if (status === 'success') {
      const orderId = params.get('order');
      setItems([]);
      window.history.replaceState({}, '', 'koszyk.html');
      if (orderId) {
        fetch(`/api/orders?id=${orderId}`, { credentials: 'include' })
          .then(r => r.json())
          .then(data => { if (data.order) setSuccessOrder(data.order); })
          .catch(() => {});
      }
    } else if (status === 'cancel') {
      setError('Płatność nie została zrealizowana. Koszyk pozostał nietknięty — możesz spróbować ponownie.');
      window.history.replaceState({}, '', 'koszyk.html');
    }
  }, []);

  React.useEffect(() => {
    if (user === null) { window.location.href = 'login.html'; return; }
    if (!user) return;
    fetchCart().then(setItems).catch((e) => setError(e.message));
  }, [user && user.email]);

  if (!user) return null;

  if (successOrder) {
    const orderItems = successOrder.items || [];
    const totalPLN = Math.round((successOrder.total_cents || 0) / 100);
    return (
      <section style={{ position: 'relative', background: AC.bg, padding: '160px 24px 100px', overflow: 'hidden' }}>
        <div style={{ maxWidth: 640, margin: '0 auto', textAlign: 'center' }}>
          <div style={{ width: 64, height: 64, borderRadius: '50%', background: 'rgba(124,58,237,0.18)', display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 24px', fontSize: 28 }}>✓</div>
          <div style={{ fontFamily: 'Nunito', fontWeight: 700, fontSize: 14, letterSpacing: '0.2em', color: AC.muted, marginBottom: 16 }}>ZAMÓWIENIE PRZYJĘTE</div>
          <h1 style={{ margin: '0 0 16px', fontFamily: 'Playfair Display', fontWeight: 400, fontSize: 40, lineHeight: 1.15, color: AC.white }}>Dziękujemy!</h1>
          <p style={{ margin: '0 0 40px', fontFamily: 'Nunito', fontSize: 16, lineHeight: 1.6, color: AC.lavender }}>
            Twoje zamówienie zostało przyjęte. Potwierdzenie zostało wysłane na Twój adres e-mail.
          </p>
          <div style={{ border: `1px solid ${AC.muted}`, borderRadius: 16, background: 'rgba(21,19,49,0.45)', overflow: 'hidden', marginBottom: 32, textAlign: 'left' }}>
            {orderItems.map((it, i) => (
              <div key={i} style={{ display: 'grid', gridTemplateColumns: '1fr auto', padding: '20px 24px', borderBottom: i < orderItems.length - 1 ? `1px solid ${AC.muted}` : 'none', fontFamily: 'Nunito', gap: 12, alignItems: 'center' }}>
                <div>
                  <div style={{ color: AC.white, fontWeight: 600, fontSize: 16, marginBottom: 4 }}>{it.service || it.id}</div>
                  {it.expert && <div style={{ color: AC.lavender, fontSize: 14 }}>{it.expert}</div>}
                </div>
                <div style={{ color: AC.gold, fontWeight: 700, fontSize: 16, whiteSpace: 'nowrap' }}>{it.price} zł</div>
              </div>
            ))}
            <div style={{ padding: '20px 24px', background: 'rgba(6,11,24,0.5)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
              <span style={{ fontFamily: 'Nunito', fontSize: 13, letterSpacing: '0.15em', color: AC.muted, textTransform: 'uppercase' }}>Razem</span>
              <span style={{ fontFamily: 'Playfair Display', fontSize: 28, color: AC.gold, fontWeight: 400 }}>{totalPLN} zł</span>
            </div>
          </div>
          <div style={{ display: 'flex', gap: 12, justifyContent: 'center', flexWrap: 'wrap' }}>
            <BtnMain href="historia-zakupow.html">Historia zamówień</BtnMain>
            <a href="index.html#uslugi" style={{ display: 'inline-flex', alignItems: 'center', gap: 8, padding: '14px 28px', borderRadius: 100, border: `1px solid ${AC.muted}`, fontFamily: 'Nunito', fontWeight: 700, fontSize: 15, color: AC.lavender, textDecoration: 'none' }}>Wróć do sklepu</a>
          </div>
        </div>
      </section>
    );
  }

  const removeItem = async (idx) => {
    const next = items.slice(); next.splice(idx, 1);
    setItems(next);
    try { await saveCart(next); } catch (e) { setError(e.message); }
  };

  const doCheckout = async () => {
    setBusy(true); setError('');
    const res = await checkout();
    if (!res.ok) {
      setBusy(false);
      setError(res.error);
    }
    // Jeśli ok: checkout() już przekierowało do Stripe — nie dotykamy stanu
  };

  const total = (items || []).reduce((s, it) => s + (Number(it.price) || 0) * (it.qty || 1), 0);

  return (
    <section style={{
      position: 'relative', background: AC.bg,
      padding: '160px 24px 100px', overflow: 'hidden'
    }}>
      <div style={{ maxWidth: 960, margin: '0 auto' }}>
        <div style={{ textAlign: 'center', marginBottom: 48 }}>
          <div style={{
            fontFamily: 'Nunito', fontWeight: 700, fontSize: 14,
            letterSpacing: '0.2em', color: AC.muted, marginBottom: 16
          }}>KOSZYK</div>
          <h1 style={{
            margin: 0, fontFamily: 'Playfair Display', fontWeight: 400, fontSize: 44,
            lineHeight: 1.15, letterSpacing: '-0.022em', color: AC.white
          }}>Twój koszyk</h1>
          <p style={{
            margin: '16px 0 0', fontFamily: 'Nunito', fontSize: 16, lineHeight: 1.6,
            color: AC.lavender
          }}>Usługi, które wybrałaś / wybrałeś. Możesz je usunąć lub przejść do podsumowania zamówienia.</p>
        </div>

        {error && <div style={{ color: '#f49b9b', textAlign: 'center', marginBottom: 16 }}>{error}</div>}
        {checkoutMsg && <div style={{ color: AC.gold, textAlign: 'center', marginBottom: 24, fontFamily: 'Nunito' }}>{checkoutMsg}</div>}

        {items === null ? (
          <div style={{ textAlign: 'center', color: AC.lavender, fontFamily: 'Nunito' }}>Wczytywanie...</div>
        ) : items.length === 0 ? (
          <div style={{
            padding: '60px 24px', textAlign: 'center',
            border: `1px dashed ${AC.muted}`, borderRadius: 16
          }}>
            <p style={{ margin: '0 0 16px', fontFamily: 'Nunito', fontSize: 15, color: AC.lavender }}>
              Twój koszyk jest pusty.
            </p>
            <BtnMain href="index.html#uslugi">Zobacz nasze usługi</BtnMain>
          </div>
        ) : (
          <div style={{
            border: `1px solid ${AC.muted}`, borderRadius: 16,
            background: 'rgba(21,19,49,0.45)', overflow: 'hidden'
          }}>
            {items.map((it, i) =>
              <div key={i} style={{
                display: 'grid',
                gridTemplateColumns: '1.5fr 1.5fr 1fr auto',
                padding: '20px 24px',
                borderBottom: i < items.length - 1 ? `1px solid ${AC.muted}` : 'none',
                fontFamily: 'Nunito', fontSize: 15,
                color: AC.lavender, alignItems: 'center', gap: 16
              }}>
                <div style={{ color: AC.white, fontWeight: 500 }}>{it.service}</div>
                <div>{it.expert}</div>
                <div style={{ textAlign: 'right', color: AC.gold, fontWeight: 600 }}>{it.price} zł</div>
                <button onClick={() => removeItem(i)} aria-label="Usuń z koszyka" style={{
                  background: 'none', border: `1px solid ${AC.muted}`, borderRadius: 8,
                  width: 36, height: 36, cursor: 'pointer',
                  color: AC.lavender, fontSize: 16, lineHeight: 1,
                  transition: 'border-color .2s, color .2s'
                }}
                onMouseEnter={(e) => { e.currentTarget.style.borderColor = AC.gold; e.currentTarget.style.color = AC.gold; }}
                onMouseLeave={(e) => { e.currentTarget.style.borderColor = AC.muted; e.currentTarget.style.color = AC.lavender; }}>×</button>
              </div>
            )}
            <div style={{
              padding: '24px',
              display: 'flex', justifyContent: 'space-between', alignItems: 'center',
              flexWrap: 'wrap', gap: 16,
              background: 'rgba(6,11,24,0.5)'
            }}>
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 12 }}>
                <span style={{
                  fontFamily: 'Nunito', fontSize: 13, letterSpacing: '0.15em',
                  color: AC.muted, textTransform: 'uppercase'
                }}>Razem</span>
                <span style={{
                  fontFamily: 'Playfair Display', fontSize: 32, color: AC.gold, fontWeight: 400
                }}>{total} zł</span>
              </div>
              <BtnMain disabled={busy} onClick={doCheckout}>{busy ? '...' : 'Przejdź do płatności'}</BtnMain>
            </div>
          </div>
        )}
      </div>
    </section>);
}

Object.assign(window, {
  LoginPage, AccountPage, AccountMenuLink,
  MyDataPage, HistoryPage, CartPage,
  getCurrentUser, useCurrentUser,
  loginUser, registerUser, logoutUser,
  updateProfile, changePassword,
  fetchOrders, fetchCart, saveCart, checkout
});
