/* ============================================================
   Төрмен — Medusa Orders (cart → complete → history)
   ============================================================ */
const { createContext:createCtxOR, useContext:useCtxOR, useState:useStateOR, useEffect:useEffectOR, useCallback:useCbOR } = React;

const LAST_ORDER_KEY = 'tormen_last_order_id';
const TRACK_ORDER_KEY = 'tormen_track_order_id';
const TRACK_TOKENS_KEY = 'tormen_track_tokens';

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

async function ordersFetch(path, { method='GET', body, auth=false }={}){
  const { backendUrl, publishableKey } = ordersEnv();
  const headers = {
    'Content-Type': 'application/json',
    'x-publishable-api-key': publishableKey,
  };
  if(auth){
    const token = window.getToken?.() || '';
    if(token) headers.Authorization = `Bearer ${token}`;
  }
  const res = await fetch(`${backendUrl}${path}`, {
    method,
    headers,
    body: body != null ? JSON.stringify(body) : undefined,
  });
  let data = {};
  try{ data = await res.json(); }catch(_){}
  if(!res.ok){
    const err = new Error(data.message || data.type || res.statusText || 'orders_failed');
    err.status = res.status;
    err.data = data;
    throw err;
  }
  return data;
}

async function resolveKzRegionId(){
  const { regions } = await ordersFetch('/store/regions?limit=20');
  const kz = (regions || []).find(r=> r.currency_code === 'kzt')
    || (regions || []).find(r=> (r.countries || []).some(c=> c.iso_2 === 'kz'));
  if(!kz) throw new Error('no_kz_region');
  return kz.id;
}

function guestEmail(phone){
  const d = window.digitsOnly?.(phone) || String(phone||'').replace(/\D/g,'');
  return d ? `guest+${d}@tormen.kz` : '';
}

function resolveOrderEmail({ formEmail, phone, userEmail }){
  if(userEmail) return String(userEmail).trim().toLowerCase();
  const e = String(formEmail||'').trim().toLowerCase();
  if(e && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)) return e;
  return guestEmail(phone);
}

function buildTelegramTrackLink(displayId, token){
  const user = (window.TORMEN_ENV?.telegram?.botUsername || 'tormen_bot').replace(/^@/, '');
  const payload = `track_${displayId}_${token}`.slice(0, 64);
  return `https://t.me/${user}?start=${payload}`;
}

function generateTrackToken(){
  if(typeof crypto !== 'undefined' && crypto.randomUUID){
    return crypto.randomUUID().replace(/-/g, '');
  }
  return Math.random().toString(36).slice(2) + Date.now().toString(36);
}

function readTrackTokens(){
  try{ return JSON.parse(localStorage.getItem(TRACK_TOKENS_KEY) || '{}'); }catch(_){ return {}; }
}
function writeTrackTokens(map){
  try{ localStorage.setItem(TRACK_TOKENS_KEY, JSON.stringify(map)); }catch(_){}
}

function saveTrackCredentials({ orderId, displayId, token }){
  if(orderId) setTrackOrderId(orderId);
  if(orderId) setLastOrderId(orderId);
  if(!token) return;
  const map = readTrackTokens();
  if(orderId) map[orderId] = token;
  if(displayId) map['d:'+displayId] = token;
  writeTrackTokens(map);
}

function getSavedTrackToken({ orderId, displayId }){
  const map = readTrackTokens();
  if(orderId && map[orderId]) return map[orderId];
  if(displayId && map['d:'+displayId]) return map['d:'+displayId];
  return '';
}

function buildOrderTrackUrl(displayId, token){
  const base = `${location.origin}${location.pathname}`;
  const id = encodeURIComponent(String(displayId ?? ''));
  const hash = token ? `order/${id}?t=${encodeURIComponent(token)}` : `order/${id}`;
  return `${base}#${hash}`;
}

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

function mapOrderStatus(order){
  const fs = order.fulfillment_status || '';
  const st = order.status || '';
  if(st === 'canceled' || st === 'cancelled') return 'cancelled';
  if(fs === 'fulfilled' || fs === 'shipped' || fs === 'delivered' || fs === 'partially_delivered') return 'done';
  if(fs === 'partially_fulfilled' || fs === 'partially_shipped') return 'way';
  return 'cook';
}

function orderDeliveryStatus(order){
  const ds = order?.metadata?.delivery_status;
  if(ds) return ds;
  const fs = order?.fulfillment_status || '';
  const st = order?.status || '';
  if(st === 'canceled' || st === 'cancelled') return 'cancelled';
  if(fs === 'delivered' || fs === 'fulfilled') return 'delivered';
  if(fs === 'shipped' || fs === 'partially_delivered' || fs === 'partially_shipped') return 'shipping';
  if(fs === 'partially_fulfilled') return 'processing';
  return 'created';
}

function orderTrackStepIndex(order){
  const ds = orderDeliveryStatus(order);
  if(ds === 'cancelled') return -1;
  if(ds === 'delivered') return 3;
  if(ds === 'shipping') return 2;
  if(ds === 'processing') return 1;
  return 0;
}

function orderTrackSteps(order){
  const pickup = order?.metadata?.delivery_mode === 'pickup';
  if(!pickup) return window.TRACK_STEPS_DEFAULT || [];
  return [
    { ic:'clipboard-check', ru:'Принят', kz:'Қабылданды', subRu:'Заказ подтверждён', subKz:'Тапсырыс расталды' },
    { ic:'package', ru:'Готовим', kz:'Дайындауда', subRu:'Собираем ваш заказ', subKz:'Тапсырысты жинаймыз' },
    { ic:'store', ru:'Готов к выдаче', kz:'Алуға дайын', subRu:'Можно забрать в точке', subKz:'Нүктеден алуға болады' },
    { ic:'home', ru:'Выдан', kz:'Берілді', subRu:'Заказ получен', subKz:'Тапсырыс алынды' },
  ];
}

function orderStatusBadge(order, lang){
  const L = (ru,kz)=> lang==='kz'?kz:ru;
  const step = orderTrackStepIndex(order);
  if(step < 0) return { label:L('Отменён','Бас тартылды'), icon:'x-circle', tone:'var(--ink-3)' };
  if(step >= 3) return { label:L('Доставлен','Жеткізілді'), icon:'check-circle', tone:'var(--emerald)' };
  const pickup = order?.metadata?.delivery_mode === 'pickup';
  if(step >= 2) return { label: pickup ? L('Готов к выдаче','Алуға дайын') : L('В доставке','Жеткізуде'), icon: pickup ? 'store' : 'bike', tone:'var(--gold)' };
  if(step >= 1) return { label:L('В обработке','Өңделуде'), icon:'package', tone:'var(--ember)' };
  return { label:L('Создан','Құрылды'), icon:'clipboard-check', tone:'var(--ember)' };
}

async function fetchGuestOrder({ displayId, orderId, phone, token }){
  const body = {};
  if(orderId) body.order_id = orderId;
  else if(displayId != null) body.display_id = Number(displayId);
  else throw new Error('no_order_ref');
  if(token) body.token = token;
  else if(phone) body.phone = phone;
  else throw new Error('no_credentials');

  const data = await ordersFetch('/store/tormen/orders/track', { method:'POST', body });
  return data.order;
}

function formatOrderDate(iso, lang){
  if(!iso) return '';
  const d = new Date(iso);
  const opts = { day:'numeric', month:'long' };
  return d.toLocaleDateString(lang === 'kz' ? 'kk-KZ' : 'ru-RU', opts);
}

function mapMedusaOrder(order, sets, lang){
  const first = order.items?.[0];
  const handle = first?.product_handle;
  const set = (sets || []).find(s=> s.id === handle);
  const persons = parseInt(first?.variant_sku?.match(/-(\d+)p$/)?.[1] || first?.variant_title?.match(/(\d+)/)?.[1] || '0', 10);
  const fallbackName = {
    ru: first?.product_title || 'Заказ',
    kz: first?.product_title || 'Тапсырыс',
  };
  return {
    id: order.id,
    no: String(order.display_id ?? order.id?.slice(-4) ?? ''),
    date: formatOrderDate(order.created_at, lang),
    status: mapOrderStatus(order),
    sum: Math.round(order.total || 0),
    items: set ? [set] : [{ id: handle || order.id, name: fallbackName, ph: 'cut' }],
    persons: persons || undefined,
    raw: order,
  };
}

function buildCheckoutAddress(form, mode, lang){
  if(mode === 'pickup') return window.TORMEN_ENV?.app?.address || 'Самовывоз';
  const v = window.validateKzAddress?.({ city: form.city, district: form.district, street: form.street }, lang);
  if(v?.valid) return window.formatKzAddress?.({ city: v.city, district: v.district, street: form.street, comment: form.comment }, lang) || form.street;
  return [form.district, form.street, form.comment].filter(Boolean).join(', ');
}

async function placeMedusaOrder({ items, form, mode, pay, lang, regionId, userEmail, auth }){
  const medusaItems = items.filter(i=> i.medusaVariantId);
  if(!medusaItems.length) throw new Error('no_medusa_items');
  if(medusaItems.length < items.length) throw new Error('mixed_cart');

  const rid = regionId || await resolveKzRegionId();
  const email = resolveOrderEmail({ formEmail: form.email, phone: form.phone, userEmail });
  if(!email) throw new Error('no_email');
  const trackToken = generateTrackToken();

  const { first, last } = splitCheckoutName(form.name);
  const phone = window.formatKzPhone?.(form.phone) || form.phone;

  const { cart } = await ordersFetch('/store/carts', {
    method:'POST',
    body:{ region_id: rid },
    auth,
  });

  for(const item of medusaItems){
    await ordersFetch(`/store/carts/${cart.id}/line-items`, {
      method:'POST',
      body:{ variant_id: item.medusaVariantId, quantity: item.qty },
      auth,
    });
  }

  const cityRec = window.kzCityById?.(form.city || 'almaty') || { medusaCity: 'Almaty' };
  const addrLine = buildCheckoutAddress(form, mode, lang || 'ru');
  const shippingBody = {
    email,
    metadata: {
      payment_method: pay,
      delivery_mode: mode,
      comment: form.comment || '',
      phone,
      notify_email: email,
      city_id: form.city || 'almaty',
      district: form.district || '',
      street: form.street || '',
      track_token: trackToken,
    },
    shipping_address: {
      first_name: first,
      last_name: last,
      address_1: addrLine,
      city: cityRec.medusaCity || 'Almaty',
      country_code: 'kz',
      phone,
    },
  };
  await ordersFetch(`/store/carts/${cart.id}`, { method:'POST', body: shippingBody, auth });

  const { shipping_options } = await ordersFetch(`/store/shipping-options?cart_id=${cart.id}`, { auth });
  const wantPickup = mode === 'pickup';
  const option = (shipping_options || []).find(o=>
    wantPickup ? (o.type?.code === 'tormen_pickup' || /самовывоз/i.test(o.name||''))
      : (o.type?.code === 'tormen_delivery' || /доставка/i.test(o.name||''))
  ) || shipping_options?.[0];
  if(!option) throw new Error('no_shipping');

  await ordersFetch(`/store/carts/${cart.id}/shipping-methods`, {
    method:'POST',
    body:{ option_id: option.id },
    auth,
  });

  const { payment_providers } = await ordersFetch(`/store/payment-providers?region_id=${rid}`, { auth });
  const provider = payment_providers?.[0];
  if(!provider) throw new Error('no_payment');

  const { payment_collection } = await ordersFetch('/store/payment-collections', {
    method:'POST',
    body:{ cart_id: cart.id },
    auth,
  });
  await ordersFetch(`/store/payment-collections/${payment_collection.id}/payment-sessions`, {
    method:'POST',
    body:{ provider_id: provider.id },
    auth,
  });

  const result = await ordersFetch(`/store/carts/${cart.id}/complete`, { method:'POST', body:{}, auth });
  if(result.type !== 'order' || !result.order) {
    const msg = result.error?.message || result.cart?.errors?.[0]?.message || 'complete_failed';
    throw new Error(msg);
  }
  const order = result.order;
  order._track_token = trackToken;
  return order;
}

/* ---------- orders context (profile history) ---------- */
const OrdersContext = createCtxOR(null);

function OrdersProvider({ children }){
  const { user, loading: authLoading } = useAuth();
  const [orders, setOrders] = useStateOR([]);
  const [loading, setLoading] = useStateOR(false);
  const [source, setSource] = useStateOR('none');
  const configured = !!window.isMedusaConfigured?.();

  const loadOrders = useCbOR(async ()=>{
    if(!configured || !user) {
      setOrders([]);
      setSource('none');
      return [];
    }
    setLoading(true);
    try{
      const { orders: list } = await ordersFetch('/store/orders?limit=20&order=-created_at', { auth:true });
      const sets = window.SETS || [];
      const lang = localStorage.getItem('tormen_lang') || 'ru';
      const mapped = (list || []).map(o=> mapMedusaOrder(o, sets, lang));
      setOrders(mapped);
      setSource('medusa');
      return mapped;
    }catch(e){
      console.warn('[orders] load:', e.message);
      setOrders([]);
      setSource('error');
      return [];
    }finally{
      setLoading(false);
    }
  }, [configured, user]);

  useEffectOR(()=>{
    if(authLoading) return;
    if(user) loadOrders();
    else { setOrders([]); setSource('none'); }
  }, [loadOrders, user, authLoading]);

  const value = { orders, loading, source, loadOrders, configured };
  return <OrdersContext.Provider value={value}>{children}</OrdersContext.Provider>;
}

function useOrders(){ return useCtxOR(OrdersContext); }

function getLastOrderId(){ return localStorage.getItem(LAST_ORDER_KEY) || ''; }
function setLastOrderId(id){
  if(id) localStorage.setItem(LAST_ORDER_KEY, id);
  else localStorage.removeItem(LAST_ORDER_KEY);
}
function getTrackOrderId(){ return localStorage.getItem(TRACK_ORDER_KEY) || getLastOrderId(); }
function setTrackOrderId(id){
  if(id) localStorage.setItem(TRACK_ORDER_KEY, id);
  else localStorage.removeItem(TRACK_ORDER_KEY);
}

Object.assign(window, {
  OrdersProvider, useOrders,
  placeMedusaOrder, mapMedusaOrder, loadMedusaOrders: async ()=>{
    const { orders } = await ordersFetch('/store/orders?limit=20&order=-created_at', { auth:true });
    return orders || [];
  },
  getLastOrderId, setLastOrderId, getTrackOrderId, setTrackOrderId,
  saveTrackCredentials, getSavedTrackToken, buildOrderTrackUrl, buildTelegramTrackLink,
  resolveOrderEmail,
  fetchGuestOrder, orderDeliveryStatus, orderTrackStepIndex, orderTrackSteps, orderStatusBadge, generateTrackToken,
  ordersFetch, resolveKzRegionId,
});