/* global supabase */
// ============================================================
// سِنان كلينيك — Supabase Client & Data Service
// ============================================================

const { createClient } = window.supabase;

const SUPABASE_URL = 'https://ckoqgeebsezgelqinabn.supabase.co';
const SUPABASE_KEY = 'sb_publishable_DWrOlkHWOyCBRPZUrosepw_zX3hXcqn';

const SB = createClient(SUPABASE_URL, SUPABASE_KEY);

// ============================================================
// Data Mappers — Supabase format → App format
// ============================================================

function initials(name) {
  if (!name) return '؟';
  const parts = name.trim().split(' ');
  return parts.length >= 2 ? parts[0][0] + parts[1][0] : name.substring(0, 2);
}

function mapPatient(p) {
  return {
    id: p.id,
    name: p.name || '',
    age: p.age || 0,
    gender: p.gender || '',
    phone: p.phone || '',
    email: p.email || '',
    notes: p.notes || '',
    status: p.status || 'active',
    insurance: p.insurance || 'بدون تأمين',
    avatar: p.avatar || initials(p.name),
    balance: parseFloat(p.balance) || 0,
    lastVisit: p.last_visit || null,
    nextVisit: p.next_visit || null,
    doctor: p.doctors?.name || p.doctor_name || '',
    clinic_id: p.clinic_id,
    created_at: p.created_at,
  };
}

function mapDoctor(d) {
  return {
    id: d.id,
    name: d.name || '',
    specialty: d.specialty || '',
    color: d.color || '#0891b2',
    avatar: d.avatar || initials(d.name),
    status: d.status || 'متاح',
    patients: 0,
    rating: 4.8,
    clinic_id: d.clinic_id,
  };
}

function mapAppointment(a) {
  return {
    id: a.id,
    patient: a.patients?.name || '',
    patientId: a.patient_id,
    doctor: a.doctors?.name || '',
    doctorId: a.doctor_id,
    doctorColor: a.doctors?.color || '#0891b2',
    time: (a.time || '').substring(0, 5),
    duration: a.duration || 30,
    date: a.date || '',
    type: a.type || '',
    status: a.status || 'pending',
    room: a.room || '',
    notes: a.notes || '',
    clinic_id: a.clinic_id,
  };
}

function mapInvoice(inv, items) {
  const myItems = (items || []).filter(it => it.invoice_id === inv.id);
  return {
    id: inv.id,
    patient: inv.patients?.name || '',
    patientId: inv.patient_id,
    date: inv.date || '',
    total: parseFloat(inv.total) || 0,
    paid: parseFloat(inv.paid) || 0,
    status: inv.status || 'unpaid',
    notes: inv.notes || '',
    items: myItems.map(it => ({
      id: it.id,
      name: it.name || '',
      qty: it.qty || 1,
      price: parseFloat(it.price) || 0,
      discount: parseFloat(it.discount) || 0,
    })),
    clinic_id: inv.clinic_id,
  };
}

function mapInventoryItem(item) {
  return {
    id: item.id,
    name: item.name || '',
    category: item.category || '',
    stock: parseFloat(item.stock) || 0,
    minStock: parseFloat(item.min_stock) || 0,
    unit: item.unit || 'قطعة',
    price: parseFloat(item.price) || 0,
    supplier: item.supplier || '',
    expiry: item.expiry || '—',
    clinic_id: item.clinic_id,
  };
}

function mapService(s) {
  return {
    id: s.id,
    name: s.name || '',
    price: parseFloat(s.price) || 0,
    duration: s.duration || 30,
    category: s.category || '',
    clinic_id: s.clinic_id,
  };
}

// ============================================================
// CRUD Helpers
// ============================================================

const DB = {
  // --- Patients ---
  async addPatient(clinicId, data) {
    const { data: row, error } = await SB.from('patients')
      .insert({ ...data, clinic_id: clinicId, avatar: initials(data.name) })
      .select().single();
    if (error) throw error;
    return mapPatient(row);
  },
  async updatePatient(id, data) {
    const { data: row, error } = await SB.from('patients')
      .update(data).eq('id', id).select().single();
    if (error) throw error;
    return mapPatient(row);
  },
  async deletePatient(id) {
    const { error } = await SB.from('patients').delete().eq('id', id);
    if (error) throw error;
  },

  // --- Doctors ---
  async addDoctor(clinicId, data) {
    const { data: row, error } = await SB.from('doctors')
      .insert({ ...data, clinic_id: clinicId, avatar: initials(data.name) })
      .select().single();
    if (error) throw error;
    return mapDoctor(row);
  },
  async updateDoctor(id, data) {
    const { data: row, error } = await SB.from('doctors')
      .update(data).eq('id', id).select().single();
    if (error) throw error;
    return mapDoctor(row);
  },

  // --- Appointments ---
  async addAppointment(clinicId, data) {
    const { data: row, error } = await SB.from('appointments')
      .insert({ ...data, clinic_id: clinicId })
      .select('*, patients(name, avatar), doctors(name, color)').single();
    if (error) throw error;
    return mapAppointment(row);
  },
  async updateAppointment(id, data) {
    const { data: row, error } = await SB.from('appointments')
      .update(data).eq('id', id)
      .select('*, patients(name, avatar), doctors(name, color)').single();
    if (error) throw error;
    return mapAppointment(row);
  },
  async deleteAppointment(id) {
    const { error } = await SB.from('appointments').delete().eq('id', id);
    if (error) throw error;
  },

  // --- Invoices (with multiple items) ---
  async addInvoice(clinicId, invoiceData, items) {
    // 1. Insert invoice
    const total = items.reduce((s, it) => s + (it.qty * it.price - (it.discount || 0)), 0);
    const { data: inv, error: invErr } = await SB.from('invoices')
      .insert({ ...invoiceData, clinic_id: clinicId, total })
      .select('*, patients(name)').single();
    if (invErr) throw invErr;

    // 2. Insert items
    if (items.length > 0) {
      const itemRows = items.map(it => ({
        invoice_id: inv.id,
        service_id: it.service_id || null,
        name: it.name,
        qty: it.qty || 1,
        price: it.price || 0,
        discount: it.discount || 0,
      }));
      const { error: itemErr } = await SB.from('invoice_items').insert(itemRows);
      if (itemErr) throw itemErr;
    }

    // 3. Fetch invoice items and return
    const { data: invItems } = await SB.from('invoice_items').select('*').eq('invoice_id', inv.id);
    return mapInvoice(inv, invItems || []);
  },

  async updateInvoicePaid(id, paid) {
    const totalRes = await SB.from('invoices').select('total').eq('id', id).single();
    const total = totalRes.data?.total || 0;
    const status = paid >= total ? 'paid' : paid > 0 ? 'partial' : 'unpaid';
    const { data: row, error } = await SB.from('invoices')
      .update({ paid, status }).eq('id', id)
      .select('*, patients(name)').single();
    if (error) throw error;
    const { data: items } = await SB.from('invoice_items').select('*').eq('invoice_id', id);
    return mapInvoice(row, items || []);
  },

  // --- Services ---
  async addService(clinicId, data) {
    const { data: row, error } = await SB.from('services')
      .insert({ ...data, clinic_id: clinicId }).select().single();
    if (error) throw error;
    return mapService(row);
  },

  // --- Inventory ---
  async addInventoryItem(clinicId, data) {
    const { data: row, error } = await SB.from('inventory')
      .insert({ ...data, clinic_id: clinicId }).select().single();
    if (error) throw error;
    return mapInventoryItem(row);
  },
  async updateInventoryItem(id, data) {
    const { data: row, error } = await SB.from('inventory')
      .update(data).eq('id', id).select().single();
    if (error) throw error;
    return mapInventoryItem(row);
  },

  // --- Purchase Invoice (auto-updates inventory via trigger) ---
  async addPurchaseInvoice(clinicId, purchaseData, items) {
    const total = items.reduce((s, it) => s + it.qty * it.unit_price, 0);
    const { data: purchase, error } = await SB.from('purchase_invoices')
      .insert({ ...purchaseData, clinic_id: clinicId, total }).select().single();
    if (error) throw error;

    if (items.length > 0) {
      const rows = items.map(it => ({
        purchase_invoice_id: purchase.id,
        inventory_id: it.inventory_id || null,
        name: it.name,
        qty: it.qty,
        unit_price: it.unit_price,
      }));
      const { error: itemErr } = await SB.from('purchase_invoice_items').insert(rows);
      if (itemErr) throw itemErr;
    }
    return purchase;
  },

  // --- Physical Count (auto-updates inventory via trigger) ---
  async addPhysicalCount(clinicId, inventoryId, actualCount, notes) {
    const { data: row, error } = await SB.from('physical_counts')
      .insert({ clinic_id: clinicId, inventory_id: inventoryId, actual_count: actualCount, notes })
      .select().single();
    if (error) throw error;
    return row;
  },

  // --- Expenses ---
  async addExpense(clinicId, data) {
    const { data: row, error } = await SB.from('expenses')
      .insert({ ...data, clinic_id: clinicId }).select().single();
    if (error) throw error;
    return row;
  },

  // --- Staff ---
  async addStaff(clinicId, data) {
    const { data: row, error } = await SB.from('staff')
      .insert({ ...data, clinic_id: clinicId, avatar: initials(data.name) }).select().single();
    if (error) throw error;
    return row;
  },
};

// ============================================================
// Load all data for a clinic
// ============================================================
async function loadClinicData(clinicId) {
  const safe = (p) => p.catch(e => { console.warn('[Senan] query failed:', e); return { data: null, error: e }; });

  const [
    { data: pts },
    { data: docs },
    { data: apts },
    { data: invs },
    { data: invItems },
    { data: inv },
    { data: svcs },
    { data: stf },
    { data: exp },
  ] = await Promise.all([
    safe(SB.from('patients').select('*').eq('clinic_id', clinicId).order('created_at', { ascending: false })),
    safe(SB.from('doctors').select('*').eq('clinic_id', clinicId).order('name')),
    safe(SB.from('appointments').select('*, patients(name, avatar), doctors(name, color)').eq('clinic_id', clinicId).order('date').order('time')),
    safe(SB.from('invoices').select('*, patients(name)').eq('clinic_id', clinicId).order('created_at', { ascending: false })),
    safe(SB.from('invoice_items').select('*')),
    safe(SB.from('inventory').select('*').eq('clinic_id', clinicId).order('name')),
    safe(SB.from('services').select('*').eq('clinic_id', clinicId).order('name')),
    safe(SB.from('staff').select('*').eq('clinic_id', clinicId)),
    safe(SB.from('expenses').select('*').eq('clinic_id', clinicId).order('date', { ascending: false })),
  ]);

  const mappedInvs = (invs || []).map(inv => mapInvoice(inv, invItems || []));

  return {
    patients:     (pts     || []).map(mapPatient),
    doctors:      (docs    || []).map(mapDoctor),
    appointments: (apts    || []).map(mapAppointment),
    invoices:     mappedInvs,
    inventory:    (inv     || []).map(mapInventoryItem),
    services:     (svcs    || []).map(mapService),
    staff:        stf  || [],
    expenses:     exp  || [],
  };
}

// Expose globally
Object.assign(window, { SB, DB, loadClinicData, mapPatient, mapDoctor, mapAppointment, mapInvoice, mapInventoryItem, mapService, initials });
