/* ============================================================
   Төрмен — Medusa Auth (Customer + emailpass)
   JWT в localStorage · Store API · phone OTP — позже
   ============================================================ */
const { createContext:createCtxAU, useContext:useCtxAU, useState:useStateAU, useEffect:useEffectAU, useCallback:useCbAU, useRef:useRefAU } = React;

const TOKEN_KEY = 'tormen_medusa_token';

function medusaEnv(){
  return window.TORMEN_ENV?.medusa || {};
}

function getToken(){ return localStorage.getItem(TOKEN_KEY) || ''; }
function setToken(t){ if(t) localStorage.setItem(TOKEN_KEY, t); else localStorage.removeItem(TOKEN_KEY); }

async function medusaFetch(path, { method='GET', body, auth=true }={}){
  const { backendUrl, publishableKey } = medusaEnv();
  const headers = {
    'Content-Type': 'application/json',
    'x-publishable-api-key': publishableKey,
  };
  if(auth){
    const token = getToken();
    if(token) headers.Authorization = `Bearer ${token}`;
  }
  const ctrl = new AbortController();
  const timer = setTimeout(()=> ctrl.abort(), 12000);
  let res;
  try{
    res = await fetch(`${backendUrl}${path}`, {
      method,
      headers,
      body: body != null ? JSON.stringify(body) : undefined,
      signal: ctrl.signal,
    });
  }finally{ clearTimeout(timer); }
  let data = {};
  try{ data = await res.json(); }catch(_){}
  if(!res.ok){
    const err = new Error(data.message || data.type || res.statusText || 'request_failed');
    err.status = res.status;
    err.data = data;
    throw err;
  }
  return data;
}

/* ---------- phone helpers (KZ) — для checkout / будущего OTP ---------- */
function digitsOnly(s){ return String(s||'').replace(/\D/g,''); }
function formatKzPhone(input){
  const d = digitsOnly(input);
  if(d.length === 11 && d[0] === '7') return '+' + d;
  if(d.length === 11 && d[0] === '8') return '+7' + d.slice(1);
  if(d.length === 10) return '+7' + d;
  return null;
}
function displayPhone(e164){
  const d = digitsOnly(e164);
  if(d.length !== 11) return e164 || '';
  return `+7 (${d.slice(1,4)}) ${d.slice(4,7)}-${d.slice(7,9)}-${d.slice(9,11)}`;
}

function splitName(full){
  const p = String(full||'').trim().split(/\s+/).filter(Boolean);
  return { first: p[0] || '', last: p.slice(1).join(' ') || '' };
}

/** Имя из БД без мусора (????, replacement char) */
function cleanName(s){
  const t = String(s||'').trim();
  if(!t) return '';
  if(/^[\?\uFFFD\uFFFE\uFFFF]+$/.test(t)) return '';
  if(/\?{2,}/.test(t)) return '';
  return t;
}

function resolveDisplayName(profile, user){
  const name = cleanName(profile?.full_name);
  if(name) return name;
  if(user?.phone) return displayPhone(user.phone);
  const email = user?.email;
  if(email){
    const local = email.split('@')[0];
    return local || email;
  }
  return '';
}

function customerToState(customer){
  if(!customer) return { customer:null, user:null, profile:null };
  const meta = customer.metadata || {};
  const first = cleanName(customer.first_name);
  const last = cleanName(customer.last_name);
  const fullName = [first, last].filter(Boolean).join(' ').trim();
  const user = { id:customer.id, email:customer.email, phone:customer.phone };
  const profile = {
    id: customer.id,
    full_name: fullName,
    phone: customer.phone,
    role: 'customer',
    bonus_points: meta.bonus_points || 0,
    telegram_linked: !!meta.telegram_linked,
    city_id: meta.city_id || 'almaty',
  };
  return { customer, user, profile };
}

function userInitial(profile, user, fallback){
  const name = cleanName(profile?.full_name);
  if(name) return [...name][0]?.toUpperCase() || '?';
  const phone = user?.phone || profile?.phone;
  if(phone) return digitsOnly(phone).slice(-1) || '?';
  const email = user?.email;
  if(email) return email[0].toUpperCase();
  return fallback || '?';
}

/* ---------- auth context ---------- */
const AuthContext = createCtxAU(null);

function AuthProvider({ children }){
  const [customer, setCustomer] = useStateAU(null);
  const [user, setUser] = useStateAU(null);
  const [profile, setProfile] = useStateAU(null);
  const [loading, setLoading] = useStateAU(true);
  const [configured] = useStateAU(()=> !!window.isMedusaConfigured?.());
  const booted = useRefAU(false);

  const applyCustomer = useCbAU((c)=>{
    const st = customerToState(c);
    setCustomer(st.customer);
    setUser(st.user);
    setProfile(st.profile);
    return st;
  }, []);

  const loadCustomer = useCbAU(async ()=>{
    if(!getToken()){ applyCustomer(null); return null; }
    try{
      const { customer:c } = await medusaFetch('/store/customers/me');
      applyCustomer(c);
      return c;
    }catch(e){
      if(e.status === 401){ setToken(''); applyCustomer(null); }
      else console.warn('[auth] customer:', e.message);
      applyCustomer(null);
      return null;
    }
  }, [applyCustomer]);

  useEffectAU(()=>{
    if(!configured){ setLoading(false); return; }
    if(booted.current) return;
    booted.current = true;
    loadCustomer().finally(()=> setLoading(false));
  }, [configured, loadCustomer]);

  const registerWithEmail = useCbAU(async (email, password, fullName='')=>{
    const e = String(email||'').trim().toLowerCase();
    if(!e.includes('@')) throw new Error('invalid_email');
    if(!password || password.length < 8) throw new Error('invalid_password');
    try{
      const { token } = await medusaFetch('/auth/customer/emailpass/register', {
        method:'POST', body:{ email:e, password }, auth:false,
      });
      setToken(token);
    }catch(err){
      if(err.status === 401 && /already exists/i.test(err.message || '')){
        const { token } = await medusaFetch('/auth/customer/emailpass', {
          method:'POST', body:{ email:e, password }, auth:false,
        });
        setToken(token);
      } else throw err;
    }
    const { first, last } = splitName(fullName);
    try{
      await medusaFetch('/store/customers', {
        method:'POST',
        body:{ email:e, first_name:first || undefined, last_name:last || undefined },
      });
    }catch(err){
      if(err.status !== 400) throw err;
    }
    return loadCustomer();
  }, [loadCustomer]);

  const loginWithEmail = useCbAU(async (email, password)=>{
    const e = String(email||'').trim().toLowerCase();
    if(!e.includes('@')) throw new Error('invalid_email');
    if(!password) throw new Error('invalid_password');
    const { token } = await medusaFetch('/auth/customer/emailpass', {
      method:'POST', body:{ email:e, password }, auth:false,
    });
    setToken(token);
    let c = await loadCustomer();
    if(!c){
      try{
        await medusaFetch('/store/customers', { method:'POST', body:{ email:e } });
        c = await loadCustomer();
      }catch(_){}
    }
    if(!c) throw new Error('no_customer');
    return c;
  }, [loadCustomer]);

  const updateProfile = useCbAU(async (patch)=>{
    if(!getToken()) throw new Error('not_authenticated');
    const body = {};
    if(patch.full_name != null){
      const { first, last } = splitName(patch.full_name);
      body.first_name = first;
      body.last_name = last;
    }
    const meta = { ...(customer?.metadata || {}) };
    if(patch.telegram_linked != null) meta.telegram_linked = !!patch.telegram_linked;
    if(patch.bonus_points != null) meta.bonus_points = patch.bonus_points;
    if(Object.keys(meta).length) body.metadata = meta;
    const { customer:c } = await medusaFetch('/store/customers/me', { method:'POST', body });
    applyCustomer(c);
    return c;
  }, [customer, applyCustomer]);

  const signOut = useCbAU(async ()=>{
    setToken('');
    setCustomer(null); setUser(null); setProfile(null);
  }, []);

  const role = profile?.role || 'customer';
  const value = {
    customer, user, profile, loading, configured,
    session: getToken() ? { token:getToken() } : null,
    role,
    isCustomer: true,
    isStaff: false,
    isAdmin: false,
    registerWithEmail, loginWithEmail,
    updateProfile, signOut, loadCustomer,
    displayName: resolveDisplayName(profile, user),
    initial: userInitial(profile, user),
  };
  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}

function useAuth(){ return useCtxAU(AuthContext); }

/* ---------- auth field ---------- */
function AuthField({ icon, value, onChange, placeholder, type, inputMode, maxLength, autoFocus }){
  return (
    <div className="relative">
      {icon && <Icon name={icon} size={16} className="absolute left-4 top-1/2 -translate-y-1/2" style={{ color:'var(--ink-3)' }} />}
      <input value={value} onChange={e=>onChange(e.target.value)} placeholder={placeholder}
        type={type||'text'} inputMode={inputMode} maxLength={maxLength} autoFocus={autoFocus}
        className="w-full rounded-2xl py-3.5 text-sm outline-none transition-all"
        style={{
          background:'var(--surface-1)', border:'1px solid var(--border)', color:'var(--ink)',
          paddingLeft: icon ? 44 : 16, paddingRight: 16,
        }}
        onFocus={e=>e.target.style.borderColor='var(--ember)'}
        onBlur={e=>e.target.style.borderColor='var(--border)'} />
    </div>
  );
}

/* ---------- setup notice ---------- */
function MedusaSetupNotice({ lang }){
  const L = (ru,kz)=> lang==='kz' ? kz : ru;
  return (
    <div className="max-w-lg mx-auto px-5 pt-28 pb-32 text-center">
      <div className="mx-auto mb-6 grid place-items-center rounded-full" style={{ width:80, height:80, background:'var(--surface-1)', border:'1px solid var(--border)' }}>
        <Icon name="server" size={32} style={{ color:'var(--gold)' }} />
      </div>
      <div className="eyebrow mb-3">Medusa</div>
      <h1 className="serif-title text-2xl md:text-3xl mb-4">{L('Подключите Medusa','Medusa қосыңыз')}</h1>
      <p className="text-sm leading-relaxed mb-6" style={{ color:'var(--ink-2)' }}>
        {L('Запустите бэкенд:','Бэкендті іске қосыңыз:')}{' '}
        <code className="text-xs px-1.5 py-0.5 rounded" style={{ background:'var(--surface-2)' }}>npm run infra:up</code>
        {' '}{L('и','және')}{' '}
        <code className="text-xs px-1.5 py-0.5 rounded" style={{ background:'var(--surface-2)' }}>npm run medusa:dev</code>.
        {L(' Затем укажите в',' Содан кейін')}{' '}
        <code className="text-xs px-1.5 py-0.5 rounded" style={{ background:'var(--surface-2)' }}>.env</code>
        {L(' ключи MEDUSA_BACKEND_URL и MEDUSA_PUBLISHABLE_KEY (из админки → Settings).',' MEDUSA_BACKEND_URL мен MEDUSA_PUBLISHABLE_KEY қойыңыз (админка → Settings).')}
      </p>
      <p className="text-xs" style={{ color:'var(--ink-3)' }}>npm run config</p>
    </div>
  );
}

/* ---------- login screen ---------- */
function AuthScreen({ go, redirectTo='profile' }){
  const { t, lang } = useLang();
  const { configured, loginWithEmail, registerWithEmail, user } = useAuth();
  const L = (ru,kz)=> lang==='kz' ? kz : ru;

  const [intent, setIntent] = useStateAU('login'); // login | register
  const [email, setEmail] = useStateAU('');
  const [password, setPassword] = useStateAU('');
  const [name, setName] = useStateAU('');
  const [busy, setBusy] = useStateAU(false);
  const [err, setErr] = useStateAU('');

  useEffectAU(()=>{
    if(user) go(redirectTo);
  }, [user, go, redirectTo]);

  if(!configured) return <MedusaSetupNotice lang={lang} />;

  const mapError = (e)=>{
    const m = (e?.message || e || '').toLowerCase();
    if(m.includes('invalid_email')) return t('auth_err_email');
    if(m.includes('invalid_password')) return t('auth_err_password');
    if(m.includes('unauthorized') || m.includes('invalid') || m.includes('no_customer')) return t('auth_err_credentials');
    if(m.includes('not_configured')) return t('auth_err_config');
    if(m.includes('fetch') || m.includes('network') || m.includes('failed to fetch')) return t('auth_err_offline');
    return t('auth_err_generic');
  };

  const submit = async ()=>{
    setErr(''); setBusy(true);
    try{
      if(intent === 'register') await registerWithEmail(email, password, name);
      else await loginWithEmail(email, password);
      go(redirectTo);
    }catch(e){ setErr(mapError(e)); }
    finally{ setBusy(false); }
  };

  return (
    <div className="max-w-md mx-auto px-5 pt-24 md:pt-28 pb-36">
      <button onClick={()=>go('home')} className="inline-flex items-center gap-2 text-sm mb-6" style={{ color:'var(--ink-2)' }}>
        <Icon name="arrow-left" size={16} />{t('back')}
      </button>

      <Reveal>
        <div className="eyebrow mb-3">{t('auth_eyebrow')}</div>
        <h1 className="display text-3xl md:text-4xl mb-2">
          <span className="grad-text">{intent==='register' ? t('auth_register_title') : t('auth_title')}</span>
        </h1>
        <p className="text-sm mb-8" style={{ color:'var(--ink-2)' }}>
          {intent==='register' ? t('auth_register_sub') : t('auth_sub')}
        </p>
      </Reveal>

      <Reveal delay={60}>
        <div className="flex gap-1 p-1 rounded-full mb-6" style={{ background:'var(--surface-2)', border:'1px solid var(--border)' }}>
          <button type="button" className="flex-1 rounded-full py-2 text-xs font-semibold"
            style={{ background:'var(--ember)', color:'var(--on-accent)' }}>
            <span className="inline-flex items-center gap-1.5 justify-center"><Icon name="mail" size={13} stroke={2} />{t('auth_email')}</span>
          </button>
          <button type="button" disabled className="flex-1 rounded-full py-2 text-xs font-semibold opacity-45 cursor-not-allowed"
            style={{ color:'var(--ink-3)' }}>
            <span className="inline-flex items-center gap-1.5 justify-center"><Icon name="smartphone" size={13} stroke={2} />{t('auth_phone_soon')}</span>
          </button>
        </div>

        <div className="space-y-3 mb-4">
          <AuthField icon="mail" value={email} onChange={setEmail}
            placeholder="name@example.com" type="email" inputMode="email" autoFocus />
          <AuthField icon="key-round" value={password} onChange={setPassword}
            placeholder={t('auth_password_ph')} type="password" />
          {intent==='register' && (
            <AuthField icon="user" value={name} onChange={setName}
              placeholder={t('auth_name_ph')} />
          )}
        </div>
        <p className="text-xs mb-4" style={{ color:'var(--ink-3)' }}>
          {intent==='register' ? t('auth_password_hint') : t('auth_email_hint')}
        </p>

        {err && <p className="text-sm mb-4" style={{ color:'var(--ember)' }}>{err}</p>}

        <button type="button" className="btn btn-primary w-full" disabled={busy || !email || !password} onClick={submit}>
          <span className="shine"></span>
          {busy ? t('auth_verifying') : (intent==='register' ? t('auth_register_btn') : t('auth_login_btn'))}
          {!busy && <Icon name="arrow-right" size={17} />}
        </button>

        <button type="button" className="w-full mt-4 text-sm font-medium py-2"
          style={{ color:'var(--ink-2)', background:'none', border:0, cursor:'pointer' }}
          onClick={()=>{ setIntent(intent==='login' ? 'register' : 'login'); setErr(''); }}>
          {intent==='login' ? t('auth_switch_register') : t('auth_switch_login')}
        </button>

        <p className="text-xs text-center mt-4 leading-relaxed" style={{ color:'var(--ink-3)' }}>{t('auth_guest_note')}</p>
        <button type="button" className="text-sm mx-auto mt-3 inline-flex items-center gap-2" style={{ color:'var(--gold)', background:'none', border:0, cursor:'pointer' }}
          onClick={()=>go('track')}>
          <Icon name="truck" size={15} />{t('nav_track')}
        </button>
      </Reveal>
    </div>
  );
}

Object.assign(window, {
  AuthProvider, useAuth, AuthScreen, MedusaSetupNotice,
  formatKzPhone, displayPhone, userInitial, cleanName, resolveDisplayName,
  medusaFetch, getToken, setToken,
});