// services/pdfExportProductService.ts
import { ProductSalesReport } from '@/types/services/analytic'

export class PDFExportSalesProductService {
  /**
   * Export Product Sales Report to PDF
   */
  static async exportProductSalesToPDF(productData: ProductSalesReport, 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.addProductReportContent(pdf, productData)

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

      // Save PDF
      pdf.save(exportFilename)

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

  /**
   * Add product report content to PDF
   */
  private static async addProductReportContent(pdf: any, productData: ProductSalesReport) {
    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, productData, yPos, pageWidth, marginLeft, marginRight)

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

    // Section 2: Product Details
    checkPageBreak(100)
    yPos = this.addProductDetailsSection(pdf, productData, yPos, pageWidth, marginLeft, marginRight, checkPageBreak)
  }

  /**
   * Add report title
   */
  private static addReportTitle(
    pdf: any,
    productData: ProductSalesReport,
    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 Penjualan Produk', pageWidth / 2, yPos, { align: 'center' })
    yPos += 10

    // Period
    pdf.setFontSize(12)
    pdf.setFont('helvetica', 'normal')
    const periodText = `${productData.date_from.split('T')[0]} - ${productData.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
   */
  private static addRingkasanSection(
    pdf: any,
    productData: ProductSalesReport,
    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', marginLeft, yPos)
    yPos += 12

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

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

    const ringkasanItems = [
      { label: 'Total Produk', value: productSummary.totalProducts.toString(), bold: false },
      { label: 'Total Quantity Sold', value: productSummary.totalQuantitySold.toString(), bold: false },
      { label: 'Total Orders', value: productSummary.totalOrders.toString(), bold: false },
      { label: 'Total Revenue', value: this.formatCurrency(productSummary.totalRevenue), bold: true },
      { label: 'Average Revenue per Item', value: this.formatCurrency(productSummary.averageRevenue), bold: false }
    ]

    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 bold 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 Product Details section - SAMA STYLE SEPERTI SALES REPORT
   */
  private static addProductDetailsSection(
    pdf: any,
    productData: ProductSalesReport,
    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('Rincian Produk', 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
    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 =
      productData.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: productData.data?.reduce((sum, item) => sum + (item?.quantity_sold || 0), 0) || 0,
      totalRevenue: productData.data?.reduce((sum, item) => sum + (item?.revenue || 0), 0) || 0,
      totalOrders: productData.data?.reduce((sum, item) => sum + (item?.order_count || 0), 0) || 0
    }

    // Table rows
    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
        pdf.setFillColor(248, 248, 248) // Soft background
        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

        // 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
          pdf.setDrawColor(230, 230, 230)
          pdf.setLineWidth(0.3)
          pdf.line(marginLeft, yPos + 8, marginLeft + tableWidth, yPos + 8)

          yPos += 10
        })

        // Category subtotal
        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
        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
      })

    // Grand total
    if (checkPageBreak(10)) yPos = 20

    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 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}`
  }

  /**
   * Export Product Sales data with custom configuration
   */
  static async exportCustomProductToPDF(
    productData: ProductSalesReport,
    options?: {
      title?: string
      includeSummary?: boolean
      customFilename?: string
      groupByCategory?: boolean
    }
  ) {
    try {
      const jsPDFModule = await import('jspdf')
      const jsPDF = jsPDFModule.default

      const pdf = new jsPDF('p', 'mm', 'a4')

      let yPos = 20
      const pageWidth = pdf.internal.pageSize.getWidth()
      const pageHeight = pdf.internal.pageSize.getHeight()
      const marginLeft = 20
      const marginRight = 20
      const marginBottom = 15

      const checkPageBreak = (neededSpace: number) => {
        if (yPos + neededSpace > pageHeight - marginBottom) {
          pdf.addPage()
          yPos = 20
          return true
        }
        return false
      }

      // Custom title if provided
      if (options?.title) {
        pdf.setFontSize(20)
        pdf.setFont('helvetica', 'bold')
        pdf.setTextColor(0, 0, 0)
        pdf.text(options.title, pageWidth / 2, yPos, { align: 'center' })
        yPos += 15
      } else {
        yPos = this.addReportTitle(pdf, productData, yPos, pageWidth, marginLeft, marginRight)
      }

      // Optional summary section
      if (options?.includeSummary !== false) {
        checkPageBreak(50)
        yPos = this.addRingkasanSection(pdf, productData, yPos, pageWidth, marginLeft, marginRight, checkPageBreak)
      }

      // Product details
      checkPageBreak(100)
      yPos = this.addProductDetailsSection(pdf, productData, yPos, pageWidth, marginLeft, marginRight, checkPageBreak)

      const exportFilename = options?.customFilename || this.generateFilename('Custom_Product_Sales', 'pdf')
      pdf.save(exportFilename)

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