/* ============================================================
   Oziq AI — mock data (deterministic, seeded)
   Cohesive across all screens
   ============================================================ */

// Seeded PRNG so refresh shows the same data
function mulberry32(a) {
  return function() {
    var t = a += 0x6D2B79F5;
    t = Math.imul(t ^ t >>> 15, t | 1);
    t ^= t + Math.imul(t ^ t >>> 7, t | 61);
    return ((t ^ t >>> 14) >>> 0) / 4294967296;
  };
}
const rng = mulberry32(20260514);
const rand  = () => rng();
const randi = (a, b) => Math.floor(rand() * (b - a + 1)) + a;
const pick  = (arr) => arr[Math.floor(rand() * arr.length)];
const pickWeighted = (arr, weights) => {
  const sum = weights.reduce((a, b) => a + b, 0);
  let r = rand() * sum;
  for (let i = 0; i < arr.length; i++) {
    r -= weights[i];
    if (r <= 0) return arr[i];
  }
  return arr[arr.length - 1];
};

// ============================================================
// Topics — 12 food-supply categories
// ============================================================
const TOPICS = [
  { id: 'onion',     uz: 'Piyoz',        ru: 'Лук',          en: 'Onion',         color: 'var(--t-onion)',     glyph: 'P', subs: ['Narx', 'Ekish', 'Saqlash', 'Eksport'] },
  { id: 'beef',      uz: 'Mol/Qoʻy goʻshti', ru: 'Говядина/Баранина', en: 'Beef/Mutton', color: 'var(--t-beef)',  glyph: 'G', subs: ['Narx', 'Sifat', 'Qassobxona', 'Logistika'] },
  { id: 'rice',      uz: 'Guruch',       ru: 'Рис',          en: 'Rice',          color: 'var(--t-rice)',      glyph: 'Gu', subs: ['Narx', 'Sifat', 'Eksport', 'Import'] },
  { id: 'carrot',    uz: 'Sabzi',        ru: 'Морковь',      en: 'Carrot',        color: 'var(--t-carrot)',    glyph: 'S', subs: ['Narx', 'Sifat', 'Saqlash'] },
  { id: 'potato',    uz: 'Kartoshka',    ru: 'Картофель',    en: 'Potato',        color: 'var(--t-potato)',    glyph: 'K', subs: ['Narx', 'Urugʻ', 'Saqlash', 'Import'] },
  { id: 'logistic',  uz: 'Logistika',    ru: 'Логистика',    en: 'Logistics',     color: 'var(--t-logistic)',  glyph: 'L', subs: ['Transport', 'Saqlash', 'Bojxona', 'Hujjatlar'] },
  { id: 'warehouse', uz: 'Ombor',        ru: 'Склад',        en: 'Warehouse',     color: 'var(--t-warehouse)', glyph: 'O', subs: ['Sigʻim', 'Sovutgich', 'Ijara'] },
  { id: 'breeding',  uz: 'Naslchilik',   ru: 'Племенное дело', en: 'Breeding',    color: 'var(--t-breeding)',  glyph: 'N', subs: ['Veterinariya', 'Yem', 'Subsidiya'] },
  { id: 'flour',     uz: 'Un',           ru: 'Мука',         en: 'Flour',         color: 'var(--t-flour)',     glyph: 'U', subs: ['Narx', 'Sifat', 'Tegirmon'] },
  { id: 'oil',       uz: 'Oʻsimlik yogʻi', ru: 'Растит. масло', en: 'Veg. oil',  color: 'var(--t-oil)',       glyph: 'Yo', subs: ['Narx', 'Sifat', 'Eksport'] },
  { id: 'poultry',   uz: 'Parranda',     ru: 'Птица',        en: 'Poultry',       color: 'var(--t-poultry)',   glyph: 'P', subs: ['Tuxum', 'Goʻsht', 'Yem'] },
  { id: 'sugar',     uz: 'Shakar',       ru: 'Сахар',        en: 'Sugar',         color: 'var(--t-sugar)',     glyph: 'Sh', subs: ['Narx', 'Import', 'Zaxira'] },
];
const TOPIC_BY_ID = Object.fromEntries(TOPICS.map(t => [t.id, t]));

// Topic share weights (% of all inquiries — must reconcile)
const TOPIC_WEIGHTS = {
  onion: 14, beef: 11, rice: 9, carrot: 6, potato: 13, logistic: 12,
  warehouse: 5, breeding: 4, flour: 8, oil: 7, poultry: 6, sugar: 5
};

// ============================================================
// Regions — 14 viloyats of Uzbekistan
// ============================================================
const REGIONS = [
  { id: 'tas', uz: 'Toshkent sh.',  ru: 'г. Ташкент',     code: 'TAS', pop: 2.9, weight: 18 },
  { id: 'tos', uz: 'Toshkent vil.', ru: 'Ташкентская обл.', code: 'TOS', pop: 2.9, weight: 12 },
  { id: 'sam', uz: 'Samarqand',     ru: 'Самаркандская',  code: 'SAM', pop: 4.0, weight: 11 },
  { id: 'fer', uz: 'Fargʻona',      ru: 'Ферганская',     code: 'FER', pop: 3.8, weight: 10 },
  { id: 'and', uz: 'Andijon',       ru: 'Андижанская',    code: 'AND', pop: 3.2, weight: 9 },
  { id: 'nam', uz: 'Namangan',      ru: 'Наманганская',   code: 'NAM', pop: 2.9, weight: 8 },
  { id: 'qsh', uz: 'Qashqadaryo',   ru: 'Кашкадарьинская', code: 'QSH', pop: 3.4, weight: 7 },
  { id: 'sur', uz: 'Surxondaryo',   ru: 'Сурхандарьинская', code: 'SUR', pop: 2.7, weight: 5 },
  { id: 'buk', uz: 'Buxoro',        ru: 'Бухарская',      code: 'BUK', pop: 1.9, weight: 5 },
  { id: 'xor', uz: 'Xorazm',        ru: 'Хорезмская',     code: 'XOR', pop: 1.9, weight: 4 },
  { id: 'jiz', uz: 'Jizzax',        ru: 'Джизакская',     code: 'JIZ', pop: 1.4, weight: 4 },
  { id: 'syr', uz: 'Sirdaryo',      ru: 'Сырдарьинская',  code: 'SYR', pop: 0.9, weight: 3 },
  { id: 'nav', uz: 'Navoiy',        ru: 'Навоийская',     code: 'NAV', pop: 1.0, weight: 2 },
  { id: 'qrq', uz: 'Qoraqalpogʻiston', ru: 'Каракалпакстан', code: 'QRQ', pop: 1.9, weight: 2 },
];
const REGION_BY_ID = Object.fromEntries(REGIONS.map(r => [r.id, r]));

// ============================================================
// Names — realistic Uzbek
// ============================================================
const FIRST_NAMES_M = ['Akmal','Botir','Davron','Eldor','Farrux','Gʻulom','Hasan','Ilhom','Jasur','Komil','Lazizbek','Mansur','Nodir','Otabek','Pulat','Qodir','Rustam','Sherzod','Tohir','Ulugʻbek','Vohid','Yusuf','Zafar','Abdulla','Bekzod','Dilshod','Erkin','Furqat','Hamid','Islom','Javohir','Karim','Murod','Nurbek','Olim','Sardor','Temur','Umid','Anvar','Bobur'];
const FIRST_NAMES_F = ['Aziza','Barno','Dilnoza','Elmira','Feruza','Gulnora','Hilola','Iroda','Jamila','Kamola','Laylo','Madina','Nilufar','Oygul','Parizoda','Qamariddin','Rayhona','Sevara','Tursunoy','Umida','Vasila','Yulduz','Zarina','Aysha','Begoyim','Dilfuza','Etibor','Gulchehra','Hayot','Iqbol','Jasmin','Komila','Malika','Nazira','Oysha','Parvina','Roziya','Saodat','Tahmina','Zulfiya'];
const LAST_NAMES = ['Karimov','Yusupov','Ismoilov','Tursunov','Mirzayev','Saidov','Rashidov','Olimov','Yoʻldoshev','Nazarov','Rahmonov','Komilov','Boboyev','Mamatov','Xolmatov','Ergashev','Sobirov','Toshmatov','Murodov','Tojiyev','Akbarov','Vohidov','Gʻafurov','Rajabov','Sharipov','Ahmadov','Hamidov','Qosimov','Otaboyev','Eshonqulov'];

function makeName() {
  const f = rand() < 0.55 ? FIRST_NAMES_M[Math.floor(rand() * FIRST_NAMES_M.length)] : FIRST_NAMES_F[Math.floor(rand() * FIRST_NAMES_F.length)];
  const l = LAST_NAMES[Math.floor(rand() * LAST_NAMES.length)];
  return `${f} ${l}`;
}
function initials(name) {
  return name.split(' ').map(s => s[0]).join('').slice(0, 2).toUpperCase();
}

// ============================================================
// Analysts — 8 ministry staff
// ============================================================
const ANALYSTS = [
  { id: 'a1', name: 'Akmal Karimov',     role: 'Bosh tahlilchi', dept: 'Don ekinlari',     online: true,  resolved: 142, avgMin: 18 },
  { id: 'a2', name: 'Dilnoza Yusupova',  role: 'Tahlilchi',      dept: 'Sabzavot',         online: true,  resolved: 128, avgMin: 22 },
  { id: 'a3', name: 'Rustam Ismoilov',   role: 'Tahlilchi',      dept: 'Chorvachilik',     online: false, resolved: 96,  avgMin: 31 },
  { id: 'a4', name: 'Sevara Mirzayeva',  role: 'Katta tahlilchi',dept: 'Logistika',        online: true,  resolved: 175, avgMin: 14 },
  { id: 'a5', name: 'Bekzod Rashidov',   role: 'Tahlilchi',      dept: 'Narx-navo',        online: true,  resolved: 118, avgMin: 24 },
  { id: 'a6', name: 'Madina Olimova',    role: 'Tahlilchi',      dept: 'Eksport-import',   online: false, resolved: 88,  avgMin: 35 },
  { id: 'a7', name: 'Otabek Nazarov',    role: 'Tahlilchi',      dept: 'Zaxira & ombor',   online: true,  resolved: 109, avgMin: 26 },
  { id: 'a8', name: 'Feruza Tojiyeva',   role: 'Boʻlim boshligʻi', dept: 'AI nazorat',     online: true,  resolved: 64,  avgMin: 12 },
];

// ============================================================
// Question templates — realistic farmer questions
// ============================================================
const Q_TEMPLATES = {
  onion: [
    { uz: 'Bu yil piyoz narxi nega bunchalik pasayib ketdi? {region}da kg 800 soʻm.', ru: 'Почему цена на лук так упала в этом году? В {region} кг 800 сум.' },
    { uz: 'Piyozni saqlash uchun sovutgich omborlari haqida maʼlumot bering.', ru: 'Дайте информацию о холодных хранилищах для лука.' },
    { uz: 'Eksport uchun piyozga sertifikat qanday olinadi?', ru: 'Как получить сертификат на экспорт лука?' },
    { uz: 'Piyoz urugʻi subsidiyasi qachon beriladi?', ru: 'Когда выдается субсидия на семена лука?' },
  ],
  beef: [
    { uz: 'Mol goʻshti narxi koʻtarilib ketdi, sabab nima? Bozorda kilosi 95000 soʻm.', ru: 'Цена на говядину поднялась, почему? На рынке 95000 сум/кг.' },
    { uz: 'Qoʻy goʻshti eksportiga limit qoʻyilganmi?', ru: 'Введён ли лимит на экспорт баранины?' },
    { uz: 'Qassobxona litsenziyasini yangilash uchun qaerga murojaat qilay?', ru: 'Куда обратиться для обновления лицензии бойни?' },
  ],
  rice: [
    { uz: 'Guruch eksport bojxona toʻlovi 2026 yilda oʻzgaradimi?', ru: 'Изменится ли таможенный сбор на экспорт риса в 2026 году?' },
    { uz: 'Bizning guruchimiz sifat sertifikatini olmadi, sabab?', ru: 'Наш рис не получил сертификат качества, почему?' },
    { uz: 'Lazer tekislash uchun subsidiya qancha?', ru: 'Какая субсидия на лазерное выравнивание полей?' },
  ],
  carrot: [
    { uz: 'Sabzi narxi shu hafta qancha?', ru: 'Какая цена на морковь на этой неделе?' },
    { uz: 'Sabzini ulgurji sotish uchun shartnoma namunasi kerak.', ru: 'Нужен образец договора оптовой продажи моркови.' },
  ],
  potato: [
    { uz: 'Kartoshka urugʻini Niderlandiyadan olib kelish mumkinmi?', ru: 'Можно ли завезти семенной картофель из Нидерландов?' },
    { uz: '{region}da kartoshka kasalligi paydo boʻlmoqda, qanday choralar?', ru: 'В {region} появились болезни картофеля, какие меры?' },
    { uz: 'Saqlash omborida harorat qancha boʻlishi kerak?', ru: 'Какая температура должна быть в хранилище картофеля?' },
  ],
  logistic: [
    { uz: 'Yuk mashinasi {region}dan Toshkentga necha kunda yetib boradi?', ru: 'За сколько дней грузовик доезжает из {region} в Ташкент?' },
    { uz: 'Bojxona terminalida 3 kun kutyapmiz, nima qilamiz?', ru: 'Уже 3 дня ждём на таможенном терминале, что делать?' },
    { uz: 'Transport subsidiyasi qaysi mahsulotlarga beriladi?', ru: 'На какую продукцию даётся транспортная субсидия?' },
  ],
  warehouse: [
    { uz: 'Sovutgich ombor ijarasi narxi {region}da qancha?', ru: 'Какая аренда холодного склада в {region}?' },
    { uz: 'Davlat omborida joy band qilish tartibi qanday?', ru: 'Каков порядок бронирования места на госскладе?' },
  ],
  breeding: [
    { uz: 'Naslchilik subsidiyasi 2026-yilda qancha boʻladi?', ru: 'Какая субсидия на племенное дело в 2026 году?' },
    { uz: 'Veterinariya tekshiruvi navbati juda uzun.', ru: 'Очередь на ветеринарную проверку очень длинная.' },
  ],
  flour: [
    { uz: 'Un narxi koʻtarildi, davlat zaxirasidan beriladimi?', ru: 'Цена на муку выросла, выдают ли из госрезерва?' },
    { uz: 'Tegirmon litsenziyasini qanday olaman?', ru: 'Как получить лицензию на мельницу?' },
  ],
  oil: [
    { uz: 'Paxta yogʻi eksportiga ruxsat qachon ochiladi?', ru: 'Когда откроют разрешение на экспорт хлопкового масла?' },
    { uz: 'Yogʻ ishlab chiqarish sexi uchun sertifikat kerakmi?', ru: 'Нужен ли сертификат для маслоцеха?' },
  ],
  poultry: [
    { uz: 'Tuxum narxi pasaydi, fermerga zarar qoplanadimi?', ru: 'Цена на яйца упала, компенсируют ли убыток?' },
    { uz: 'Tovuq yemiga don zaxirasi yetadimi?', ru: 'Хватит ли зернового запаса на корм птицы?' },
  ],
  sugar: [
    { uz: 'Shakar narxi nima uchun har hafta oʻzgaryapti?', ru: 'Почему цена на сахар меняется каждую неделю?' },
    { uz: 'Importi 2026-yilda kvota bilan boʻladimi?', ru: 'Будет ли импорт сахара по квотам в 2026 году?' },
  ],
};

// ============================================================
// Farmers — ~300
// ============================================================
const FARMERS = [];
const NUM_FARMERS = 312;
for (let i = 0; i < NUM_FARMERS; i++) {
  const region = pickWeighted(REGIONS, REGIONS.map(r => r.weight));
  const name = makeName();
  const primaryTopic = pickWeighted(TOPICS, TOPICS.map(t => TOPIC_WEIGHTS[t.id]));
  const inquiries = randi(2, 38);
  const lastDays = Math.floor(rand() * 60);
  const sentScore = rand(); // 0..1
  FARMERS.push({
    id: `F${String(i + 1).padStart(4, '0')}`,
    name, initials: initials(name),
    region: region.id,
    primaryTopic: primaryTopic.id,
    inquiries,
    lastSeenDays: lastDays,
    status: lastDays < 7 ? 'active' : lastDays < 30 ? 'dormant' : 'inactive',
    sentiment: sentScore < 0.3 ? 'negative' : sentScore < 0.7 ? 'neutral' : 'positive',
    phone: `+998 9${randi(0,9)} ${randi(100,999)} ${randi(10,99)} ${randi(10,99)}`,
  });
}

// ============================================================
// Inquiries — 5000 across 90 days
// ============================================================
const NOW = new Date('2026-05-14T14:30:00');
const INQUIRIES = [];
const NUM_INQUIRIES = 5240;

// Daily volume curve — weekly seasonality + slight upward trend
function dailyVolume(dayBack) {
  const day = 89 - dayBack;
  const trend = 35 + day * 0.18;
  const dow = ((new Date(NOW.getTime() - dayBack * 86400000)).getDay() + 6) % 7;
  const weekly = [1.05, 1.15, 1.10, 1.08, 1.00, 0.55, 0.45][dow];
  const noise = 0.85 + rand() * 0.30;
  return Math.round(trend * weekly * noise);
}
const dailyTotals = [];
for (let d = 89; d >= 0; d--) dailyTotals.push(dailyVolume(d));

const STATUSES = ['new', 'classified', 'routed', 'answered', 'resolved'];
const STATUS_WEIGHTS = { new: 8, classified: 10, routed: 22, answered: 35, resolved: 25 };
const PRIORITIES = ['urgent', 'high', 'medium', 'low'];
const PRIO_WEIGHTS = { urgent: 6, high: 18, medium: 48, low: 28 };
const LANGS = ['uz-latn', 'uz-cyrl', 'ru', 'mixed'];
const LANG_WEIGHTS = { 'uz-latn': 58, 'uz-cyrl': 12, 'ru': 24, 'mixed': 6 };
const CHANNELS = ['bot', 'group', 'group', 'bot', 'bot']; // bot more common

let inquiryId = 1;
for (let d = 0; d < 90; d++) {
  const cnt = dailyTotals[d];
  const dayOffset = 89 - d;
  for (let i = 0; i < cnt; i++) {
    const topic = pickWeighted(TOPICS, TOPICS.map(t => TOPIC_WEIGHTS[t.id]));
    const sub = pick(topic.subs);
    const farmer = FARMERS[Math.floor(rand() * FARMERS.length)];
    const region = REGION_BY_ID[farmer.region];
    const templates = Q_TEMPLATES[topic.id] || Q_TEMPLATES.onion;
    const tmpl = pick(templates);
    const text = tmpl.uz.replace('{region}', region.uz);
    const ru = tmpl.ru.replace('{region}', region.ru);
    const lang = pickWeighted(LANGS, LANGS.map(l => LANG_WEIGHTS[l]));
    const intent = pickWeighted(['question','complaint','noise'], [62, 30, 8]);
    const sentRoll = rand();
    const sent = intent === 'complaint' ? (sentRoll < 0.75 ? 'negative' : 'neutral')
               : intent === 'noise'     ? 'neutral'
               : (sentRoll < 0.20 ? 'negative' : sentRoll < 0.55 ? 'neutral' : 'positive');
    // urgency higher for complaints + recent days
    let prio = pickWeighted(PRIORITIES, PRIORITIES.map(p => PRIO_WEIGHTS[p]));
    if (intent === 'complaint' && rand() < 0.4) prio = 'urgent';
    // status: older items more likely resolved
    let status;
    if (dayOffset > 7) status = pickWeighted(['answered','resolved','routed'], [30, 60, 10]);
    else if (dayOffset > 2) status = pickWeighted(STATUSES, [3, 8, 20, 38, 31]);
    else status = pickWeighted(STATUSES, [22, 25, 28, 18, 7]);
    const confidence = 0.62 + rand() * 0.36;
    const ts = new Date(NOW.getTime() - dayOffset * 86400000 - randi(0, 86399) * 1000);

    INQUIRIES.push({
      id: `MUR-${String(inquiryId++).padStart(6, '0')}`,
      ts,
      dayOffset,
      topic: topic.id,
      sub,
      farmer: farmer.id,
      region: farmer.region,
      text, textRu: ru,
      lang, intent, sentiment: sent,
      priority: prio,
      status,
      confidence,
      channel: pick(CHANNELS),
      analyst: status !== 'new' ? pick(ANALYSTS).id : null,
      hasAttachment: rand() < 0.12,
      slaMins: status === 'resolved' || status === 'answered' ? null : randi(-180, 480),
    });
  }
}
// truncate to ~5240
INQUIRIES.length = Math.min(INQUIRIES.length, NUM_INQUIRIES);
// sort newest first
INQUIRIES.sort((a, b) => b.ts - a.ts);

// ============================================================
// Aggregations — pre-computed for all screens
// ============================================================

// By topic
const BY_TOPIC = {};
TOPICS.forEach(t => BY_TOPIC[t.id] = { total: 0, q: 0, open: 0, urgent: 0, neg: 0, neu: 0, pos: 0, prevWeek: 0, thisWeek: 0 });
INQUIRIES.forEach(inq => {
  const b = BY_TOPIC[inq.topic];
  b.total++;
  if (inq.intent === 'question') b.q++;
  if (inq.status !== 'resolved') b.open++;
  if (inq.priority === 'urgent') b.urgent++;
  if (inq.sentiment === 'negative') b.neg++;
  else if (inq.sentiment === 'positive') b.pos++;
  else b.neu++;
  if (inq.dayOffset <= 6) b.thisWeek++;
  else if (inq.dayOffset <= 13) b.prevWeek++;
});

// By region
const BY_REGION = {};
REGIONS.forEach(r => BY_REGION[r.id] = { total: 0, open: 0, urgent: 0, topics: {}, sent: { neg: 0, neu: 0, pos: 0 } });
INQUIRIES.forEach(inq => {
  const b = BY_REGION[inq.region];
  b.total++;
  if (inq.status !== 'resolved') b.open++;
  if (inq.priority === 'urgent') b.urgent++;
  b.topics[inq.topic] = (b.topics[inq.topic] || 0) + 1;
  b.sent[inq.sentiment === 'negative' ? 'neg' : inq.sentiment === 'positive' ? 'pos' : 'neu']++;
});

// By day, by topic
const BY_DAY = []; // [{date, total, byTopic: {...}}]
for (let d = 0; d < 90; d++) {
  BY_DAY.push({ dayOffset: 89 - d, total: 0, byTopic: {}, date: new Date(NOW.getTime() - (89 - d) * 86400000) });
  TOPICS.forEach(t => BY_DAY[d].byTopic[t.id] = 0);
}
INQUIRIES.forEach(inq => {
  const idx = 89 - inq.dayOffset;
  BY_DAY[idx].total++;
  BY_DAY[idx].byTopic[inq.topic]++;
});

// Hourly heatmap: 7 days × 24 hours (last 7 days)
const HEATMAP = []; // 7 rows × 24 cols, rows = day-of-week starting Mon
for (let dow = 0; dow < 7; dow++) HEATMAP.push(new Array(24).fill(0));
INQUIRIES.forEach(inq => {
  if (inq.dayOffset >= 28) return;
  const dow = (inq.ts.getDay() + 6) % 7;
  HEATMAP[dow][inq.ts.getHours()]++;
});

// Status totals
const STATUS_TOTALS = { new: 0, classified: 0, routed: 0, answered: 0, resolved: 0 };
INQUIRIES.forEach(inq => STATUS_TOTALS[inq.status]++);

// KPI totals (reconcile across screens)
const TODAY_COUNT = INQUIRIES.filter(i => i.dayOffset === 0).length;
const YESTERDAY_COUNT = INQUIRIES.filter(i => i.dayOffset === 1).length;
const TOTAL = INQUIRIES.length;
const QUESTIONS = INQUIRIES.filter(i => i.intent === 'question').length;
const OPEN_Q = INQUIRIES.filter(i => i.intent === 'question' && i.status !== 'resolved').length;
const RESOLVED_TODAY = INQUIRIES.filter(i => i.dayOffset === 0 && i.status === 'resolved').length;
const URGENT_OPEN = INQUIRIES.filter(i => i.priority === 'urgent' && i.status !== 'resolved').length;

// Trending keywords (last 24h)
const KEYWORDS = [
  { w: 'Piyoz narxi',              count: 184, prev: 142, topic: 'onion' },
  { w: 'Guruch eksporti',          count: 121, prev: 156, topic: 'rice' },
  { w: 'Naslchilik subsidiyasi',   count: 98,  prev: 64,  topic: 'breeding' },
  { w: 'Bojxona to‘lovi',          count: 87,  prev: 92,  topic: 'logistic' },
  { w: 'Guruch sertifikati',       count: 76,  prev: 58,  topic: 'rice' },
  { w: 'Ombor ijarasi',            count: 71,  prev: 80,  topic: 'warehouse' },
  { w: 'Transport tariflari',      count: 68,  prev: 51,  topic: 'logistic' },
  { w: 'Sovutgich ombor',          count: 54,  prev: 48,  topic: 'warehouse' },
  { w: 'Kartoshka urugʻi',         count: 49,  prev: 32,  topic: 'potato' },
  { w: 'Piyoz narxi pasayishi',    count: 42,  prev: 18,  topic: 'onion' },
  { w: 'Qassobxona litsenziyasi',  count: 38,  prev: 41,  topic: 'beef' },
  { w: 'Un tegirmoni',             count: 35,  prev: 30,  topic: 'flour' },
  { w: 'Veterinariya xizmati',     count: 33,  prev: 28,  topic: 'breeding' },
  { w: 'Tuxum narxi',              count: 29,  prev: 33,  topic: 'poultry' },
  { w: 'Shakar kvotasi',           count: 27,  prev: 14,  topic: 'sugar' },
  { w: 'Logistika shartnomasi',    count: 25,  prev: 22,  topic: 'logistic' },
  { w: 'Un litsenziyasi',          count: 23,  prev: 19,  topic: 'flour' },
  { w: 'Shakar importi',           count: 22,  prev: 28,  topic: 'sugar' },
  { w: 'Lazerli sortlash',         count: 19,  prev: 9,   topic: 'rice' },
  { w: 'Paxta yogʻi',              count: 17,  prev: 11,  topic: 'oil' },
  { w: 'Piyoz narxnomasi',         count: 16,  prev: 13,  topic: 'onion' },
  { w: 'Mol-qoʻy yemi',            count: 15,  prev: 12,  topic: 'breeding' },
  { w: 'Kartoshka kasalligi',      count: 14,  prev: 6,   topic: 'potato' },
  { w: 'Un zaxirasi',              count: 13,  prev: 17,  topic: 'flour' },
  { w: 'Saqlash harorati',         count: 11,  prev: 8,   topic: 'potato' },
];

// Recent alerts
const ALERTS = [
  { sev: 'critical', uz: 'Piyoz narx tushishi {region} viloyatida 38% (anomaliya)', ru: 'Падение цены лука 38% в {region}', region: 'sam', topic: 'onion', mins: 12, ack: false },
  { sev: 'warning',  uz: 'Logistika murojaatlari +47% (24 soat)', region: 'qsh', topic: 'logistic', mins: 38, ack: false },
  { sev: 'warning',  uz: 'AI ishonchliligi 78% gacha tushdi (Naslchilik)', topic: 'breeding', mins: 64, ack: true },
  { sev: 'info',     uz: 'Yangi tahlilchi tizimga qoʻshildi: O. Nazarov',  mins: 145, ack: true },
  { sev: 'critical', uz: 'Mol goʻshti narxi 12% koʻtarildi (Fargʻona)', region: 'fer', topic: 'beef', mins: 220, ack: false },
];

// Notifications (top-bar dropdown)
const NOTIFICATIONS = [
  { kind: 'urgent', uz: 'Yangi shoshilinch murojaat: piyoz narxi', mins: 4 },
  { kind: 'anomaly', uz: 'Anomaliya: Logistika +47% bugun', mins: 18 },
  { kind: 'report', uz: 'Haftalik hisobot tayyor', mins: 42 },
  { kind: 'system', uz: 'Model qayta oʻrgatildi (v2.18)', mins: 88 },
  { kind: 'ack', uz: 'F. Tojiyeva ogohlantirishni tasdiqladi', mins: 124 },
];

// AI live metrics
const AI_METRICS = {
  accuracy: 0.913,
  confidenceAvg: 0.847,
  latencyMs: 142,
  langAccuracy: 0.973,
  misclassified: 218,
  processedToday: TODAY_COUNT,
};

// Funnel
const FUNNEL = [
  { uz: 'Qabul qilindi',    ru: 'Принято',        value: TOTAL },
  { uz: 'Tasniflandi',      ru: 'Классифициров.', value: TOTAL - STATUS_TOTALS.new },
  { uz: 'Yoʻnaltirildi',    ru: 'Маршрутизирован',value: TOTAL - STATUS_TOTALS.new - STATUS_TOTALS.classified },
  { uz: 'Javob berildi',    ru: 'Отвечено',       value: STATUS_TOTALS.answered + STATUS_TOTALS.resolved },
  { uz: 'Tasdiqlandi',      ru: 'Подтверждено',   value: STATUS_TOTALS.resolved },
];

// Telegram member count (simulated live)
const TG_MEMBERS = 18472;
const TG_DELTA = 47;

// Reconciled KPI deltas
function delta(today, prev) { return ((today - prev) / Math.max(prev, 1)) * 100; }

const KPIS = [
  { id: 'total',     uz: 'Jami xabarlar',     ru: 'Всего сообщений',   value: TOTAL,           unit: '',     spark: BY_DAY.slice(-14).map(d => d.total), delta: 4.2,  trend: 'up' },
  { id: 'questions', uz: 'Aniqlangan savollar', ru: 'Распознано вопросов', value: QUESTIONS,    unit: '',     spark: BY_DAY.slice(-14).map(d => Math.round(d.total * 0.62)), delta: 6.1, trend: 'up' },
  { id: 'open',      uz: 'Ochiq savollar',    ru: 'Открытых вопросов', value: OPEN_Q,          unit: '',     spark: BY_DAY.slice(-14).map(d => Math.round(d.total * 0.18 + 4)), delta: -2.4, trend: 'down' },
  { id: 'today',     uz: 'Bugun yangi',       ru: 'Новых сегодня',     value: TODAY_COUNT,     unit: '',     spark: BY_DAY.slice(-14).map(d => d.total), delta: delta(TODAY_COUNT, YESTERDAY_COUNT), trend: TODAY_COUNT >= YESTERDAY_COUNT ? 'up' : 'down' },
  { id: 'res',       uz: 'Bugun hal etildi',  ru: 'Решено сегодня',    value: RESOLVED_TODAY,  unit: '',     spark: BY_DAY.slice(-14).map(d => Math.round(d.total * 0.25)), delta: 8.7, trend: 'up' },
  { id: 'rt',        uz: 'Oʻrt. javob',       ru: 'Сред. ответ',       value: 23.4,            unit: 'daq',  spark: [28,26,27,25,24,24,26,25,23,24,23,22,24,23], delta: -3.2, trend: 'up' },
  { id: 'ai',        uz: 'AI aniqlik',        ru: 'Точность ИИ',       value: 91.3,            unit: '%',    spark: [88,89,90,89,90,91,91,91,91,92,91,91,92,91], delta: 0.8,  trend: 'up' },
  { id: 'urgent',    uz: 'Shoshilinch ochiq', ru: 'Срочных открытых',  value: URGENT_OPEN,     unit: '',     spark: BY_DAY.slice(-14).map(d => Math.round(d.total * 0.04 + 1)), delta: 14.2, trend: 'down' },
];

// ============================================================
// Hijri date (May 14, 2026 ~= Dhu al-Qa'dah 1447)
// ============================================================
const HIJRI = '26 Dhu al-Qaʿdah 1447';
const WEEKDAY_UZ = 'Payshanba';
const DATE_UZ = '14 May 2026';

// helpers
function formatRel(ts) {
  const ms = NOW - ts;
  const m = Math.floor(ms / 60000);
  if (m < 1) return 'hozir';
  if (m < 60) return `${m} daq`;
  const h = Math.floor(m / 60);
  if (h < 24) return `${h} soat`;
  const d = Math.floor(h / 24);
  return `${d} kun`;
}

function formatNum(n) {
  if (n >= 1000000) return (n / 1000000).toFixed(1) + 'M';
  if (n >= 10000) return (n / 1000).toFixed(1) + 'K';
  if (n >= 1000) return n.toLocaleString('en-US').replace(/,/g, ' ');
  return String(n);
}

// Export
Object.assign(window, {
  rand, randi, pick,
  TOPICS, TOPIC_BY_ID, TOPIC_WEIGHTS,
  REGIONS, REGION_BY_ID,
  FARMERS, ANALYSTS,
  INQUIRIES, BY_TOPIC, BY_REGION, BY_DAY, HEATMAP,
  STATUS_TOTALS, FUNNEL,
  KEYWORDS, ALERTS, NOTIFICATIONS,
  AI_METRICS, KPIS,
  TG_MEMBERS, TG_DELTA, NOW, HIJRI, WEEKDAY_UZ, DATE_UZ,
  TODAY_COUNT, YESTERDAY_COUNT, TOTAL, QUESTIONS, OPEN_Q, RESOLVED_TODAY, URGENT_OPEN,
  formatRel, formatNum, initials,
});
