// Gemini live discovery — يبحث في Google مباشرة عن المسابقات العالمية المفتوحة
// المفتاح: يمكن تغييره من الكونسول: localStorage.setItem('ibtikar_gem_key','AQ...')
const GEM_KEY = (typeof localStorage !== 'undefined' && localStorage.getItem('ibtikar_gem_key')) || 'AQ.Ab8RN6K4WMTVpJUOgpqGXDu9kW7i7MXX6tOxlIUwswJzdE8yHw';
// مصادر تُقرأ عبر أداة url_context عند تعذر بحث Google (خطة بديلة بحصة Flash-Lite الكبيرة)
const GEM_RSS = () => {
  const y = new Date().getFullYear(), g = (q, ar) => 'https://news.google.com/rss/search?q=' + encodeURIComponent(q + ' when:45d') + (ar ? '&hl=ar&gl=SA&ceid=SA:ar' : '&hl=en-US&gl=US&ceid=US:en');
  return [
    ['health hackathon registration open ' + y, 'medical AI challenge competition ' + y, 'digital health innovation competition apply ' + y].map((q) => g(q, false)),
    ['healthcare innovation prize open call ' + y, 'medtech startup competition applications ' + y].map((q) => g(q, false)).concat('https://devpost.com/api/hackathons?search=health&status[]=open&status[]=upcoming'),
    ['هاكاثون صحي التسجيل ' + y, 'مسابقة ابتكار صحي ' + y, 'تحدي الذكاء الاصطناعي في الصحة'].map((q) => g(q, true)),
    GEM_WATCH.map((w) => w.url),
  ];
};
// قائمة مراقبة: مسابقات وجوائز كبرى متكررة تُفحص صفحاتها الرسمية مباشرة في كل تشغيل
const GEM_WATCH = [
  { name: 'Hello Tomorrow Challenge', url: 'https://hello-tomorrow.org/global-challenge/' },
  { name: 'MIT Solve', url: 'https://solve.mit.edu/challenges' },
  { name: 'XPRIZE', url: 'https://www.xprize.org/prizes' },
  { name: 'EIC Accelerator', url: 'https://eic.ec.europa.eu/eic-funding-opportunities/eic-accelerator_en' },
  { name: 'Geneva Inventions', url: 'https://www.inventions-geneva.ch/en/' },
  { name: 'James Dyson Award', url: 'https://www.jamesdysonaward.org/' },
  { name: 'Hult Prize', url: 'https://www.hultprize.org/' },
  { name: 'Challenge.gov', url: 'https://www.challenge.gov/' },
  { name: 'Kaggle', url: 'https://www.kaggle.com/competitions' },
  { name: 'Grand Challenge', url: 'https://grand-challenge.org/challenges/' },
];
const GEM_API = 'https://generativelanguage.googleapis.com/v1beta/models';
const GEM_TOPICS = [
  { ar: 'تحديات الذكاء الاصطناعي الطبي (Kaggle · grand-challenge · MICCAI)', q: 'Global medical AI and healthcare data science competitions on Kaggle, DrivenData, grand-challenge.org, AIcrowd, Zindi, PhysioNet and MICCAI challenges' },
  { ar: 'هاكاثونات الصحة الرقمية (Devpost · MLH · MIT)', q: 'Online and in-person health, medtech and digital health hackathons on Devpost, MLH, Lablab.ai, MIT Hacking Medicine' },
  { ar: 'تحديات Google · Gemini · Microsoft · NVIDIA', q: 'Google, Gemini API, Google for Startups, Microsoft, NVIDIA, AWS, OpenAI developer challenges or accelerators accepting healthcare AI projects' },
  { ar: 'جوائز عالمية (XPRIZE · MIT Solve · WHO · Gates)', q: 'Global health innovation prizes and open calls: XPRIZE, MIT Solve, WHO, Wellcome Leap, Gates Grand Challenges, UNICEF, Challenge.gov, NIH, ARPA-H' },
  { ar: 'أوروبا وبريطانيا (EIC · EIT Health · Innovate UK)', q: 'European and UK health innovation calls: EIC Accelerator, Horizon Europe health, EIT Health, Innovate UK, NHS innovation competitions' },
  { ar: 'مسابقات طلابية دولية', q: 'Student and early-career medical innovation competitions and research awards open internationally' },
  { ar: 'السعودية (الصحة · سدايا · كاوست · منشآت)', q: "Saudi Arabia health innovation competitions, hackathons and awards (MOH, SDAIA, KAUST, KACST, Monsha'at, Misk, Health Holding)" },
  { ar: 'الخليج ومصر والأردن', q: 'UAE, Qatar, Kuwait, Bahrain, Oman, Egypt, Jordan health and AI innovation competitions and hackathons' },
];
const GEM_SYS = (today) => `You find CURRENTLY OPEN competitions, hackathons, challenges, prizes and funded open calls in medicine, digital health, medical AI and innovation — including deep-tech / science startup competitions that have a health, biotech or medtech track (e.g. Hello Tomorrow), and invention exhibitions and invention awards. Use Google Search. Today is ${today}. Only include items open now or opening within 60 days, deadline today or later. Use the OFFICIAL page URL.
Return ONLY a JSON array, no prose. Each item:
{"title":"Arabic title","en":"original English title","org":"organizer","country":"one of: دولي | الولايات المتحدة | أوروبا | ألمانيا | سويسرا | المملكة المتحدة | السعودية | الإمارات | قطر | مصر | الكويت | البحرين | عُمان | الأردن","field":"one of: طب | طب + ذكاء اصطناعي | ذكاء اصطناعي | هاكاثون | ابتكار","hack":true/false,"deadline":"YYYY-MM-DD or null","prize":"number only or null","cur":"USD|EUR|SAR|null","desc":"1-2 sentence Arabic description","url":"official url"}
Return 8-20 items in total.`;

// ── سلسلة المزودين: إذا رفض نموذج يتولى التالي تلقائياً ──
// مفتاح Z.ai (GLM-4.5-Flash مجاني + بحث ويب): من https://z.ai/manage-apikey/apikey-list
const ZAI_KEY = '';

let gemChainCache = null;
async function gemBuildChain() {
  if (gemChainCache) return gemChainCache;
  let names = [];
  try {
    const r = await fetch(`${GEM_API}?pageSize=1000`, { headers: { 'x-goog-api-key': GEM_KEY } });
    const j = await r.json();
    names = (j.models || []).filter((m) => (m.supportedGenerationMethods || []).includes('generateContent')).map((m) => m.name.replace(/^models\//, ''));
  } catch (e) {}
  const ver = (n) => parseFloat((n.match(/^gemini-(\d+(?:\.\d+)?)/) || [0, 0])[1]);
  const tier = (t) => names.filter((n) => new RegExp(`^gemini-\\d+(\\.\\d+)?-${t}(-preview)?(-[\\d-]+)?$`).test(n)).sort((x, y) => ver(y) - ver(x) || x.length - y.length);
  const has = (n) => !names.length || names.includes(n);
  // 1) بحث Google المباشر (Grounding) — مجاني على نماذج 2.5 فقط؛ Flash-Lite أولاً لأن حصته أكبر
  const search = ['gemini-2.5-flash-lite', 'gemini-2.5-flash'].filter(has).map((m) => ({ prov: 'gemini', model: m, mode: 'search' }));
  // 2) بديل: قراءة خلاصات Google News و Devpost عبر url_context
  const lite = [...new Set(['gemini-flash-lite-latest', ...tier('flash-lite').slice(0, 2), 'gemini-2.5-flash-lite'])].filter((n) => has(n) && !/pro/.test(n));
  const url = lite.map((m) => ({ prov: 'gemini', model: m, mode: 'url' }));
  gemChainCache = [...search, ...url, ...(ZAI_KEY ? [{ prov: 'zai', model: 'glm-4.5-flash' }] : [])];
  return gemChainCache;
}
const gemSleep = (ms) => new Promise((r) => setTimeout(r, ms));
const gemLabel = (e) => (e.prov === 'zai' ? 'Z.ai ' : '') + e.model + (e.mode === 'url' ? ' · RSS' : e.mode === 'search' ? ' · Search' : '');

async function gemCall(entry, prompt, sys, gi) {
  if (entry.prov === 'zai') {
    const r = await fetch('https://api.z.ai/api/paas/v4/chat/completions', {
      method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + ZAI_KEY },
      body: JSON.stringify({ model: entry.model, temperature: 0.2, messages: [{ role: 'system', content: sys.replace('Use Google Search', 'Use web search') }, { role: 'user', content: prompt }], tools: [{ type: 'web_search', web_search: { enable: true, search_result: true } }] }),
    });
    const j = await r.json().catch(() => ({}));
    if (!r.ok) { const e = new Error((j.error && j.error.message) || 'Z.ai HTTP ' + r.status); e.status = r.status; throw e; }
    return (j.choices && j.choices[0] && j.choices[0].message && j.choices[0].message.content) || '';
  }
  const r = await fetch(`${GEM_API}/${entry.model}:generateContent`, {
    method: 'POST', headers: { 'Content-Type': 'application/json', 'x-goog-api-key': GEM_KEY },
    body: JSON.stringify(entry.mode === 'url'
      ? { systemInstruction: { parts: [{ text: sys.replace('Use Google Search.', 'Read the provided feed URLs with the URL context tool; keep only real competitions from them and use the article or official URL found there.') }] }, contents: [{ role: 'user', parts: [{ text: prompt + '\n\nSources to read:\n' + GEM_RSS()[Math.min(gi, 3)].join('\n') }] }], tools: [{ url_context: {} }], generationConfig: { temperature: 0.1 } }
      : { systemInstruction: { parts: [{ text: sys }] }, contents: [{ role: 'user', parts: [{ text: prompt }] }], tools: [{ google_search: {} }], generationConfig: { temperature: 0.2 } }),
  });
  const j = await r.json().catch(() => ({}));
  if (!r.ok) { const e = new Error((j.error && j.error.message) || 'HTTP ' + r.status); e.status = r.status; throw e; }
  return ((j.candidates && j.candidates[0] && j.candidates[0].content && j.candidates[0].content.parts) || []).map((p) => p.text || '').join('');
}

function gemParse(txt) {
  const t = String(txt).replace(/```json|```/gi, ''), s = t.indexOf('['), e = t.lastIndexOf(']');
  if (s < 0 || e <= s) return [];
  try { const a = JSON.parse(t.slice(s, e + 1)); return Array.isArray(a) ? a : []; } catch (x) { return []; }
}

const gemKeyOf = (c) => String(c.url || c.en || c.title || '').toLowerCase().replace(/^https?:\/\/(www\.)?/, '').replace(/[?#].*$/, '').replace(/\/+$/, '');

// onStep({ i, total, label, found, model }) · returns { items, model, errors }
async function engGeminiDiscover(known, onStep) {
  const chain = await gemBuildChain();
  let ci = 0;
  const today = new Date().toISOString().slice(0, 10), sys = GEM_SYS(today);
  const seen = new Set((known || []).map(gemKeyOf)), items = [], errors = [];
  // دمج المحاور في 3 طلبات فقط لتوفير الحصة المجانية
  const GROUPS = [[0, 1, 2], [3, 4, 5], [6, 7]].map((ix) => ({ ar: ix.map((k) => GEM_TOPICS[k].ar.split(' (')[0]).join(' · '), q: ix.map((k, n) => (n + 1) + ') ' + GEM_TOPICS[k].q).join('\n') }));
  GROUPS.push({ ar: 'قائمة المراقبة: ' + GEM_WATCH.slice(0, 4).map((w) => w.name).join(' · ') + '…', q: 'Check each official page below. For every competition, challenge, prize or award whose applications are currently open or open within 60 days, return it (a deep-tech competition counts if it accepts health/biotech/medtech projects). Take the deadline from the page.', watch: true });
  for (let i = 0; i < GROUPS.length; i++) {
    const tp = GROUPS[i];
    let txt = '', waited = false;
    if (tp.watch) {
      const we = chain.find((e) => e.mode === 'url');
      if (we) {
        onStep && onStep({ i, total: GROUPS.length, label: tp.ar, found: items.length, model: gemLabel(we) });
        try { txt = await gemCall(we, tp.q, sys, 3); } catch (e) { errors.push(gemLabel(we) + ': ' + e.message); }
      }
    }
    while (!tp.watch && ci < chain.length) {
      const model = gemLabel(chain[ci]);
      onStep && onStep({ i, total: GROUPS.length, label: tp.ar, found: items.length, model });
      try { txt = await gemCall(chain[ci], `Find open opportunities for each of these areas:\n${tp.q}`, sys, i); if (!gemParse(txt).length && chain[ci].mode === 'url' && ci < chain.length - 1) throw Object.assign(new Error('رد فارغ'), { status: 0 }); break; }
      catch (e) {
        errors.push(model + ': ' + e.message);
        if (e.status === 429 && !waited && !/limit: ?0|per ?day|PerDay/i.test(e.message)) { waited = true; onStep && onStep({ i, total: GROUPS.length, label: tp.ar + ' · انتظار الحد…', found: items.length, model }); await gemSleep(20000); continue; }
        ci += 1; waited = false; // النموذج رفض ← التالي
      }
    }
    gemParse(txt).forEach((x, n) => {
      if (!x || !x.title || !x.url) return;
      if (x.deadline && !/^\d{4}-\d{2}-\d{2}$/.test(x.deadline)) x.deadline = null;
      if (x.deadline && new Date(x.deadline + 'T23:59:59') < new Date()) return;
      const k = gemKeyOf(x);
      if (seen.has(k)) return;
      seen.add(k);
      const field = ['طب', 'طب + ذكاء اصطناعي', 'ذكاء اصطناعي', 'هاكاثون', 'ابتكار'].includes(x.field) ? x.field : 'ابتكار';
      items.push({
        id: 'gem_' + Date.now().toString(36) + '_' + i + '_' + n,
        title: x.title, en: x.en || '', org: x.org || '—', country: x.country || 'دولي', field, url: x.url,
        deadline: x.deadline || null, prize: x.prize ? String(x.prize).replace(/[^\d]/g, '') || null : null, cur: x.prize ? (x.cur || 'USD') : '',
        desc: x.desc || '', hack: !!x.hack || field === 'هاكاثون', medical: /طب/.test(field), ai: /ذكاء/.test(field), gemini: true, foundAt: today,
      });
    });
    if (i < GROUPS.length - 1) await gemSleep(7000); // مراعاة حد الخطة المجانية (~10 طلبات/دقيقة)
  }
  const model = chain[Math.min(ci, chain.length - 1)] ? gemLabel(chain[Math.min(ci, chain.length - 1)]) : '—';
  onStep && onStep({ i: GROUPS.length, total: GROUPS.length, label: '✓', found: items.length, model });
  return { items, model, errors: items.length ? [] : [errors[0] || ''].concat(errors.length > 1 ? ['(+' + (errors.length - 1) + ')'] : []).filter(Boolean) };
}

Object.assign(window, { engGeminiDiscover, GEM_TOPICS });
