// supabase.jsx — client, auth, and customer persistence.
// The publishable key is safe to ship: Row Level Security protects the data.

const SUPABASE_URL = 'https://ysvxpakiwrudnbyvoghc.supabase.co';
const SUPABASE_KEY = 'sb_publishable_gF7hQ4990H-2ApO7A1WOOg_FIXgGWaC';

const sbClient = supabase.createClient(SUPABASE_URL, SUPABASE_KEY, {
  auth: { persistSession: true, autoRefreshToken: true, detectSessionInUrl: true },
});

// ── mappers: DB row <-> the app's customer object ──
// The full UI customer object lives in the `data` JSONB column. A few fields are
// promoted to real columns (name, nurturing, ready_date, confirmed) for queries + RLS.
function dbToUi(row) {
  const data = row.data || {};
  return {
    ...data,
    id: row.id,                                   // DB uuid is canonical
    name: data.name ?? row.name,
    nurturing: row.nurturing ?? data.nurturing ?? false,
    readyDate: row.ready_date ?? data.readyDate ?? null,
  };
}

function uiToDb(cust, userId) {
  const { id, ...doc } = cust;                     // strip client id; DB owns id
  const out = {
    name: cust.name || 'Unnamed',
    nurturing: !!cust.nurturing,
    ready_date: cust.readyDate || null,
    confirmed: cust.confirmed ?? true,
    data: doc,
  };
  if (userId) out.user_id = userId;
  return out;
}

// ── auth ──
const SBAuth = {
  async getSession() {
    const { data } = await sbClient.auth.getSession();
    return data.session;
  },
  onChange(cb) {
    return sbClient.auth.onAuthStateChange((_event, session) => cb(session));
  },
  async signIn(email) {
    return sbClient.auth.signInWithOtp({
      email: email.trim(),
      options: { emailRedirectTo: window.location.origin + window.location.pathname },
    });
  },
  async verifyCode(email, token) {
    return sbClient.auth.verifyOtp({ email: email.trim(), token: token.trim(), type: 'email' });
  },
  async signOut() {
    return sbClient.auth.signOut();
  },
};

// ── customer CRUD ──
const SBData = {
  async load() {
    const { data, error } = await sbClient
      .from('customers').select('*')
      .is('deleted_at', null)
      .order('created_at', { ascending: false });
    if (error) { console.error('SBData.load', error); return []; }
    return data.map(dbToUi);
  },
  async create(cust, userId) {
    const { data, error } = await sbClient
      .from('customers').insert(uiToDb(cust, userId)).select().single();
    if (error) { console.error('SBData.create', error); return null; }
    return dbToUi(data);
  },
  async update(cust) {
    const patch = uiToDb(cust);                    // no user_id on update
    const { data, error } = await sbClient
      .from('customers').update(patch).eq('id', cust.id).select().single();
    if (error) { console.error('SBData.update', error); return null; }
    return dbToUi(data);
  },
  async remove(id) {                                // soft delete
    const { error } = await sbClient
      .from('customers').update({ deleted_at: new Date().toISOString() }).eq('id', id);
    if (error) console.error('SBData.remove', error);
  },
};

// ── AI capture (Cloudflare Worker reads a photo with Claude Haiku vision) ──
// Set AI_API to the deployed Worker URL (see worker/). Until then, photo→AI is off.
const AI_API = window.AI_API_URL || 'https://alex-crm-api.aeguevara0204.workers.dev';
const AI = {
  configured() { return !AI_API.includes('REPLACE'); },
  async fromPhoto(base64, mediaType) {
    const { data } = await sbClient.auth.getSession();
    const token = data.session && data.session.access_token;
    const res = await fetch(AI_API + '/capture/photo', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + token },
      body: JSON.stringify({ image: base64, mediaType, today: new Date().toISOString().slice(0, 10) }),
    });
    if (!res.ok) { const t = await res.text().catch(() => ''); throw new Error('AI ' + res.status + ' ' + t); }
    return res.json();
  },
};

Object.assign(window, { sbClient, SBAuth, SBData, AI });
