// services/pdfExportCategoryService.ts
import { CategoryReport } from '@/types/services/analytic'

export class PDFExportSalesProductCategoryService {
  /**
   * Export Category Sales Report to PDF
   */
  static async exportCategorySalesToPDF(categoryData: CategoryReport, 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.addCategoryReportContent(pdf, categoryData)

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

      // Save PDF
      pdf.save(exportFilename)

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

  /**
   * Add category report content to PDF
   */
  private static async addCategoryReportContent(pdf: any, categoryData: CategoryReport) {
    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, categoryData, yPos, pageWidth, marginLeft, marginRight)

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

    // Section 2: Category Details
    checkPageBreak(80)
    yPos = this.addCategoryDetailsSection(pdf, categoryData, yPos, pageWidth, marginLeft, marginRight, checkPageBreak)
  }

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

    // Period
    pdf.setFontSize(12)
    pdf.setFont('helvetica', 'normal')
    const periodText = `${categoryData.date_from.split('T')[0]} - ${categoryData.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,
    categoryData: CategoryReport,
    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 categorySummary = {
      totalRevenue: categoryData.data?.reduce((sum, item) => sum + (item?.total_revenue || 0), 0) || 0,
      orderCount: categoryData.data?.reduce((sum, item) => sum + (item?.order_count || 0), 0) || 0,
      productCount: categoryData.data?.reduce((sum, item) => sum + (item?.product_count || 0), 0) || 0,
      totalQuantity: categoryData.data?.reduce((sum, item) => sum + (item?.total_quantity || 0), 0) || 0,
      totalCategories: categoryData.data?.length || 0,
      averageRevenuePerCategory: 0
    }
    categorySummary.averageRevenuePerCategory =
      categorySummary.totalCategories > 0 ? categorySummary.totalRevenue / categorySummary.totalCategories : 0

    const ringkasanItems = [
      { label: 'Total Kategori', value: categorySummary.totalCategories.toString(), bold: false },
      { label: 'Total Produk', value: categorySummary.productCount.toString(), bold: false },
      { label: 'Total Quantity', value: categorySummary.totalQuantity.toString(), bold: false },
      { label: 'Total Orders', value: categorySummary.orderCount.toString(), bold: false },
      { label: 'Total Revenue', value: this.formatCurrency(categorySummary.totalRevenue), bold: true },
      {
        label: 'Rata-rata Revenue per Kategori',
        value: this.formatCurrency(categorySummary.averageRevenuePerCategory),
        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 Category Details section
   */
  private static addCategoryDetailsSection(
    pdf: any,
    categoryData: CategoryReport,
    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 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
    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 summary for footer
    const categorySummary = {
      totalRevenue: categoryData.data?.reduce((sum, item) => sum + (item?.total_revenue || 0), 0) || 0,
      productCount: categoryData.data?.reduce((sum, item) => sum + (item?.product_count || 0), 0) || 0,
      totalQuantity: categoryData.data?.reduce((sum, item) => sum + (item?.total_quantity || 0), 0) || 0
    }

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

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

      yPos += 10
    })

    // Table footer (Total)
    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
  }

  /**
   * 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 Category Sales data with custom configuration
   */
  static async exportCustomCategoryToPDF(
    categoryData: CategoryReport,
    options?: {
      title?: string
      includeSummary?: boolean
      customFilename?: string
      includeOrderCount?: 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, categoryData, yPos, pageWidth, marginLeft, marginRight)
      }

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

      // Category details
      checkPageBreak(80)
      yPos = this.addCategoryDetailsSection(pdf, categoryData, yPos, pageWidth, marginLeft, marginRight, checkPageBreak)

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

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

  /**
   * Export Category Sales with extended table including order count
   */
  static async exportExtendedCategoryToPDF(categoryData: CategoryReport, filename?: string) {
    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
      }

      // Title section
      yPos = this.addReportTitle(pdf, categoryData, yPos, pageWidth, marginLeft, marginRight)

      // Summary section
      checkPageBreak(50)
      yPos = this.addRingkasanSection(pdf, categoryData, yPos, pageWidth, marginLeft, marginRight, checkPageBreak)

      // Extended table with order count
      checkPageBreak(80)
      yPos = this.addExtendedCategoryDetailsSection(
        pdf,
        categoryData,
        yPos,
        pageWidth,
        marginLeft,
        marginRight,
        checkPageBreak
      )

      const exportFilename = filename || this.generateFilename('Laporan_Kategori_Extended', 'pdf')
      pdf.save(exportFilename)

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

  /**
   * Add Extended Category Details section with order count
   */
  private static addExtendedCategoryDetailsSection(
    pdf: any,
    categoryData: CategoryReport,
    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 Kategori (Extended)', marginLeft, yPos)
    yPos += 12

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

    // Table setup - wider for 5 columns
    const tableWidth = pageWidth - marginLeft - marginRight
    const colWidths = [40, 25, 20, 20, 35] // Name, Products, Qty, Orders, Revenue
    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 = ['Nama', 'Total Produk', 'Qty', 'Orders', '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 summary for footer
    const categorySummary = {
      totalRevenue: categoryData.data?.reduce((sum, item) => sum + (item?.total_revenue || 0), 0) || 0,
      productCount: categoryData.data?.reduce((sum, item) => sum + (item?.product_count || 0), 0) || 0,
      totalQuantity: categoryData.data?.reduce((sum, item) => sum + (item?.total_quantity || 0), 0) || 0,
      orderCount: categoryData.data?.reduce((sum, item) => sum + (item?.order_count || 0), 0) || 0
    }

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

    categoryData.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
      const categoryName =
        category.category_name.length > 30 ? category.category_name.substring(0, 27) + '...' : category.category_name
      pdf.text(categoryName, 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]

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

      // Revenue
      pdf.text(this.formatCurrency(category.total_revenue), 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
    })

    // Table footer (Total)
    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(categorySummary.orderCount.toString(), currentX + colWidths[3] / 2, yPos + 6, { align: 'center' })
    currentX += colWidths[3]

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

    return yPos + 20
  }
}
