// assets/data_commerce.jsx — commerce & users mock data
// Money is stored as integer cents (matches backend). Display via /100.

(() => {
const R = (() => { let s = 1337; return () => { s = (s * 1664525 + 1013904223) % 4294967296; return s / 4294967296; }; })();
const ri = (a, b) => Math.floor(R() * (b - a + 1)) + a;
const pick = arr => arr[Math.floor(R() * arr.length)];
const ulid = () => { const cs = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'; let s = '01KR'; for (let i = 0; i < 22; i++) s += cs[Math.floor(R() * cs.length)]; return s; };
const uuid = () => { const h = '0123456789abcdef'; let s = ''; for (let i = 0; i < 32; i++) s += h[Math.floor(R() * 16)]; return s.slice(0,8)+'-'+s.slice(8,12)+'-'+s.slice(12,16)+'-'+s.slice(16,20)+'-'+s.slice(20); };

// ─── Users ────────────────────────────────────────────────────────────────
const USERNAMES = [
  'huyvu', 'phongtran', 'mainguyen', 'linhpham', 'duvo', 'anbui', 'thaole', 'tundang', 'kimdo', 'sondinh',
  'hadinh', 'baoluu', 'quanhoang', 'thangnghiem', 'binhng', 'longdh', 'tienng', 'vupham', 'phatle', 'mintran',
  'duyendo', 'haile', 'tonyle', 'lannguyen', 'kiet','hieu_dev', 'phuc_admin', 'minh_q','luna_studio','noahdo',
  'rio_le', 'sophie_t', 'jade_n', 'mickey', 'amber_d', 'kira_q', 'ezra_l', 'avapham', 'tomvn', 'leo_design',
];
const USERS = USERNAMES.map((u, i) => {
  const created = Date.now() - ri(2, 720) * 86400000;
  const lastLogin = R() > 0.18 ? Date.now() - ri(0, 14) * 86400000 - ri(0, 86400000) : null;
  const isActive = R() > 0.12;
  return {
    id: uuid(),
    username: u,
    email: `${u}@${pick(['gmail.com','outlook.com','proton.me','shopquantum.app','duck.com'])}`,
    subdomain: `${u}.shopquantum.app`,
    is_active: isActive,
    is_verified: isActive && R() > 0.15,
    role: i === 0 ? 'admin' : pick(['merchant','merchant','merchant','merchant','staff']),
    created_at: created,
    updated_at: created + ri(0, 30) * 86400000,
    last_login: lastLogin,
    balance_cents: Math.floor(R() * 80000) - 4000, // some negative
    projects_count: ri(0, 12),
    active_projects_count: ri(0, 5),
    sessions_count: ri(0, 184),
    messages_count: ri(0, 2400),
  };
});

// ─── Merchants (1 merchant may own multiple stores) ──────────────────────
const MERCHANT_NAMES = [
  'Bloom Cosmetics Vietnam','Artisan Craft Co','CoffeeBar Studio','Daily Essentials Shop','TryBlossom',
  'Northlight Studio','KitchenKit','PetPlace VN','Homestay Saigon','YogaHaus','GearLoft','PlantFriends',
  'Stationery Store','Speakeasy Bar','Lens & Light','Studio Candle','Silkroad Jewels','RunClub','UrbanLeaf','Saigon Spice',
];
const MERCHANTS = MERCHANT_NAMES.map((n) => ({
  id: ulid(),
  name: n,
  logo_url: null,
  status: R() > 0.08 ? 'active' : 'inactive',
  created_at: Date.now() - ri(30, 900) * 86400000,
}));

// ─── Stores ───────────────────────────────────────────────────────────────
const PLATFORMS = [
  { name: 'shopify', share: 0.42, color: 'var(--chart-3)' },
  { name: 'custom',  share: 0.32, color: 'var(--chart-1)' },
  { name: 'woocommerce', share: 0.18, color: 'var(--chart-5)' },
  { name: 'psa', share: 0.05, color: 'var(--chart-2)' },
  { name: 'other', share: 0.03, color: 'var(--chart-8)' },
];
const platformPick = () => {
  const r = R(); let acc = 0;
  for (const p of PLATFORMS) { acc += p.share; if (r < acc) return p; }
  return PLATFORMS[0];
};
const PLANS = ['free', 'basic', 'pro', 'max', null]; // null = no subscription
const PLAN_PRICES_CENTS = { free: 0, basic: 1900, pro: 4900, max: 14900 };

const STORE_NAME_TEMPLATES = [
  '{m} Main Store','{m} Outlet','{m} Wholesale','{m} EU','{m} US','{m} Studio','{m} Bazaar',
  '{m} Concept','{m} Vault','{m} Goods'
];
function mkStores() {
  const stores = [];
  let id = 1;
  MERCHANTS.forEach((m, mi) => {
    const storesCount = mi < 6 ? ri(2, 4) : ri(1, 2); // first merchants have more
    for (let s = 0; s < storesCount; s++) {
      const platform = platformPick();
      const created = Date.now() - ri(7, 600) * 86400000;
      const totalOrders = Math.floor(R() * 1800);
      const fulfilled = Math.floor(totalOrders * (0.62 + R() * 0.35));
      const cancelled = Math.floor((totalOrders - fulfilled) * R() * 0.6);
      const processing = totalOrders - fulfilled - cancelled;
      const aov_cents = ri(2500, 12000);
      const revenue_cents = totalOrders * aov_cents;
      const plan = pick(PLANS);
      const subStatus = plan ? pick(['active','active','active','active','past_due','canceled']) : null;
      const ownerUser = pick(USERS);
      const lastOrder = totalOrders > 0 ? Date.now() - ri(0, 30) * 86400000 : null;
      const baseName = m.name.split(' ')[0];
      const storeName = s === 0 ? m.name : pick(STORE_NAME_TEMPLATES).replace('{m}', baseName);
      const domain = (storeName.toLowerCase().replace(/[^a-z0-9]+/g, '-').slice(0, 28) + '.myshopify.com').replace(/^-/, '');
      stores.push({
        id: ulid(),
        name: storeName,
        store_domain: platform.name === 'shopify' ? domain : (storeName.toLowerCase().replace(/[^a-z0-9]+/g,'') + '.com'),
        platform: platform.name,
        platform_color: platform.color,
        merchant_id: m.id,
        merchant_name: m.name,
        owner_user_id: ownerUser.id,
        owner_username: ownerUser.username,
        owner_email: ownerUser.email,
        is_deleted: false,
        is_paid: !!plan && subStatus === 'active' && plan !== 'free',
        plan,
        subscription_status: subStatus,
        subscription_provider: subStatus ? 'stripe' : null,
        stripe_customer_id: subStatus ? 'cus_' + uuid().slice(0, 14) : null,
        stripe_sub_id: subStatus ? 'sub_' + uuid().slice(0, 14) : null,
        period_start: subStatus ? Date.now() - ri(0, 25) * 86400000 : null,
        period_end:   subStatus ? Date.now() + ri(5, 30) * 86400000 : null,
        cancel_at_period_end: subStatus === 'canceled',
        plan_price_cents: PLAN_PRICES_CENTS[plan] || 0,
        total_orders: totalOrders,
        fulfilled_orders: fulfilled,
        processing_orders: Math.max(processing, 0),
        cancelled_orders: cancelled,
        fulfill_rate: totalOrders > 0 ? fulfilled / totalOrders : 0,
        revenue_cents,
        aov_cents,
        currency: pick(['USD','USD','USD','EUR','VND']),
        created_at: created,
        updated_at: created + ri(0, 60) * 86400000,
        last_order_at: lastOrder,
        project_count: ri(1, 8),
        project_cost_cents: ri(50, 4800), // total session cost in cents
        trd_store_id:    platform.name === 'shopify' ? String(ri(10000000, 99999999)) : null,
        trd_store_name:  platform.name === 'shopify' ? storeName : null,
        trd_store_domain:platform.name === 'shopify' ? domain : null,
      });
      id++;
    }
  });
  return stores;
}
const STORES = mkStores().sort((a, b) => b.revenue_cents - a.revenue_cents);

// Account balance per user (some only)
const BALANCES = {};
USERS.forEach(u => {
  if (R() > 0.18) {
    const total = u.balance_cents;
    const frozen = total > 0 ? Math.floor(R() * total * 0.2) : 0;
    BALANCES[u.id] = {
      total_balance_cents: total,
      frozen_cents: frozen,
      available_cents: total - frozen,
      total_deposit_cents: total > 0 ? total + ri(0, 50000) : ri(0, 10000),
      total_spend_cents: ri(0, 30000),
    };
  }
});

// ─── Orders (only realised for store detail; lazy: top 30 per store via fn) ──
function mkOrdersForStore(store, limit = 10) {
  if (!store.total_orders) return [];
  const out = [];
  const trackingPrefixes = ['1Z','SF','VN','SPX','LP','GLS'];
  for (let i = 0; i < limit; i++) {
    const statusCode = R() < 0.7 ? 2 : (R() < 0.85 ? 1 : 3);
    const price = ri(store.aov_cents - 1500, store.aov_cents + 3000);
    out.push({
      id: ulid(),
      order_number: '#' + ri(1001, 99999),
      status_code: statusCode,
      status: statusCode === 1 ? 'Processing' : statusCode === 2 ? 'Fulfilled' : 'Cancelled',
      price_cents: price,
      currency: store.currency,
      tracking: statusCode === 2 ? pick(trackingPrefixes) + ri(100000000, 999999999) : null,
      created_at: Date.now() - ri(0, 28) * 86400000 - ri(0, 86400000),
    });
  }
  return out.sort((a, b) => b.created_at - a.created_at);
}

// ─── Projects per merchant (mock) ────────────────────────────────────────
const PROJECT_NAMES_M = [
  'Homepage clone','Product page rebuild','Hero refresh','Newsletter section','Footer redesign',
  'Collection landing','Onboarding flow','Cart drawer','Checkout polish','Mobile nav','PDP variants','Blog template'
];
function mkProjectsForMerchant(merchant_id, count) {
  return Array.from({ length: count }, (_, i) => ({
    id: ulid(),
    name: pick(PROJECT_NAMES_M),
    status: pick(['published','published','draft','archived']),
    preview_url: 'https://preview.shopquantum.app/p/' + ulid().slice(0,12),
    production_url: R() > 0.4 ? 'https://prod.shopquantum.app/p/' + ulid().slice(0,12) : null,
    is_published: R() > 0.4,
    created_at: Date.now() - ri(0, 200) * 86400000,
    total_cost_cents: ri(20, 1200),
  }));
}

// ─── Commerce KPIs (derived) ─────────────────────────────────────────────
const KPI = {
  total_revenue_cents: STORES.reduce((s, x) => s + x.revenue_cents, 0),
  mrr_cents: STORES.filter(s => s.subscription_status === 'active').reduce((s, x) => s + x.plan_price_cents, 0),
  active_stores: STORES.filter(s => !s.is_deleted).length,
  total_orders: STORES.reduce((s, x) => s + x.total_orders, 0),
  fulfilled_orders: STORES.reduce((s, x) => s + x.fulfilled_orders, 0),
  merchants_distinct: new Set(STORES.map(s => s.merchant_id)).size,
  subs_active: STORES.filter(s => s.subscription_status === 'active').length,
  paid_stores: STORES.filter(s => s.is_paid).length,
};

// ─── Time series helpers (revenue/orders over last 30d) ──────────────────
function seriesDays(n, base, jitter, trend = 0) {
  const arr = [];
  for (let i = 0; i < n; i++) arr.push(Math.max(0, Math.round(base + trend * i + (R() - 0.5) * jitter)));
  return arr;
}
const TIMESERIES = {
  labels_30d: Array.from({ length: 30 }, (_, i) => { const d = new Date(); d.setDate(d.getDate() - (29 - i)); return (d.getMonth()+1) + '/' + d.getDate(); }),
  revenue_30d_cents:  seriesDays(30, 1800000, 600000, 30000),
  orders_30d:         seriesDays(30, 280, 90, 2),
  new_stores_30d:     seriesDays(30, 1.5, 1.4, 0.04).map(Math.round),
  new_subs_30d:       seriesDays(30, 0.8, 1.0, 0.05).map(Math.round),
};

// Top stores by revenue (use first N)
const TOP_STORES = STORES.slice(0, 10);

// Platform breakdown
const PLATFORM_BREAKDOWN = PLATFORMS.map(p => ({
  label: p.name, color: p.color,
  value: STORES.filter(s => s.platform === p.name).length,
  revenue_cents: STORES.filter(s => s.platform === p.name).reduce((sum, s) => sum + s.revenue_cents, 0),
}));

// Plan breakdown
const PLAN_BREAKDOWN = ['free','basic','pro','max'].map(p => ({
  label: p, value: STORES.filter(s => s.plan === p).length,
}));

// ─── Money helpers ───────────────────────────────────────────────────────
const fmtMoney = (cents, currency = 'USD') => {
  if (cents == null) return '—';
  const v = cents / 100;
  if (currency === 'USD') return '$' + v.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  if (currency === 'EUR') return '€' + v.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  if (currency === 'VND') return '₫' + Math.round(v * 24500).toLocaleString();
  return v.toFixed(2) + ' ' + currency;
};
const fmtMoneyCompact = (cents) => {
  if (cents == null) return '—';
  const v = cents / 100;
  if (v >= 1e6) return '$' + (v / 1e6).toFixed(2) + 'M';
  if (v >= 1e3) return '$' + (v / 1e3).toFixed(1) + 'k';
  return '$' + v.toFixed(2);
};
const fmtDate = (ts) => {
  if (!ts) return '—';
  const d = new Date(ts);
  return d.getFullYear() + '-' + String(d.getMonth()+1).padStart(2,'0') + '-' + String(d.getDate()).padStart(2,'0');
};

// ─── Prompts ──────────────────────────────────────────────────────────────
const PROMPTS = {
  landing_page: {
    name: 'landing_page',
    title: 'Landing Page Agent',
    file: 'prompts/agents/landing_page.md',
    updated_at: Date.now() - 18 * 3600000,
    content: `# Landing Page Agent

You are the **Landing Page Agent** for ShopQuantum. You build hi-fi landing pages for
e-commerce merchants given a brief, brand assets, and a target audience.

## Operating principles

1. **Use the Tailwind design system.** All colors, spacing, and typography come from
   the project's \`tailwind.config.ts\`. Never use arbitrary values like \`text-[#1a2b3c]\`
   or \`p-[37px]\`. If you need a new token, propose it; do not inline.
2. **Sections you may include**, in this order: Hero, Featured Products (grid 3–6),
   Social Proof / Testimonials, FAQ, Newsletter, Footer.
3. **Respect the brand voice.** If the merchant brief includes a tone descriptor
   (\`playful\`, \`luxury\`, \`technical\`), reflect it in copy and visual weight.
4. **Accessibility first.** Every \`<img>\` needs an \`alt\`. Buttons must be \`<button>\`,
   not clickable \`<div>\`. Headings must be ordered.

## Forbidden

- \`dangerouslySetInnerHTML\` (sanitizer will strip it).
- Inline \`style={{}}\` — utility classes only.
- \`console.log\` in production paths.
- Hard-coded credentials, API keys, or external \`fetch()\` URLs.

## Output

Write components to \`src/components/\` and the page to \`src/pages/index.tsx\`.
Use the shared \`<ProductCard />\` from \`shared/\`.
`,
  },
  store: {
    name: 'store',
    title: 'Store Agent',
    file: 'prompts/agents/store.md',
    updated_at: Date.now() - 3 * 86400000,
    content: `# Store Agent

You are the **Store Agent** — you build and maintain entire storefronts on top of
the ShopQuantum platform. Unlike the Landing Page Agent, you own multiple pages,
state, navigation, and cart logic.

## Pages you produce

- \`/\` — Home (uses Landing Page Agent's section components where possible)
- \`/collections/[handle]\` — Collection grid with filters (price, vendor, type)
- \`/products/[handle]\` — Product detail with variant picker, qty, gallery
- \`/cart\` — Cart drawer + standalone page
- \`/checkout\` — Lightweight wrapper around Stripe Checkout
- \`/pages/[handle]\` — CMS pages (about, FAQ, policy)

## State & data

- Cart state lives in \`zustand\` store, persisted to \`localStorage\` (key \`sq_cart_v1\`).
- Product data comes from \`/api/storefront/products\` (typed via \`shared/types\`).
- Use \`useSWR\` for fetching; never call \`fetch\` directly in components.

## Multi-tenant rules

- \`storeDomain\` is read from \`headers.x-sq-store\` server-side and from a
  global context client-side. **Never hard-code a domain.**
- Theme tokens are resolved from \`store.theme_tokens\` at request time.

## Hooks

The platform enforces hooks at write time. The most common denials are:
- \`block_inline_styles\` — fix by moving to utility classes.
- \`enforce_tailwind_tokens\` — replace arbitrary values with named tokens.
- \`block_dangerous_html\` — sanitize content server-side instead.
`,
  },
};

// Export everything to window
Object.assign(window, {
  USERS, MERCHANTS, STORES, BALANCES, PLATFORMS, KPI, TIMESERIES, TOP_STORES,
  PLATFORM_BREAKDOWN, PLAN_BREAKDOWN, PROMPTS,
  mkOrdersForStore, mkProjectsForMerchant,
  fmtMoney, fmtMoneyCompact, fmtDate,
});
})();
