// Shared lib for RMP accounting — Supabase helpers and types
import { createClient } from '@/lib/supabase/server';

export const RMP_SITES = ['avbeat', 'avbeat', 'backlotbeat', 'broadcastengineering'] as const;
export type RmpSite = typeof RMP_SITES[number];

export const EXPENSE_CATEGORIES = [
  'contract_labor', 'software_subscriptions', 'hosting_infrastructure',
  'travel', 'office_supplies', 'legal_accounting', 'marketing', 'equipment', 'other',
] as const;

export const INVOICE_STATUSES = ['pending', 'paid', 'overdue', 'cancelled'] as const;
export const ORDER_STATUSES = ['active', 'completed', 'cancelled'] as const;
export const FLIGHT_STATUSES = ['scheduled', 'active', 'paused', 'expired', 'cancelled'] as const;

/** Generate next internal order number: RMP-YYYY-NNNN */
export async function generateOrderNumber(): Promise<string> {
  const supabase = await createClient();
  const year = new Date().getFullYear();
  const { count } = await supabase
    .from('rmp_orders')
    .select('*', { count: 'exact', head: true })
    .like('internal_order_number', `RMP-${year}-%`);
  const seq = String((count ?? 0) + 1).padStart(4, '0');
  return `RMP-${year}-${seq}`;
}

/** Generate next invoice number: RMP-YYYY-NNNN */
export async function generateInvoiceNumber(): Promise<string> {
  const supabase = await createClient();
  const year = new Date().getFullYear();
  const { count } = await supabase
    .from('rmp_invoices')
    .select('*', { count: 'exact', head: true })
    .like('invoice_number', `RMP-${year}-%`);
  const seq = String((count ?? 0) + 1).padStart(4, '0');
  return `RMP-${year}-${seq}`;
}

/** Calculate commission for a paid invoice using tiered rates */
export async function calculateCommission(
  staffId: string,
  invoiceId: string,
  saleAmountCents: number,
  year: number
): Promise<{ rate: number; amountCents: number; ytdCents: number } | null> {
  const supabase = await createClient();

  // Get YTD sales before this invoice
  const { data: ytdData } = await supabase
    .from('rmp_commissions')
    .select('sale_amount_cents')
    .eq('staff_id', staffId)
    .eq('year', year);

  const ytdBefore = (ytdData ?? []).reduce((s: number, r: any) => s + (r.sale_amount_cents ?? 0), 0);

  // Get tiers sorted
  const { data: tiers } = await supabase
    .from('rmp_commission_tiers')
    .select('*')
    .eq('staff_id', staffId)
    .eq('effective_year', year)
    .order('tier_order', { ascending: true });

  if (!tiers || tiers.length === 0) return null;

  // Calculate blended commission handling tier crossings
  let remaining = saleAmountCents;
  let ytdRunning = ytdBefore;
  let totalCommission = 0;
  let effectiveRate = 0;

  for (const tier of tiers) {
    if (remaining <= 0) break;
    const threshold = tier.threshold_cents ?? Infinity;
    const tierStart = ytdRunning;
    const tierSpace = threshold - tierStart;

    if (tierSpace <= 0) continue;

    const inThisTier = Math.min(remaining, tierSpace);
    totalCommission += Math.round(inThisTier * tier.rate);
    effectiveRate = tier.rate;
    ytdRunning += inThisTier;
    remaining -= inThisTier;
  }

  // If remaining after all tiers, use last tier rate
  if (remaining > 0 && tiers.length > 0) {
    const lastTier = tiers[tiers.length - 1];
    totalCommission += Math.round(remaining * lastTier.rate);
    effectiveRate = lastTier.rate;
  }

  return {
    rate: effectiveRate,
    amountCents: totalCommission,
    ytdCents: ytdBefore + saleAmountCents,
  };
}

/** Mark invoice as paid and trigger commission calculation */
export async function markInvoicePaid(
  invoiceId: string,
  method: string,
  paidDate: string,
  wireRef?: string,
  stripeId?: string
): Promise<{ ok: boolean; error?: string }> {
  const supabase = await createClient();

  const { data: invoice, error: fetchErr } = await supabase
    .from('rmp_invoices')
    .select('*')
    .eq('id', invoiceId)
    .single();

  if (fetchErr || !invoice) return { ok: false, error: 'Invoice not found' };

  const { error: updateErr } = await supabase
    .from('rmp_invoices')
    .update({
      status: 'paid',
      payment_method: method,
      paid_date: paidDate,
      wire_reference: wireRef ?? null,
      stripe_payment_id: stripeId ?? null,
    })
    .eq('id', invoiceId);

  if (updateErr) return { ok: false, error: updateErr.message };

  // Commission calculation
  if (invoice.is_staff_sale && invoice.staff_id) {
    const year = new Date(paidDate).getFullYear();
    const commission = await calculateCommission(
      invoice.staff_id,
      invoiceId,
      invoice.amount_cents ?? 0,
      year
    );
    if (commission) {
      await supabase.from('rmp_commissions').insert({
        invoice_id: invoiceId,
        staff_id: invoice.staff_id,
        year,
        sale_amount_cents: invoice.amount_cents,
        commission_rate: commission.rate,
        commission_amount_cents: commission.amountCents,
        ytd_sales_at_time_cents: commission.ytdCents,
        paid: false,
      });
    }
  }

  // Log notification
  await supabase.from('rmp_notifications').insert({
    type: 'payment_received',
    message: `Invoice ${invoice.invoice_number} marked paid via ${method}`,
    invoice_id: invoiceId,
  });

  return { ok: true };
}

/** Admin guard for API routes */
export async function requireRmpAdmin(): Promise<{ user: any } | null> {
  const supabase = await createClient();
  const { data: { user } } = await supabase.auth.getUser();
  if (!user) return null;
  const { data: profile } = await supabase
    .from('user_profiles')
    .select('role')
    .eq('id', user.id)
    .single();
  if (!profile || !['administrator', 'admin'].includes(profile.role)) return null;
  return { user };
}

/** AdOps uploader guard */
export async function requireAdopsAccess(): Promise<{ user: any; role: string } | null> {
  const supabase = await createClient();
  const { data: { user } } = await supabase.auth.getUser();
  if (!user) return null;
  const { data: profile } = await supabase
    .from('user_profiles')
    .select('role')
    .eq('id', user.id)
    .single();
  if (!profile || !['administrator', 'admin', 'adops_uploader'].includes(profile.role)) return null;
  return { user, role: profile.role };
}
