// petal-api.jsx — the data layer. One API surface, two backends:
//   • DEMO  (no Supabase keys): browser localStorage + window.claude. Lets you
//            preview the whole app, including the sign-in screen, with no setup.
//   • LIVE  (keys in petal-config.js): Supabase Auth + Postgres + an Edge
//            Function that proxies the AI so your API key stays secret.
// Everything the rest of the app needs goes through window.PetalAPI.

const _cfg = window.PETAL_CONFIG || {};
const LIVE = !!(_cfg.SUPABASE_URL && _cfg.SUPABASE_ANON_KEY);
let _sb = null;

function _loadScript(src) {
  return new Promise((res, rej) => {
    const s = document.createElement('script');
    s.src = src; s.onload = res; s.onerror = rej;
    document.head.appendChild(s);
  });
}

async function _init() {
  if (LIVE && !_sb) {
    await _loadScript('https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2.45.4/dist/umd/supabase.min.js');
    _sb = window.supabase.createClient(_cfg.SUPABASE_URL, _cfg.SUPABASE_ANON_KEY);
  }
}

// ── DEMO storage ─────────────────────────────────────────────
const SKEY = 'petal.sessions.v1';
const UKEY = 'petal.demoUser';
const HKEY = 'petal.health';
// demo only: guess a role from the typed email so you can preview either side
function _demoRoleForEmail(email) {
  const e = String(email || '').toLowerCase();
  const d = String((window.PETAL_CONFIG || {}).DOCTOR_NAME || 'nuno').toLowerCase();
  return e.includes(d) || e.includes('doctor') ? 'doctor' : 'patient';
}
const _demo = {
  load() { try { return JSON.parse(localStorage.getItem(SKEY)) || []; } catch (e) { return []; } },
  save(l) { localStorage.setItem(SKEY, JSON.stringify(l)); },
  seed() { if (!this.load().length) this.save(DEMO_SEED()); },
};

// ── LIVE row mapping ─────────────────────────────────────────
function rowToApp(r) {
  return {
    id: r.id, startedAt: r.created_at ? Date.parse(r.created_at) : Date.now(),
    concern: r.concern, severity: r.severity, qa: r.qa || [],
    summary: r.summary || '', status: r.status || 'pending', doctorNote: r.doctor_note || '',
  };
}
function appToRow(s) {
  const r = {};
  if ('concern' in s) r.concern = s.concern;
  if ('severity' in s) r.severity = s.severity;
  if ('qa' in s) r.qa = s.qa;
  if ('summary' in s) r.summary = s.summary;
  if ('status' in s) r.status = s.status;
  if ('doctorNote' in s) r.doctor_note = s.doctorNote;
  if ('startedAt' in s) r.created_at = new Date(s.startedAt).toISOString();
  return r;
}

// ── public API ───────────────────────────────────────────────
const PetalAPI = {
  LIVE,
  async init() { await _init(); },

  auth: {
    // returns { id, email, role, name } or null
    async current() {
      if (!LIVE) { try { return JSON.parse(localStorage.getItem(UKEY)); } catch (e) { return null; } }
      const { data: { user } } = await _sb.auth.getUser();
      if (!user) return null;
      let profile = null;
      try { const { data } = await _sb.from('profiles').select('*').eq('id', user.id).single(); profile = data; } catch (e) {}
      return { id: user.id, email: user.email, role: (profile && profile.role) || 'patient', name: (profile && profile.display_name) || user.email };
    },
    async signIn(email, password) {
      if (!LIVE) throw new Error('demo');
      const { error } = await _sb.auth.signInWithPassword({ email, password });
      if (error) throw error;
    },
    // email OTP (passwordless) — the primary sign-in
    async sendOtp(email) {
      if (!LIVE) return; // demo: pretend we sent one
      const { error } = await _sb.auth.signInWithOtp({ email, options: { shouldCreateUser: false } });
      if (error) throw error;
    },
    async verifyOtp(email, code) {
      if (!LIVE) return PetalAPI.auth.demoSignIn(_demoRoleForEmail(email));
      const { error } = await _sb.auth.verifyOtp({ email, token: code, type: 'email' });
      if (error) throw error;
      return await PetalAPI.auth.current();
    },
    async signOut() {
      if (!LIVE) { localStorage.removeItem(UKEY); return; }
      await _sb.auth.signOut();
    },
    // demo only — lets the preview explore either role
    demoSignIn(role) {
      const u = role === 'doctor'
        ? { id: 'demo-d', email: 'demo', role: 'doctor', name: PEOPLE.doctor }
        : { id: 'demo-p', email: 'demo', role: 'patient', name: PEOPLE.patient };
      localStorage.setItem(UKEY, JSON.stringify(u));
      return u;
    },
  },

  async listSessions() {
    if (!LIVE) { _demo.seed(); return _demo.load(); }
    const { data, error } = await _sb.from('sessions').select('*').order('created_at', { ascending: false });
    if (error) { console.warn('listSessions', error); return []; }
    return (data || []).map(rowToApp);
  },

  async addSession(s) {
    if (!LIVE) { const l = _demo.load(); l.unshift(s); _demo.save(l); return; }
    const { error } = await _sb.from('sessions').insert(appToRow(s));
    if (error) console.warn('addSession', error);
  },

  async updateSession(id, patch) {
    if (!LIVE) { _demo.save(_demo.load().map(x => x.id === id ? { ...x, ...patch } : x)); return; }
    const { error } = await _sb.from('sessions').update(appToRow(patch)).eq('id', id);
    if (error) console.warn('updateSession', error);
  },

  // ── health profile (shared, single record) ──
  async getHealth() {
    if (!LIVE) {
      try { const h = JSON.parse(localStorage.getItem(HKEY)); if (h) return h; } catch (e) {}
      const seed = DEMO_HEALTH(); localStorage.setItem(HKEY, JSON.stringify(seed)); return seed;
    }
    const { data } = await _sb.from('health_profile').select('*').limit(1).maybeSingle();
    return data ? (data.data || {}) : {};
  },
  async saveHealth(data) {
    if (!LIVE) { localStorage.setItem(HKEY, JSON.stringify(data)); return; }
    const { data: existing } = await _sb.from('health_profile').select('id').limit(1).maybeSingle();
    if (existing) await _sb.from('health_profile').update({ data, updated_at: new Date().toISOString() }).eq('id', existing.id);
    else await _sb.from('health_profile').insert({ data });
  },

  // ask Posy for the next turn (questions or wrap-up)
  async askPosy(messages, rounds) {
    let health = null, past = [];
    try { health = await PetalAPI.getHealth(); } catch (e) {}
    try { past = await PetalAPI.listSessions(); } catch (e) {}
    const prompt = buildPosyPrompt(messages, rounds, { health, past });
    let text;
    if (!LIVE) {
      try { text = await window.claude.complete({ messages: [{ role: 'user', content: prompt }] }); }
      catch (e) { return fallbackTurn(rounds); }
    } else {
      try {
        const { data: { session } } = await _sb.auth.getSession();
        const res = await fetch(`${_cfg.SUPABASE_URL}/functions/v1/posy`, {
          method: 'POST',
          headers: {
            'content-type': 'application/json',
            'apikey': _cfg.SUPABASE_ANON_KEY,
            'Authorization': `Bearer ${session ? session.access_token : _cfg.SUPABASE_ANON_KEY}`,
          },
          body: JSON.stringify({ prompt }),
        });
        if (!res.ok) return fallbackTurn(rounds);
        const j = await res.json();
        text = j.text;
      } catch (e) { return fallbackTurn(rounds); }
    }
    return normalizePosy(parseLoose(text), rounds);
  },
};

window.PetalAPI = PetalAPI;
