// Billing model: campañas, facturas, pagos.
// Everything lives in localStorage so the admin panel (separate HTML, same origin)
// can read/write the same state and changes reflect in the vendedora app.

const BILLING_STORAGE_KEY = 'inova-billing-v1';
const VENDEDORAS_STORAGE_KEY = 'inova-vendedoras-v1';
const SESSION_KEY = 'inova-session-v1';

// ——— Campaign defaults (editable from admin) ———
// Each campaign lasts ~15 days; pedido day is fixed (normally Friday), and the 3 payment
// cuotas are the 3 Fridays after the pedido day.
function friday(date) {
  const d = new Date(date);
  const day = d.getDay();
  const diff = (5 - day + 7) % 7 || 7; // next Friday (never today)
  d.setDate(d.getDate() + diff);
  d.setHours(0, 0, 0, 0);
  return d;
}

function defaultCampaigns() {
  // Build a rolling 6 campaigns: 3 past, current, 2 future.
  const base = new Date(2026, 3, 3); // April 3 2026 Friday (C06 pedido day)
  const out = [];
  for (let i = 0; i < 6; i++) {
    const pedidoDay = new Date(base);
    pedidoDay.setDate(base.getDate() + i * 15);
    const [c1, c2, c3] = [friday(pedidoDay), friday(friday(pedidoDay)), friday(friday(friday(pedidoDay)))];
    const num = 6 + i;
    out.push({
      id: `C${String(num).padStart(2, '0')}`,
      nombre: `C${String(num).padStart(2, '0')} / 2026`,
      pedidoDay: pedidoDay.toISOString(),
      cuotas: [c1.toISOString(), c2.toISOString(), c3.toISOString()],
      porcentajes: [34, 33, 33], // split
      descuentoVendedora: 20,
      empresaPagoMovil: '0412-3334455',
      empresaBanco: 'Banesco',
      empresaCedula: 'J-30445566-7',
    });
  }
  return out;
}

function defaultVendedoras() {
  return [
    { id: 'v1', nombre: 'María Pérez', telefono: '04121234567', email: 'maria@inova.ve', zona: 'Valencia', clave: '1234', puntualidadStreak: 3 /* campañas seguidas a tiempo */, badge: 'puntual' },
    { id: 'v2', nombre: 'Carolina Mendoza', telefono: '04247778888', email: 'carolina@inova.ve', zona: 'Caracas', clave: '1234', puntualidadStreak: 1 },
    { id: 'v3', nombre: 'Ana Rojas', telefono: '04145556677', email: 'ana@inova.ve', zona: 'Turmero', clave: '1234', puntualidadStreak: 0 },
  ];
}

function loadBilling() {
  try {
    const raw = localStorage.getItem(BILLING_STORAGE_KEY);
    if (raw) return JSON.parse(raw);
  } catch {}
  const initial = {
    campaigns: defaultCampaigns(),
    facturas: [],   // {id, vendedoraId, campaignId, pedidoId, total, descuentoPct, aPagar, cuotas:[{fecha, monto, status}], createdAt}
    pagos: [],      // {id, facturaId, vendedoraId, monto, metodo, banco, referencia, fecha, capturaDataUrl, nota, status, createdAt, verifiedAt, rejectReason}
    retiros: [],    // {id, facturaId, codigo, retirado:bool, createdAt}
  };
  saveBilling(initial);
  return initial;
}

function saveBilling(state) {
  try { localStorage.setItem(BILLING_STORAGE_KEY, JSON.stringify(state)); } catch {}
}

function loadVendedoras() {
  try {
    const raw = localStorage.getItem(VENDEDORAS_STORAGE_KEY);
    if (raw) return JSON.parse(raw);
  } catch {}
  const v = defaultVendedoras();
  saveVendedoras(v);
  return v;
}
function saveVendedoras(v) {
  try { localStorage.setItem(VENDEDORAS_STORAGE_KEY, JSON.stringify(v)); } catch {}
}

function loadSession() {
  try { return JSON.parse(localStorage.getItem(SESSION_KEY) || 'null'); } catch { return null; }
}
function saveSession(s) {
  try {
    if (s) localStorage.setItem(SESSION_KEY, JSON.stringify(s));
    else localStorage.removeItem(SESSION_KEY);
  } catch {}
}

// ——— Factura creation ———
function createFacturaFromPedido({ pedido, vendedoraId, campaignId }) {
  const state = loadBilling();
  const campaign = state.campaigns.find(c => c.id === campaignId) || state.campaigns[state.campaigns.length - 1];
  const total = pedido.productos.reduce((s, x) => s + x.precio * x.cantidad, 0);
  const descuentoPct = campaign.descuentoVendedora;
  const aPagar = +(total * (1 - descuentoPct / 100)).toFixed(2);

  const cuotaMontos = campaign.porcentajes.map(p => +(aPagar * p / 100).toFixed(2));
  // Adjust rounding drift onto last cuota
  const drift = +(aPagar - cuotaMontos.reduce((a, b) => a + b, 0)).toFixed(2);
  cuotaMontos[cuotaMontos.length - 1] = +(cuotaMontos[cuotaMontos.length - 1] + drift).toFixed(2);

  const cuotas = campaign.cuotas.map((fecha, i) => ({
    fecha, monto: cuotaMontos[i], status: 'pendiente', // pendiente | pagada | vencida
  }));

  const factura = {
    id: `FAC-${campaign.id}-${Date.now().toString().slice(-5)}`,
    vendedoraId,
    campaignId: campaign.id,
    pedidoId: pedido.id,
    total, descuentoPct, aPagar,
    ganancia: +(total - aPagar).toFixed(2),
    cuotas,
    createdAt: new Date().toISOString(),
    retiroCodigo: null,
    retirado: false,
  };
  state.facturas.push(factura);
  saveBilling(state);
  return factura;
}

// ——— Deuda/Saldo helpers ———
function facturaSaldo(factura, pagos) {
  const verificados = pagos
    .filter(p => p.facturaId === factura.id && p.status === 'verificado')
    .reduce((s, p) => s + p.monto, 0);
  return +(factura.aPagar - verificados).toFixed(2);
}

function facturaEstado(factura, pagos) {
  const saldo = facturaSaldo(factura, pagos);
  if (saldo <= 0.01) return factura.retirado ? 'retirado' : 'pagada';
  const verificados = pagos.filter(p => p.facturaId === factura.id && p.status === 'verificado').length;
  const pendientes = pagos.filter(p => p.facturaId === factura.id && p.status === 'pendiente').length;
  const now = new Date();
  const hasOverdue = factura.cuotas.some((c, i) => {
    const cuotaFecha = new Date(c.fecha);
    if (cuotaFecha > now) return false;
    // Sum should cover up to this cuota
    const needed = factura.cuotas.slice(0, i + 1).reduce((s, x) => s + x.monto, 0);
    const paid = pagos
      .filter(p => p.facturaId === factura.id && p.status === 'verificado')
      .reduce((s, p) => s + p.monto, 0);
    return paid < needed - 0.01;
  });
  if (hasOverdue) return 'vencida';
  if (pendientes > 0) return 'pago-pendiente';
  if (verificados > 0) return 'abonada';
  return 'por-pagar';
}

function totalDeuda(facturas, pagos) {
  return facturas
    .filter(f => !f.retirado)
    .reduce((s, f) => s + Math.max(0, facturaSaldo(f, pagos)), 0);
}
function totalDeudaVencida(facturas, pagos) {
  return facturas
    .filter(f => facturaEstado(f, pagos) === 'vencida')
    .reduce((s, f) => s + Math.max(0, facturaSaldo(f, pagos)), 0);
}

// ——— Payment actions ———
function registrarPago({ facturaId, vendedoraId, monto, metodo, banco, referencia, fecha, capturaDataUrl, nota }) {
  const state = loadBilling();
  const pago = {
    id: `PAG-${Date.now()}`,
    facturaId, vendedoraId,
    monto: +parseFloat(monto).toFixed(2),
    metodo, banco, referencia, fecha,
    capturaDataUrl, nota,
    status: 'pendiente', // pendiente | verificado | rechazado
    createdAt: new Date().toISOString(),
  };
  state.pagos.push(pago);
  saveBilling(state);
  return pago;
}

function verificarPago(pagoId, verificadorId) {
  const state = loadBilling();
  const pago = state.pagos.find(p => p.id === pagoId);
  if (!pago) return;
  pago.status = 'verificado';
  pago.verifiedAt = new Date().toISOString();
  pago.verifiedBy = verificadorId;
  // Check if factura fully paid → set cuotas paid + generate retiro code
  const factura = state.facturas.find(f => f.id === pago.facturaId);
  if (factura) {
    const saldo = facturaSaldo(factura, state.pagos);
    if (saldo <= 0.01 && !factura.retiroCodigo) {
      factura.retiroCodigo = `RET-${factura.campaignId}-${String(Math.floor(Math.random() * 9999)).padStart(4, '0')}`;
    }
    // Mark cuotas paid progressively
    const verificado = state.pagos
      .filter(p => p.facturaId === factura.id && p.status === 'verificado')
      .reduce((s, p) => s + p.monto, 0);
    let covered = 0;
    for (const c of factura.cuotas) {
      covered += c.monto;
      c.status = verificado >= covered - 0.01 ? 'pagada' : 'pendiente';
    }
  }
  saveBilling(state);
}

function rechazarPago(pagoId, razon, verificadorId) {
  const state = loadBilling();
  const pago = state.pagos.find(p => p.id === pagoId);
  if (!pago) return;
  pago.status = 'rechazado';
  pago.rejectReason = razon;
  pago.verifiedAt = new Date().toISOString();
  pago.verifiedBy = verificadorId;
  saveBilling(state);
}

// ——— Seed demo data so the app doesn't look empty ———
function seedDemoIfEmpty(vendedoraId) {
  const state = loadBilling();
  if (state.facturas.some(f => f.vendedoraId === vendedoraId)) return;
  const camps = state.campaigns;
  const activeCamp = camps[camps.length - 3]; // one in the past with partial payments
  const nextCamp = camps[camps.length - 2];

  // Factura 1: C06 — paid ~50%
  const f1 = {
    id: `FAC-${activeCamp.id}-SEED1`,
    vendedoraId,
    campaignId: activeCamp.id,
    pedidoId: 'C18-042',
    total: 187.20, descuentoPct: 20, aPagar: 149.76, ganancia: 37.44,
    cuotas: activeCamp.cuotas.map((f, i) => ({
      fecha: f, monto: i === 2 ? 49.42 : 50.17,
      status: i === 0 ? 'pagada' : 'pendiente',
    })),
    createdAt: new Date(2026, 3, 3).toISOString(),
  };
  // Factura 2: C07 — just created, nothing paid
  const f2 = {
    id: `FAC-${nextCamp.id}-SEED2`,
    vendedoraId,
    campaignId: nextCamp.id,
    pedidoId: 'C18-041',
    total: 112.50, descuentoPct: 20, aPagar: 90.00, ganancia: 22.50,
    cuotas: nextCamp.cuotas.map((f, i) => ({
      fecha: f, monto: i === 2 ? 29.70 : 30.15,
      status: 'pendiente',
    })),
    createdAt: new Date(2026, 3, 18).toISOString(),
  };
  state.facturas.push(f1, f2);

  // Seed payments: one verified on f1, one pending on f1
  state.pagos.push({
    id: 'PAG-SEED-1', facturaId: f1.id, vendedoraId,
    monto: 50.17, metodo: 'Pago Móvil', banco: 'Banesco',
    referencia: '002344519', fecha: new Date(2026, 3, 10).toISOString(),
    status: 'verificado', createdAt: new Date(2026, 3, 10, 9, 30).toISOString(),
    verifiedAt: new Date(2026, 3, 10, 14, 0).toISOString(),
  });
  state.pagos.push({
    id: 'PAG-SEED-2', facturaId: f1.id, vendedoraId,
    monto: 50.17, metodo: 'Transferencia', banco: 'Mercantil',
    referencia: '8872341', fecha: new Date(2026, 3, 17).toISOString(),
    status: 'pendiente', createdAt: new Date(2026, 3, 17, 11, 0).toISOString(),
  });
  saveBilling(state);
}

function fmtDate(iso) {
  const d = new Date(iso);
  return d.toLocaleDateString('es', { day: '2-digit', month: 'short' });
}
function fmtMoney(n) {
  return '$' + (+n).toFixed(2);
}

Object.assign(window, {
  loadBilling, saveBilling,
  loadVendedoras, saveVendedoras,
  loadSession, saveSession,
  createFacturaFromPedido,
  facturaSaldo, facturaEstado,
  totalDeuda, totalDeudaVencida,
  registrarPago, verificarPago, rechazarPago,
  seedDemoIfEmpty,
  fmtDate, fmtMoney,
});
