
import { jsPDF } from 'jspdf';
import autoTable from 'jspdf-autotable';
import { supabase } from '@/integrations/supabase/client';

// Standard Avria-style colors
const COLORS = {
  text: [30, 41, 59],
  secondary: [100, 116, 139],
  border: [226, 232, 240],
  headerBg: [248, 250, 252],
  black: [15, 23, 42]
};

export const groupExpensesByCategory = (expenses) => {
  const grouped = {};
  
  expenses.forEach(expense => {
    const category = expense.category || 'Uncategorized';
    if (!grouped[category]) {
      grouped[category] = [];
    }
    grouped[category].push(expense);
  });

  return Object.entries(grouped).map(([category, items]) => {
    const sortedItems = items.sort((a, b) => new Date(a.date || 0) - new Date(b.date || 0));
    const subtotal = sortedItems.reduce((sum, item) => sum + parseFloat(item.amount || 0), 0);
    return { category, count: items.length, items: sortedItems, subtotal };
  });
};

export const generateQuickbooksStyleInvoicePDF = async ({ client, items, invoiceNumberFormatted, settings, dueDate, invoiceDate, taxAmount = 0 }) => {
  const doc = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' });
  const pageWidth = doc.internal.pageSize.getWidth();
  const pageHeight = doc.internal.pageSize.getHeight();
  const margin = 20;

  console.log('[InvoicePDF] Generating Avria-style PDF for client:', client?.name, 'Invoice:', invoiceNumberFormatted);

  let currentY = margin;

  // Company Details (Left)
  doc.setFontSize(14);
  doc.setTextColor(...COLORS.black);
  doc.setFont('helvetica', 'bold');
  const companyName = settings?.business_name || 'Avria Community Management, LLC';
  doc.text(companyName, margin, currentY + 5);

  doc.setFontSize(9);
  doc.setFont('helvetica', 'normal');
  doc.setTextColor(...COLORS.secondary);
  
  let leftY = currentY + 10;
  if (settings?.address) {
    const addressLines = doc.splitTextToSize(settings.address, 80);
    addressLines.forEach(line => {
      doc.text(line, margin, leftY);
      leftY += 4.5;
    });
  }
  if (settings?.phone) { doc.text(settings.phone, margin, leftY); leftY += 4.5; }
  if (settings?.email) { doc.text(settings.email, margin, leftY); leftY += 4.5; }
  if (settings?.website) { doc.text(settings.website, margin, leftY); leftY += 4.5; }

  // Logo (Right)
  if (settings?.logo_url) {
    try {
      const img = new Image();
      img.src = settings.logo_url;
      img.crossOrigin = "Anonymous"; 
      await new Promise((resolve, reject) => { 
        img.onload = resolve; 
        img.onerror = reject;
      });
      const ratio = img.width / img.height;
      let imgH = 22;
      let imgW = imgH * ratio;
      if (imgW > 65) { imgW = 65; imgH = imgW / ratio; }
      doc.addImage(img, 'PNG', pageWidth - margin - imgW, currentY, imgW, imgH, undefined, 'FAST');
    } catch (e) {
      console.warn('[InvoicePDF] Logo load failed:', e);
    }
  }

  currentY = Math.max(leftY, currentY + 25) + 15;

  // Bill To & Invoice Details
  const startDetailsY = currentY;

  doc.setFontSize(11);
  doc.setFont('helvetica', 'bold');
  doc.setTextColor(...COLORS.black);
  doc.text("Bill to", margin, currentY);
  
  currentY += 6;
  doc.setFontSize(10);
  doc.text(client?.name || 'Client Name', margin, currentY);
  
  currentY += 5;
  doc.setFontSize(9);
  doc.setFont('helvetica', 'normal');
  doc.setTextColor(...COLORS.secondary);
  
  if (client?.mailing_address) {
    const addressLines = doc.splitTextToSize(client.mailing_address, 80);
    addressLines.forEach(line => {
      doc.text(line, margin, currentY);
      currentY += 4.5;
    });
  }
  
  // Invoice Details (Right)
  const detailsBoxWidth = 80;
  const detailsBoxX = pageWidth - margin - detailsBoxWidth;
  let rightY = startDetailsY - 4;

  doc.setFontSize(22);
  doc.setFont('helvetica', 'bold');
  doc.setTextColor(...COLORS.black);
  doc.text("INVOICE", pageWidth - margin, rightY, { align: 'right' });
  
  rightY += 8;

  const drawDetailRow = (label, value, y) => {
    doc.setFontSize(9);
    doc.setFont('helvetica', 'bold');
    doc.setTextColor(...COLORS.black);
    doc.text(label, detailsBoxX, y);
    doc.setFont('helvetica', 'normal');
    doc.setTextColor(...COLORS.secondary);
    doc.text(value, pageWidth - margin, y, { align: 'right' });
  };

  const invDateStr = invoiceDate ? new Date(invoiceDate).toLocaleDateString() : new Date().toLocaleDateString();
  const dueDateStr = dueDate ? new Date(dueDate).toLocaleDateString() : 'Upon Receipt';

  drawDetailRow("Invoice number", invoiceNumberFormatted || '-', rightY); rightY += 6;
  drawDetailRow("Terms", "Due on receipt", rightY); rightY += 6;
  drawDetailRow("Date", invDateStr, rightY); rightY += 6;
  drawDetailRow("Due Date", dueDateStr, rightY); rightY += 6;

  currentY = Math.max(currentY, rightY) + 15;

  // Line Items Table
  const tableBody = [];
  let grandTotal = 0;

  items.forEach((item, index) => {
    const qty = item.quantity ? parseFloat(item.quantity) : 1;
    const amount = parseFloat(item.amount || 0);
    const unitPrice = item.unit_price ? parseFloat(item.unit_price) : (amount / qty);

    tableBody.push([
      (index + 1).toString(),
      new Date(item.date).toLocaleDateString(),
      item.address || '-',
      item.category || 'General',
      item.description || '-',
      qty.toFixed(2).replace(/\.00$/, ''),
      `$${Math.abs(unitPrice).toFixed(2)}`,
      `$${amount.toFixed(2)}`
    ]);
    grandTotal += amount;
  });

  autoTable(doc, {
    startY: currentY,
    head: [['#', 'Date', 'Address', 'Category', 'Description', 'Qty', 'Rate', 'Amount']],
    body: tableBody,
    theme: 'plain',
    headStyles: { fillColor: COLORS.headerBg, textColor: COLORS.black, fontStyle: 'bold', lineWidth: 0.1, lineColor: COLORS.border },
    bodyStyles: { textColor: COLORS.text, lineColor: COLORS.border, lineWidth: { bottom: 0.1 } },
    styles: { fontSize: 8.5, cellPadding: 4, font: 'helvetica' },
    columnStyles: {
      0: { cellWidth: 10 }, 1: { cellWidth: 20 }, 2: { cellWidth: 35 }, 3: { cellWidth: 30 },
      4: { cellWidth: 'auto' }, 5: { cellWidth: 15, halign: 'right' }, 6: { cellWidth: 20, halign: 'right' }, 7: { cellWidth: 22, halign: 'right' }
    }
  });

  currentY = doc.lastAutoTable.finalY + 15;

  if (currentY + 60 > pageHeight - margin) { doc.addPage(); currentY = margin; }

  // Summary
  const beforeSummaryY = currentY;
  const groupedItems = groupExpensesByCategory(items);
  const summaryBody = groupedItems.map(g => [g.category, g.count.toString(), `$${g.subtotal.toFixed(2)}`]);

  doc.setFontSize(10);
  doc.setFont('helvetica', 'bold');
  doc.setTextColor(...COLORS.black);
  doc.text("Charges Breakdown by Category", margin, currentY);
  currentY += 4;

  autoTable(doc, {
    startY: currentY,
    head: [['Category', 'Count', 'Subtotal']],
    body: summaryBody,
    theme: 'plain',
    tableWidth: 100,
    margin: { left: margin },
    headStyles: { fillColor: COLORS.headerBg, textColor: COLORS.black, fontStyle: 'bold', lineWidth: 0.1, lineColor: COLORS.border },
    bodyStyles: { textColor: COLORS.text, lineColor: COLORS.border, lineWidth: { bottom: 0.1 } },
    styles: { fontSize: 8.5, cellPadding: 3, font: 'helvetica' },
    columnStyles: { 0: { cellWidth: 50 }, 1: { cellWidth: 20, halign: 'center' }, 2: { cellWidth: 30, halign: 'right' } }
  });

  // Grand Total (Right)
  const totalY = beforeSummaryY + 12;
  const totalLabelX = pageWidth - margin - 45;
  const totalValueX = pageWidth - margin;

  doc.setFontSize(14);
  doc.setFont('helvetica', 'bold');
  doc.setTextColor(...COLORS.black);
  doc.text("Total:", totalLabelX, totalY, { align: 'right' });
  doc.text(`$${grandTotal.toFixed(2)}`, totalValueX, totalY, { align: 'right' });

  // Footer
  const pageCount = doc.internal.getNumberOfPages();
  for (let i = 1; i <= pageCount; i++) {
    doc.setPage(i);
    doc.setFontSize(8);
    doc.setTextColor(150, 150, 150);
    doc.setFont('helvetica', 'normal');
    doc.text(`Page ${i} of ${pageCount}`, pageWidth / 2, pageHeight - 10, { align: 'center' });
  }

  console.log('[InvoicePDF] PDF generation complete.');
  return doc.output('blob');
};

export const generateInvoicePDF = generateQuickbooksStyleInvoicePDF;

export const getNextInvoiceNumber = async (clientId) => {
  try {
    const { data: existing, error: fetchError } = await supabase
      .from('invoice_number_sequence')
      .select('last_invoice_number')
      .eq('client_id', clientId)
      .maybeSingle();

    if (fetchError && fetchError.code !== 'PGRST116') throw fetchError;

    if (existing) {
      const nextNumber = (existing.last_invoice_number || 0) + 1;
      const { error: updateError } = await supabase
        .from('invoice_number_sequence')
        .update({ last_invoice_number: nextNumber, updated_at: new Date().toISOString() })
        .eq('client_id', clientId);
      if (updateError) throw updateError;
      return nextNumber;
    } else {
      const nextNumber = 1001;
      const { error: insertError } = await supabase
        .from('invoice_number_sequence')
        .insert([{ client_id: clientId, last_invoice_number: nextNumber, updated_at: new Date().toISOString() }]);
      if (insertError) throw insertError;
      return nextNumber;
    }
  } catch (error) {
    console.error('Error getting next invoice number:', error);
    return Math.floor(Date.now() / 1000);
  }
};

export const saveInvoiceRecord = async (clientId, invoiceNumber, type, pdfUrl, amount) => {
  console.log('[Invoice] Saving record to DB for client:', clientId, 'Invoice:', invoiceNumber);
  const { error } = await supabase.from('invoice_tracking').insert([{
    client_id: clientId,
    invoice_number: invoiceNumber,
    invoice_type: type,
    pdf_url: pdfUrl,
    amount: amount,
    status: 'generated',
    generated_date: new Date().toISOString()
  }]);
  if (error) { console.error('[Invoice] Failed to save record:', error); throw error; }
};

export const uploadInvoicePdf = async (blob, fileName) => {
  console.log('[Invoice] Uploading PDF to storage:', fileName);
  const { data, error } = await supabase.storage
    .from('invoices')
    .upload(fileName, blob, { upsert: true });
  
  if (error) { console.error('[Invoice] Storage upload failed:', error); throw error; }
  
  const { data: urlData } = supabase.storage.from('invoices').getPublicUrl(fileName);
  return urlData.publicUrl;
};
