import jsPDF from 'jspdf'
import type { RepairTicket, RepairLineItem, RepairNote } from '@/types/repair'

const STATUS_LABELS: Record<string, string> = {
  in_transit: 'In Transit',
  intake: 'Intake',
  diagnosing: 'Diagnosing',
  pending_approval: 'Pending Approval',
  approved: 'Approved',
  in_progress: 'In Progress',
  pending_parts: 'Pending Parts',
  ready: 'Ready for Pickup',
  picked_up: 'Picked Up',
  delivered: 'Delivered',
  cancelled: 'Cancelled',
}

interface GeneratePdfOptions {
  ticket: RepairTicket
  lineItems: RepairLineItem[]
  notes: RepairNote[]
  includeNotes: boolean
  companyName?: string
}

export function generateRepairPdf({ ticket, lineItems, notes, includeNotes, companyName = 'LunarFront' }: GeneratePdfOptions): jsPDF {
  const doc = new jsPDF()
  let y = 20

  // Header
  doc.setFontSize(18)
  doc.setFont('helvetica', 'bold')
  doc.text(companyName, 14, y)
  y += 8
  doc.setFontSize(12)
  doc.setFont('helvetica', 'normal')
  doc.text('Repair Ticket', 14, y)

  // Ticket number and status — right aligned
  doc.setFontSize(14)
  doc.setFont('helvetica', 'bold')
  doc.text(`#${ticket.ticketNumber ?? ''}`, 196, 20, { align: 'right' })
  doc.setFontSize(10)
  doc.setFont('helvetica', 'normal')
  doc.text(STATUS_LABELS[ticket.status] ?? ticket.status, 196, 28, { align: 'right' })
  doc.text(new Date(ticket.intakeDate).toLocaleDateString(), 196, 34, { align: 'right' })

  y += 12

  // Divider
  doc.setDrawColor(200)
  doc.line(14, y, 196, y)
  y += 8

  // Customer info
  doc.setFontSize(10)
  doc.setFont('helvetica', 'bold')
  doc.text('Customer', 14, y)
  doc.text('Item', 110, y)
  y += 5
  doc.setFont('helvetica', 'normal')
  doc.text(ticket.customerName, 14, y)
  doc.text(ticket.itemDescription ?? '-', 110, y)
  y += 5
  if (ticket.customerPhone) { doc.text(ticket.customerPhone, 14, y); y += 5 }
  if (ticket.serialNumber) { doc.text(`S/N: ${ticket.serialNumber}`, 110, y - 5) }
  y += 3

  // Problem description
  doc.setFont('helvetica', 'bold')
  doc.text('Problem Description', 14, y)
  y += 5
  doc.setFont('helvetica', 'normal')
  const problemLines = doc.splitTextToSize(ticket.problemDescription, 180)
  doc.text(problemLines, 14, y)
  y += problemLines.length * 4 + 5

  // Dates
  doc.setFontSize(9)
  const dateInfo = [
    `Intake: ${new Date(ticket.intakeDate).toLocaleDateString()}`,
    ticket.promisedDate ? `Promised: ${new Date(ticket.promisedDate).toLocaleDateString()}` : null,
    ticket.completedDate ? `Completed: ${new Date(ticket.completedDate).toLocaleDateString()}` : null,
  ].filter(Boolean).join('   |   ')
  doc.text(dateInfo, 14, y)
  y += 8

  // Line items table (exclude consumables — internal only)
  const billableItems = lineItems.filter((i) => i.itemType !== 'consumable')
  if (billableItems.length > 0) {
    doc.setDrawColor(200)
    doc.line(14, y, 196, y)
    y += 6

    doc.setFontSize(10)
    doc.setFont('helvetica', 'bold')
    doc.text('Line Items', 14, y)
    y += 6

    // Table header
    doc.setFontSize(8)
    doc.setFillColor(245, 245, 245)
    doc.rect(14, y - 3, 182, 6, 'F')
    doc.text('Type', 16, y)
    doc.text('Description', 40, y)
    doc.text('Qty', 130, y, { align: 'right' })
    doc.text('Unit Price', 155, y, { align: 'right' })
    doc.text('Total', 190, y, { align: 'right' })
    y += 5

    // Table rows
    doc.setFont('helvetica', 'normal')
    for (const item of billableItems) {
      if (y > 270) { doc.addPage(); y = 20 }
      doc.text(item.itemType.replace('_', ' '), 16, y)
      const descLines = doc.splitTextToSize(item.description, 85)
      doc.text(descLines, 40, y)
      doc.text(String(item.qty), 130, y, { align: 'right' })
      doc.text(`$${item.unitPrice}`, 155, y, { align: 'right' })
      doc.text(`$${item.totalPrice}`, 190, y, { align: 'right' })
      y += descLines.length * 4 + 2
    }

    // Total
    y += 2
    doc.setDrawColor(200)
    doc.line(140, y, 196, y)
    y += 5
    doc.setFont('helvetica', 'bold')
    doc.setFontSize(10)
    const total = billableItems.reduce((sum, i) => sum + parseFloat(i.totalPrice), 0)
    doc.text('Total:', 155, y, { align: 'right' })
    doc.text(`$${total.toFixed(2)}`, 190, y, { align: 'right' })
    y += 4

    if (ticket.estimatedCost) {
      doc.setFont('helvetica', 'normal')
      doc.setFontSize(9)
      doc.text(`Estimated: $${ticket.estimatedCost}`, 190, y, { align: 'right' })
      y += 4
    }
    y += 4
  }

  // Customer-visible notes
  if (includeNotes) {
    const customerNotes = notes.filter((n) => n.visibility === 'customer')
    if (customerNotes.length > 0) {
      if (y > 250) { doc.addPage(); y = 20 }
      doc.setDrawColor(200)
      doc.line(14, y, 196, y)
      y += 6
      doc.setFontSize(10)
      doc.setFont('helvetica', 'bold')
      doc.text('Notes', 14, y)
      y += 6

      doc.setFontSize(9)
      doc.setFont('helvetica', 'normal')
      for (const note of customerNotes) {
        if (y > 270) { doc.addPage(); y = 20 }
        doc.setFont('helvetica', 'bold')
        doc.text(`${note.authorName} — ${new Date(note.createdAt).toLocaleDateString()}`, 14, y)
        y += 4
        doc.setFont('helvetica', 'normal')
        const noteLines = doc.splitTextToSize(note.content, 180)
        doc.text(noteLines, 14, y)
        y += noteLines.length * 3.5 + 4
      }
    }
  }

  // Footer
  if (y > 270) { doc.addPage(); y = 20 }
  y = 280
  doc.setFontSize(8)
  doc.setFont('helvetica', 'normal')
  doc.setTextColor(150)
  doc.text(`Generated ${new Date().toLocaleString()} — Ticket #${ticket.ticketNumber}`, 105, y, { align: 'center' })

  return doc
}

export async function generateAndUploadPdf(
  options: GeneratePdfOptions,
  ticketId: string,
  token: string | null,
): Promise<void> {
  const doc = generateRepairPdf(options)
  const filename = `repair-${options.ticket.ticketNumber}-${options.ticket.status}.pdf`

  // Download for user
  doc.save(filename)

  // Also upload to ticket documents
  const blob = doc.output('blob')
  const formData = new FormData()
  formData.append('file', new File([blob], filename, { type: 'application/pdf' }))
  formData.append('entityType', 'repair_ticket')
  formData.append('entityId', ticketId)
  formData.append('category', 'document')

  try {
    await fetch('/v1/files', {
      method: 'POST',
      headers: { Authorization: `Bearer ${token}` },
      body: formData,
    })
  } catch {
    // Download succeeded even if upload fails — non-critical
  }
}
