import { CategoryReport, PaymentReport, ProductSalesReport, ProfitLossReport } from '@/types/services/analytic'

export interface SalesReportData {
  profitLoss: ProfitLossReport
  paymentAnalytics: PaymentReport
  categoryAnalytics: CategoryReport
  productAnalytics: ProductSalesReport
}

export class PDFExportSalesService {
  /**
   * Export Sales Report to PDF
   */
  static async exportSalesReportToPDF(salesData: SalesReportData, filename?: string) {
    try {
      // Dynamic import untuk jsPDF
      const jsPDFModule = await import('jspdf')
      const jsPDF = jsPDFModule.default

      // Create new PDF document - PORTRAIT A4
      const pdf = new jsPDF('p', 'mm', 'a4')

      // Add content
      await this.addSalesReportContent(pdf, salesData)

      // Generate filename
      const exportFilename = filename || this.generateFilename('Laporan_Transaksi', 'pdf')

      // Save PDF
      pdf.save(exportFilename)

      return { success: true, filename: exportFilename }
    } catch (error) {
      console.error('Error exporting sales report to PDF:', error)
      return { success: false, error: `PDF export failed: ${(error as Error).message}` }
    }
  }

  /**
   * Add sales report content to PDF
   */
  private static async addSalesReportContent(pdf: any, salesData: SalesReportData) {
    let yPos = 20
    const pageWidth = pdf.internal.pageSize.getWidth()
    const pageHeight = pdf.internal.pageSize.getHeight()
    const marginLeft = 20
    const marginRight = 20
    const marginBottom = 15

    // Helper function to check page break
    const checkPageBreak = (neededSpace: number) => {
      if (yPos + neededSpace > pageHeight - marginBottom) {
        pdf.addPage()
        yPos = 20
        return true
      }
      return false
    }

    // Title
    yPos = this.addReportTitle(pdf, salesData.profitLoss, yPos, pageWidth, marginLeft, marginRight)

    // Section 1: Ringkasan
    checkPageBreak(50)
    yPos = this.addRingkasanSection(pdf, salesData.profitLoss, yPos, pageWidth, marginLeft, marginRight, checkPageBreak)

    // Section 2: Invoice Summary
    checkPageBreak(40)
    yPos = this.addInvoiceSection(pdf, salesData.profitLoss, yPos, pageWidth, marginLeft, marginRight, checkPageBreak)

    // Section 3: Payment Methods
    checkPageBreak(80)
    yPos = this.addPaymentMethodsSection(
      pdf,
      salesData.paymentAnalytics,
      yPos,
      pageWidth,
      marginLeft,
      marginRight,
      checkPageBreak
    )

    // Section 4: Category Summary
    checkPageBreak(80)
    yPos = this.addCategorySection(
      pdf,
      salesData.categoryAnalytics,
      yPos,
      pageWidth,
      marginLeft,
      marginRight,
      checkPageBreak
    )

    // Section 5: Product Summary
    checkPageBreak(100)
    yPos = this.addProductSection(
      pdf,
      salesData.productAnalytics,
      yPos,
      pageWidth,
      marginLeft,
      marginRight,
      checkPageBreak
    )
  }

  /**
   * Add report title
   */
  private static addReportTitle(
    pdf: any,
    profitLoss: ProfitLossReport,
    startY: number,
    pageWidth: number,
    marginLeft: number,
    marginRight: number
  ): number {
    let yPos = startY

    // Title
    pdf.setFontSize(20)
    pdf.setFont('helvetica', 'bold')
    pdf.setTextColor(0, 0, 0)
    pdf.text('Laporan Transaksi', pageWidth / 2, yPos, { align: 'center' })
    yPos += 10

    // Period
    pdf.setFontSize(12)
    pdf.setFont('helvetica', 'normal')
    const periodText = `${profitLoss.date_from.split('T')[0]} - ${profitLoss.date_to.split('T')[0]}`
    pdf.text(periodText, pageWidth / 2, yPos, { align: 'center' })
    yPos += 10

    // Purple line separator
    pdf.setDrawColor(102, 45, 145)
    pdf.setLineWidth(2)
    pdf.line(marginLeft, yPos, pageWidth - marginRight, yPos)
    yPos += 15

    return yPos
  }

  /**
   * Add Ringkasan section - SAMAKAN DENGAN PAYMENT METHODS STYLE
   */
  private static addRingkasanSection(
    pdf: any,
    profitLoss: ProfitLossReport,
    startY: number,
    pageWidth: number,
    marginLeft: number,
    marginRight: number,
    checkPageBreak: (space: number) => boolean
  ): number {
    let yPos = startY

    // Section title - SAMA SEPERTI PAYMENT METHODS
    pdf.setFontSize(14)
    pdf.setFont('helvetica', 'bold')
    pdf.setTextColor(102, 45, 145)
    pdf.text('Ringkasan', marginLeft, yPos)
    yPos += 12

    // Reset text color
    pdf.setTextColor(0, 0, 0)
    pdf.setFontSize(11)

    const ringkasanItems = [
      { label: 'Total Penjualan', value: this.formatCurrency(profitLoss.summary.total_revenue), bold: false },
      { label: 'Total Diskon', value: this.formatCurrency(profitLoss.summary.total_discount), bold: false },
      { label: 'Total Pajak', value: this.formatCurrency(profitLoss.summary.total_tax), bold: false },
      { label: 'Total', value: this.formatCurrency(profitLoss.summary.total_revenue), bold: true }
    ]

    ringkasanItems.forEach((item, index) => {
      if (checkPageBreak(15)) yPos = 20

      // Set font weight
      pdf.setFont('helvetica', item.bold ? 'bold' : 'normal')

      pdf.text(item.label, marginLeft, yPos)
      pdf.text(item.value, pageWidth - marginRight, yPos, { align: 'right' })

      // Light separator line (except for total row)
      if (!item.bold) {
        pdf.setDrawColor(230, 230, 230)
        pdf.setLineWidth(0.5)
        pdf.line(marginLeft, yPos + 2, pageWidth - marginRight, yPos + 2)
      }

      yPos += 8
    })

    return yPos + 20
  }

  /**
   * Add Invoice section - SAMAKAN DENGAN PAYMENT METHODS STYLE
   */
  private static addInvoiceSection(
    pdf: any,
    profitLoss: ProfitLossReport,
    startY: number,
    pageWidth: number,
    marginLeft: number,
    marginRight: number,
    checkPageBreak: (space: number) => boolean
  ): number {
    let yPos = startY

    // Section title - SAMA SEPERTI PAYMENT METHODS
    pdf.setFontSize(14)
    pdf.setFont('helvetica', 'bold')
    pdf.setTextColor(102, 45, 145)
    pdf.text('Invoice', marginLeft, yPos)
    yPos += 12

    // Reset formatting
    pdf.setTextColor(0, 0, 0)
    pdf.setFontSize(11)

    const invoiceItems = [
      { label: 'Total Invoice', value: profitLoss.summary.total_orders.toString() },
      { label: 'Rata-rata Tagihan Per Invoice', value: this.formatCurrency(profitLoss.summary.average_profit) }
    ]

    invoiceItems.forEach((item, index) => {
      if (checkPageBreak(15)) yPos = 20

      pdf.setFont('helvetica', 'normal')
      pdf.text(item.label, marginLeft, yPos)
      pdf.text(item.value, pageWidth - marginRight, yPos, { align: 'right' })

      // Light separator line
      if (index < invoiceItems.length - 1) {
        pdf.setDrawColor(230, 230, 230)
        pdf.setLineWidth(0.5)
        pdf.line(marginLeft, yPos + 2, pageWidth - marginRight, yPos + 2)
      }

      yPos += 8
    })

    return yPos + 20
  }

  /**
   * Add Payment Methods section - ORIGINAL STYLE (3 jam lu bikin ini!)
   */
  private static addPaymentMethodsSection(
    pdf: any,
    paymentAnalytics: PaymentReport,
    startY: number,
    pageWidth: number,
    marginLeft: number,
    marginRight: number,
    checkPageBreak: (space: number) => boolean
  ): number {
    let yPos = startY

    // Section title
    pdf.setFontSize(14)
    pdf.setFont('helvetica', 'bold')
    pdf.setTextColor(102, 45, 145)
    pdf.text('Ringkasan Metode Pembayaran', marginLeft, yPos)
    yPos += 12

    // Reset formatting
    pdf.setTextColor(0, 0, 0)

    // Table setup
    const tableWidth = pageWidth - marginLeft - marginRight
    const colWidths = [50, 25, 30, 35, 25] // Method, Type, Order, Amount, %
    let currentX = marginLeft

    // Table header
    pdf.setFillColor(240, 240, 240)
    pdf.rect(marginLeft, yPos, tableWidth, 10, 'F')

    pdf.setFont('helvetica', 'bold')
    pdf.setFontSize(9)

    const headers = ['Metode Pembayaran', 'Tipe', 'Jumlah Order', 'Total Amount', 'Persentase']
    currentX = marginLeft

    headers.forEach((header, index) => {
      if (index === 0) {
        pdf.text(header, currentX + 2, yPos + 6)
      } else {
        pdf.text(header, currentX + colWidths[index] / 2, yPos + 6, { align: 'center' })
      }
      currentX += colWidths[index]
    })

    yPos += 12

    // Table rows
    pdf.setFont('helvetica', 'normal')
    pdf.setFontSize(9)

    paymentAnalytics.data?.forEach((payment, index) => {
      if (checkPageBreak(10)) yPos = 20

      currentX = marginLeft
      pdf.setFont('helvetica', 'normal')
      pdf.setFontSize(9)
      pdf.setTextColor(0, 0, 0)

      // Method name
      pdf.text(payment.payment_method_name, currentX + 2, yPos + 5)
      currentX += colWidths[0]

      // Type with simple color coding
      const typeText = payment.payment_method_type.toUpperCase()
      if (payment.payment_method_type === 'cash') {
        pdf.setTextColor(0, 120, 0) // Green
      } else if (payment.payment_method_type === 'card') {
        pdf.setTextColor(0, 80, 200) // Blue
      } else {
        pdf.setTextColor(200, 100, 0) // Orange
      }
      pdf.text(typeText, currentX + colWidths[1] / 2, yPos + 5, { align: 'center' })
      pdf.setTextColor(0, 0, 0) // Reset color
      currentX += colWidths[1]

      // Order count
      pdf.text(payment.order_count.toString(), currentX + colWidths[2] / 2, yPos + 5, { align: 'center' })
      currentX += colWidths[2]

      // Amount
      pdf.text(this.formatCurrency(payment.total_amount), currentX + colWidths[3] - 2, yPos + 5, { align: 'right' })
      currentX += colWidths[3]

      // Percentage
      pdf.text(`${(payment.percentage ?? 0).toFixed(1)}%`, currentX + colWidths[4] / 2, yPos + 5, { align: 'center' })

      // Draw bottom border line
      pdf.setDrawColor(230, 230, 230)
      pdf.setLineWidth(0.3)
      pdf.line(marginLeft, yPos + 8, marginLeft + tableWidth, yPos + 8)

      yPos += 10
    })

    // Table footer (Total) - directly after last row
    pdf.setFillColor(245, 245, 245) // Lighter gray
    pdf.rect(marginLeft, yPos, tableWidth, 10, 'F')

    pdf.setFont('helvetica', 'bold')
    pdf.setFontSize(9)

    currentX = marginLeft
    pdf.text('TOTAL', currentX + 2, yPos + 6)
    currentX += colWidths[0] + colWidths[1]

    pdf.text((paymentAnalytics.summary?.total_orders ?? 0).toString(), currentX + colWidths[2] / 2, yPos + 6, {
      align: 'center'
    })
    currentX += colWidths[2]

    pdf.text(this.formatCurrency(paymentAnalytics.summary?.total_amount ?? 0), currentX + colWidths[3] - 2, yPos + 6, {
      align: 'right'
    })

    return yPos + 20
  }

  /**
   * Add Category section - SAMAKAN DENGAN PAYMENT METHODS STYLE
   */
  private static addCategorySection(
    pdf: any,
    categoryAnalytics: CategoryReport,
    startY: number,
    pageWidth: number,
    marginLeft: number,
    marginRight: number,
    checkPageBreak: (space: number) => boolean
  ): number {
    let yPos = startY

    // Section title - SAMA SEPERTI PAYMENT METHODS
    pdf.setFontSize(14)
    pdf.setFont('helvetica', 'bold')
    pdf.setTextColor(102, 45, 145)
    pdf.text('Ringkasan Kategori', marginLeft, yPos)
    yPos += 12

    // Reset formatting
    pdf.setTextColor(0, 0, 0)

    // Table setup
    const tableWidth = pageWidth - marginLeft - marginRight
    const colWidths = [50, 30, 25, 35] // Name, Products, Qty, Revenue
    let currentX = marginLeft

    // Table header - SAMA SEPERTI PAYMENT METHODS
    pdf.setFillColor(240, 240, 240)
    pdf.rect(marginLeft, yPos, tableWidth, 10, 'F')

    pdf.setFont('helvetica', 'bold')
    pdf.setFontSize(9)

    const headers = ['Nama', 'Total Produk', 'Qty', 'Pendapatan']
    currentX = marginLeft

    headers.forEach((header, index) => {
      if (index === 0) {
        pdf.text(header, currentX + 2, yPos + 6)
      } else {
        pdf.text(header, currentX + colWidths[index] / 2, yPos + 6, { align: 'center' })
      }
      currentX += colWidths[index]
    })

    yPos += 12

    // Calculate summaries
    const categorySummary = {
      totalRevenue: categoryAnalytics.data?.reduce((sum, item) => sum + (item?.total_revenue || 0), 0) || 0,
      productCount: categoryAnalytics.data?.reduce((sum, item) => sum + (item?.product_count || 0), 0) || 0,
      totalQuantity: categoryAnalytics.data?.reduce((sum, item) => sum + (item?.total_quantity || 0), 0) || 0
    }

    // Table rows - SAMA SEPERTI PAYMENT METHODS
    pdf.setFont('helvetica', 'normal')
    pdf.setFontSize(9)

    categoryAnalytics.data?.forEach((category, index) => {
      if (checkPageBreak(10)) yPos = 20

      currentX = marginLeft
      pdf.setFont('helvetica', 'normal')
      pdf.setFontSize(9)
      pdf.setTextColor(0, 0, 0)

      // Category name
      pdf.text(category.category_name, currentX + 2, yPos + 5)
      currentX += colWidths[0]

      // Product count
      pdf.text(category.product_count.toString(), currentX + colWidths[1] / 2, yPos + 5, { align: 'center' })
      currentX += colWidths[1]

      // Quantity
      pdf.text(category.total_quantity.toString(), currentX + colWidths[2] / 2, yPos + 5, { align: 'center' })
      currentX += colWidths[2]

      // Revenue
      pdf.text(this.formatCurrency(category.total_revenue), currentX + colWidths[3] - 2, yPos + 5, { align: 'right' })

      // Draw bottom border line - SAMA SEPERTI PAYMENT METHODS
      pdf.setDrawColor(230, 230, 230)
      pdf.setLineWidth(0.3)
      pdf.line(marginLeft, yPos + 8, marginLeft + tableWidth, yPos + 8)

      yPos += 10
    })

    // Table footer (Total) - SAMA SEPERTI PAYMENT METHODS
    pdf.setFillColor(245, 245, 245) // Lighter gray
    pdf.rect(marginLeft, yPos, tableWidth, 10, 'F')

    pdf.setFont('helvetica', 'bold')
    pdf.setFontSize(9)

    currentX = marginLeft
    pdf.text('TOTAL', currentX + 2, yPos + 6)
    currentX += colWidths[0]

    pdf.text(categorySummary.productCount.toString(), currentX + colWidths[1] / 2, yPos + 6, { align: 'center' })
    currentX += colWidths[1]

    pdf.text(categorySummary.totalQuantity.toString(), currentX + colWidths[2] / 2, yPos + 6, { align: 'center' })
    currentX += colWidths[2]

    pdf.text(this.formatCurrency(categorySummary.totalRevenue), currentX + colWidths[3] - 2, yPos + 6, {
      align: 'right'
    })

    return yPos + 20
  }

  /**
   * Add Product section - SAMAKAN DENGAN PAYMENT METHODS STYLE
   */
  private static addProductSection(
    pdf: any,
    productAnalytics: ProductSalesReport,
    startY: number,
    pageWidth: number,
    marginLeft: number,
    marginRight: number,
    checkPageBreak: (space: number) => boolean
  ): number {
    let yPos = startY // Hapus extra spacing, biar sama dengan section lain

    // Section title - SAMA SEPERTI PAYMENT METHODS
    pdf.setFontSize(14)
    pdf.setFont('helvetica', 'bold')
    pdf.setTextColor(102, 45, 145)
    pdf.text('Ringkasan Item', marginLeft, yPos)
    yPos += 12

    // Reset formatting
    pdf.setTextColor(0, 0, 0)

    // Table setup
    const tableWidth = pageWidth - marginLeft - marginRight
    const colWidths = [60, 20, 20, 30, 30] // Product, Qty, Order, Revenue, Average
    let currentX = marginLeft

    // Table header - SAMA SEPERTI PAYMENT METHODS
    pdf.setFillColor(240, 240, 240)
    pdf.rect(marginLeft, yPos, tableWidth, 10, 'F')

    pdf.setFont('helvetica', 'bold')
    pdf.setFontSize(9)

    const headers = ['Produk', 'Qty', 'Order', 'Pendapatan', 'Rata Rata']
    currentX = marginLeft

    headers.forEach((header, index) => {
      if (index === 0) {
        pdf.text(header, currentX + 2, yPos + 6)
      } else {
        pdf.text(header, currentX + colWidths[index] / 2, yPos + 6, { align: 'center' })
      }
      currentX += colWidths[index]
    })

    yPos += 12

    // Group products by category
    const groupedProducts =
      productAnalytics.data?.reduce(
        (acc, item) => {
          const categoryName = item.category_name || 'Tidak Berkategori'
          if (!acc[categoryName]) {
            acc[categoryName] = []
          }
          acc[categoryName].push(item)
          return acc
        },
        {} as Record<string, any[]>
      ) || {}

    // Calculate product summary
    const productSummary = {
      totalQuantitySold: productAnalytics.data?.reduce((sum, item) => sum + (item?.quantity_sold || 0), 0) || 0,
      totalRevenue: productAnalytics.data?.reduce((sum, item) => sum + (item?.revenue || 0), 0) || 0,
      totalOrders: productAnalytics.data?.reduce((sum, item) => sum + (item?.order_count || 0), 0) || 0
    }

    // Table rows - SAMA SEPERTI PAYMENT METHODS
    pdf.setFont('helvetica', 'normal')
    pdf.setFontSize(9)

    // Render grouped products
    Object.keys(groupedProducts)
      .sort()
      .forEach(categoryName => {
        const categoryProducts = groupedProducts[categoryName]

        // Check page break for category header
        if (checkPageBreak(10)) yPos = 20

        // Category header - SAMA STYLE SEPERTI PAYMENT METHODS TAPI WARNA LEBIH SOFT
        pdf.setFillColor(248, 248, 248) // Warna lebih soft
        pdf.rect(marginLeft, yPos, tableWidth, 10, 'F')
        pdf.setFont('helvetica', 'bold')
        pdf.setFontSize(9)
        pdf.setTextColor(102, 45, 145)
        pdf.text(categoryName.toUpperCase(), marginLeft + 2, yPos + 6)
        pdf.setTextColor(0, 0, 0)
        yPos += 10 // Kurangi jarak, langsung ke 10px seperti row normal

        // Category products
        categoryProducts.forEach((item, index) => {
          if (checkPageBreak(10)) yPos = 20

          currentX = marginLeft
          pdf.setFont('helvetica', 'normal')
          pdf.setFontSize(9)
          pdf.setTextColor(0, 0, 0)

          // Product name (indented and truncated if needed)
          const productName =
            item.product_name.length > 45 ? item.product_name.substring(0, 42) + '...' : item.product_name

          pdf.text(`  ${productName}`, currentX + 2, yPos + 5) // Indented for products
          currentX += colWidths[0]

          // Quantity
          pdf.text(item.quantity_sold.toString(), currentX + colWidths[1] / 2, yPos + 5, { align: 'center' })
          currentX += colWidths[1]

          // Order count
          pdf.text((item.order_count || 0).toString(), currentX + colWidths[2] / 2, yPos + 5, { align: 'center' })
          currentX += colWidths[2]

          // Revenue
          pdf.text(this.formatCurrency(item.revenue), currentX + colWidths[3] - 2, yPos + 5, { align: 'right' })
          currentX += colWidths[3]

          // Average price
          pdf.text(this.formatCurrency(item.average_price), currentX + colWidths[4] - 2, yPos + 5, { align: 'right' })

          // Draw bottom border line - SAMA SEPERTI PAYMENT METHODS
          pdf.setDrawColor(230, 230, 230)
          pdf.setLineWidth(0.3)
          pdf.line(marginLeft, yPos + 8, marginLeft + tableWidth, yPos + 8)

          yPos += 10
        })

        // Category subtotal - WARNA LEBIH SOFT
        if (checkPageBreak(10)) yPos = 20

        const categoryTotalQty = categoryProducts.reduce((sum, item) => sum + (item.quantity_sold || 0), 0)
        const categoryTotalOrders = categoryProducts.reduce((sum, item) => sum + (item.order_count || 0), 0)
        const categoryTotalRevenue = categoryProducts.reduce((sum, item) => sum + (item.revenue || 0), 0)

        pdf.setFillColor(240, 240, 240) // Sama dengan table header, lebih soft
        pdf.rect(marginLeft, yPos, tableWidth, 10, 'F')
        pdf.setFont('helvetica', 'bold')
        pdf.setFontSize(9)

        currentX = marginLeft
        pdf.text(`Subtotal ${categoryName}`, currentX + 2, yPos + 6)
        currentX += colWidths[0]

        pdf.text(categoryTotalQty.toString(), currentX + colWidths[1] / 2, yPos + 6, { align: 'center' })
        currentX += colWidths[1]

        pdf.text(categoryTotalOrders.toString(), currentX + colWidths[2] / 2, yPos + 6, { align: 'center' })
        currentX += colWidths[2]

        pdf.text(this.formatCurrency(categoryTotalRevenue), currentX + colWidths[3] - 2, yPos + 6, { align: 'right' })

        yPos += 10 // Kurangi spacing dari 15 ke 10
      })

    // Grand total - SAMA SEPERTI PAYMENT METHODS FOOTER
    if (checkPageBreak(10)) yPos = 20

    pdf.setFillColor(245, 245, 245) // Lighter gray - SAMA SEPERTI PAYMENT METHODS
    pdf.rect(marginLeft, yPos, tableWidth, 10, 'F')

    pdf.setFont('helvetica', 'bold')
    pdf.setFontSize(9)

    currentX = marginLeft
    pdf.text('TOTAL KESELURUHAN', currentX + 2, yPos + 6)
    currentX += colWidths[0]

    pdf.text(productSummary.totalQuantitySold.toString(), currentX + colWidths[1] / 2, yPos + 6, { align: 'center' })
    currentX += colWidths[1]

    pdf.text(productSummary.totalOrders.toString(), currentX + colWidths[2] / 2, yPos + 6, { align: 'center' })
    currentX += colWidths[2]

    pdf.text(this.formatCurrency(productSummary.totalRevenue), currentX + colWidths[3] - 2, yPos + 6, {
      align: 'right'
    })

    return yPos + 25
  }

  /**
   * Format currency for display
   */
  private static formatCurrency(amount: number): string {
    return `Rp ${amount.toLocaleString('id-ID')}`
  }

  /**
   * Generate filename with timestamp
   */
  private static generateFilename(prefix: string, extension: string): string {
    const now = new Date()
    const year = now.getFullYear()
    const month = (now.getMonth() + 1).toString().padStart(2, '0')
    const day = now.getDate().toString().padStart(2, '0')
    const hour = now.getHours().toString().padStart(2, '0')
    const minute = now.getMinutes().toString().padStart(2, '0')

    return `${prefix}_${year}_${month}_${day}_${hour}${minute}.${extension}`
  }
}
