import { NextRequest, NextResponse } from 'next/server';
import { createClient } from '@/lib/supabase/server';
import { moonGetContacts, moonGetInvoices } from '@/lib/billing/moonInvoiceClient';
import { logSync, updateBillingSettings } from '@/lib/billing/billingService';
import { createClient as createSupabaseClient } from '@supabase/supabase-js';

const supabase = createSupabaseClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
  { db: { schema: process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || 'bb' } }
);

async function requireAdmin(req: NextRequest) {
  const sb = await createClient();
  const { data: { user } } = await sb.auth.getUser();
  if (!user) return null;
  const { data: profile } = await sb
    .from('user_profiles')
    .select('role')
    .eq('id', user.id)
    .single();
  if (!profile || !['administrator', 'admin'].includes(profile.role)) return null;
  return user;
}

export async function POST(req: NextRequest) {
  const admin = await requireAdmin(req);
  if (!admin) return NextResponse.json({ error: 'Not found' }, { status: 404 });

  const { company } = await req.json().catch(() => ({}));
  const companies: Array<'rmp' | 'jtr'> = company ? [company] : ['rmp', 'jtr'];

  const results: Record<string, any> = {};

  for (const mc of companies) {
    const hasKey = mc === 'rmp'
      ? !!process.env.MOONINVOICE_API_KEY_RMP
      : !!process.env.MOONINVOICE_API_KEY_JTR;

    if (!hasKey) {
      results[mc] = { skipped: true, reason: 'API key not configured' };
      continue;
    }

    const logEntry = await logSync({
      sync_type: `full_sync_${mc}`,
      status: 'running',
      started_at: new Date().toISOString(),
    });

    let recordsSynced = 0;
    const errors: string[] = [];

    try {
      // Sync contacts
      const { data: companyRow } = await supabase
        .from('billing_companies')
        .select('id')
        .eq('llc_entity', mc.toUpperCase())
        .single();

      if (companyRow) {
        let page = 1;
        let hasMore = true;
        while (hasMore) {
          const res = await moonGetContacts(mc, page);
          const contacts = res?.data || res?.contacts || [];
          if (!contacts.length) { hasMore = false; break; }

          for (const c of contacts) {
            await supabase.from('billing_clients').upsert({
              company_id: companyRow.id,
              name: c.name || c.contact_name || '',
              organization: c.organization || c.company || '',
              email: c.email || '',
              phone: c.phone || '',
              mooninvoice_contact_id: String(c.id || c.contact_id || ''),
              updated_at: new Date().toISOString(),
            }, { onConflict: 'mooninvoice_contact_id' });
            recordsSynced++;
          }
          page++;
          if (contacts.length < 50) hasMore = false;
        }

        // Sync invoices
        page = 1;
        hasMore = true;
        while (hasMore) {
          const res = await moonGetInvoices(mc, page);
          const invoices = res?.data || res?.invoices || [];
          if (!invoices.length) { hasMore = false; break; }

          for (const inv of invoices) {
            await supabase.from('billing_invoices').upsert({
              company_id: companyRow.id,
              invoice_number: inv.invoice_number || inv.number || '',
              issue_date: inv.issue_date || inv.date || null,
              due_date: inv.due_date || null,
              status: mapMoonStatus(inv.status),
              total: Number(inv.total || 0),
              amount_paid: Number(inv.amount_paid || 0),
              currency: inv.currency || 'USD',
              mooninvoice_invoice_id: String(inv.id || inv.invoice_id || ''),
              updated_at: new Date().toISOString(),
            }, { onConflict: 'mooninvoice_invoice_id' });
            recordsSynced++;
          }
          page++;
          if (invoices.length < 50) hasMore = false;
        }
      }

      await supabase.from('billing_sync_log').update({
        status: 'completed',
        records_synced: recordsSynced,
        completed_at: new Date().toISOString(),
      }).eq('id', logEntry.id);

      // Update last sync timestamp
      const field = mc === 'rmp' ? 'last_sync_rmp' : 'last_sync_jtr';
      await updateBillingSettings({ [field]: new Date().toISOString() });

      results[mc] = { ok: true, recordsSynced };
    } catch (err: any) {
      errors.push(err.message);
      await supabase.from('billing_sync_log').update({
        status: 'failed',
        errors: { messages: errors },
        completed_at: new Date().toISOString(),
      }).eq('id', logEntry.id);
      results[mc] = { ok: false, error: err.message };
    }
  }

  return NextResponse.json({ results });
}

function mapMoonStatus(status: string): string {
  const map: Record<string, string> = {
    draft: 'draft',
    sent: 'sent',
    viewed: 'viewed',
    paid: 'paid',
    overdue: 'overdue',
    cancelled: 'cancelled',
    canceled: 'cancelled',
  };
  return map[status?.toLowerCase()] || 'draft';
}
