// services/excelExportSalesService.ts
import type { CategoryReport, PaymentReport, ProductSalesReport, ProfitLossReport } from '@/types/services/analytic'

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

export class ExcelExportSalesService {
  /**
   * Export Sales Report to Excel
   */
  static async exportSalesReportToExcel(salesData: SalesReportData, filename?: string) {
    try {
      // Dynamic import untuk xlsx library
      const XLSX = await import('xlsx')

      // Prepare data untuk Excel
      const worksheetData: any[][] = []

      // Header dengan report info (baris 1-2)
      worksheetData.push(['LAPORAN TRANSAKSI']) // Row 0 - Main title
      worksheetData.push([
        `Periode: ${salesData.profitLoss.date_from.split('T')[0]} - ${salesData.profitLoss.date_to.split('T')[0]}`
      ]) // Row 1 - Period
      worksheetData.push([]) // Empty row

      // Add Summary Section (Ringkasan)
      worksheetData.push(['RINGKASAN PERIODE']) // Section header
      worksheetData.push([]) // Empty row

      const ringkasanData = [
        ['Total Penjualan:', `Rp ${salesData.profitLoss.summary.total_revenue.toLocaleString('id-ID')}`],
        ['Total Diskon:', `Rp ${salesData.profitLoss.summary.total_discount.toLocaleString('id-ID')}`],
        ['Total Pajak:', `Rp ${salesData.profitLoss.summary.total_tax.toLocaleString('id-ID')}`],
        ['Total:', `Rp ${salesData.profitLoss.summary.total_revenue.toLocaleString('id-ID')}`]
      ]

      ringkasanData.forEach(row => {
        worksheetData.push([row[0], row[1]])
      })

      worksheetData.push([]) // Empty row
      worksheetData.push([]) // Empty row

      // Add Invoice Section
      worksheetData.push(['INVOICE']) // Section header
      worksheetData.push([]) // Empty row

      const invoiceData = [
        ['Total Invoice:', salesData.profitLoss.summary.total_orders.toString()],
        ['Rata-rata Tagihan Per Invoice:', `Rp ${salesData.profitLoss.summary.average_profit.toLocaleString('id-ID')}`]
      ]

      invoiceData.forEach(row => {
        worksheetData.push([row[0], row[1]])
      })

      worksheetData.push([]) // Empty row
      worksheetData.push([]) // Empty row

      // Add Payment Methods Section
      worksheetData.push(['RINGKASAN METODE PEMBAYARAN']) // Section header
      worksheetData.push([]) // Empty row

      // Payment methods table header
      const paymentHeaderRow = ['No', 'Metode Pembayaran', 'Tipe', 'Jumlah Order', 'Total Amount', 'Persentase']
      worksheetData.push(paymentHeaderRow)

      // Payment methods data
      salesData.paymentAnalytics.data?.forEach((payment, index) => {
        const rowData = [
          index + 1,
          payment.payment_method_name,
          payment.payment_method_type.toUpperCase(),
          payment.order_count,
          payment.total_amount,
          `${(payment.percentage ?? 0).toFixed(1)}%`
        ]
        worksheetData.push(rowData)
      })

      // Payment methods total row
      const paymentTotalRow = [
        'TOTAL',
        '',
        '',
        salesData.paymentAnalytics.summary?.total_orders ?? 0,
        salesData.paymentAnalytics.summary?.total_amount ?? 0,
        '100.0%'
      ]
      worksheetData.push(paymentTotalRow)

      worksheetData.push([]) // Empty row
      worksheetData.push([]) // Empty row

      // Add Category Section
      worksheetData.push(['RINGKASAN KATEGORI']) // Section header
      worksheetData.push([]) // Empty row

      // Category table header
      const categoryHeaderRow = ['No', 'Nama', 'Total Produk', 'Qty', 'Pendapatan']
      worksheetData.push(categoryHeaderRow)

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

      // Category data
      salesData.categoryAnalytics.data?.forEach((category, index) => {
        const rowData = [
          index + 1,
          category.category_name,
          category.product_count,
          category.total_quantity,
          category.total_revenue
        ]
        worksheetData.push(rowData)
      })

      // Category total row
      const categoryTotalRow = [
        'TOTAL',
        '',
        categorySummary.productCount,
        categorySummary.totalQuantity,
        categorySummary.totalRevenue
      ]
      worksheetData.push(categoryTotalRow)

      worksheetData.push([]) // Empty row
      worksheetData.push([]) // Empty row

      // Add Product Section
      worksheetData.push(['RINGKASAN ITEM']) // Section header
      worksheetData.push([]) // Empty row

      // Group products by category
      const groupedProducts =
        salesData.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:
          salesData.productAnalytics.data?.reduce((sum, item) => sum + (item?.quantity_sold || 0), 0) || 0,
        totalRevenue: salesData.productAnalytics.data?.reduce((sum, item) => sum + (item?.revenue || 0), 0) || 0,
        totalOrders: salesData.productAnalytics.data?.reduce((sum, item) => sum + (item?.order_count || 0), 0) || 0
      }

      // Product table header
      const productHeaderRow = ['Kategori', 'Produk', 'Qty', 'Order', 'Pendapatan', 'Rata Rata']
      worksheetData.push(productHeaderRow)

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

          // Category header row
          worksheetData.push([categoryName.toUpperCase(), '', '', '', '', ''])

          // Category products
          categoryProducts.forEach(item => {
            const rowData = [
              '',
              item.product_name,
              item.quantity_sold,
              item.order_count || 0,
              item.revenue,
              item.average_price
            ]
            worksheetData.push(rowData)
          })

          // Category subtotal
          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)
          const categoryAverage = categoryTotalQty > 0 ? categoryTotalRevenue / categoryTotalQty : 0

          const categorySubtotalRow = [
            `Subtotal ${categoryName}`,
            '',
            categoryTotalQty,
            categoryTotalOrders,
            categoryTotalRevenue,
            categoryAverage
          ]
          worksheetData.push(categorySubtotalRow)
          worksheetData.push([]) // Empty row between categories
        })

      // Grand total
      const grandTotalAverage =
        productSummary.totalQuantitySold > 0 ? productSummary.totalRevenue / productSummary.totalQuantitySold : 0
      const grandTotalRow = [
        'TOTAL KESELURUHAN',
        '',
        productSummary.totalQuantitySold,
        productSummary.totalOrders,
        productSummary.totalRevenue,
        grandTotalAverage
      ]
      worksheetData.push(grandTotalRow)

      // Create workbook dan worksheet
      const workbook = XLSX.utils.book_new()
      const worksheet = XLSX.utils.aoa_to_sheet(worksheetData)

      // Apply basic formatting
      this.applyBasicFormatting(worksheet, worksheetData.length, XLSX)

      // Add worksheet ke workbook
      XLSX.utils.book_append_sheet(workbook, worksheet, 'Laporan Transaksi')

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

      // Download file
      XLSX.writeFile(workbook, exportFilename)

      return { success: true, filename: exportFilename }
    } catch (error) {
      console.error('Error exporting sales report to Excel:', error)
      return { success: false, error: 'Failed to export Excel file' }
    }
  }

  /**
   * Apply basic formatting (SheetJS compatible)
   */
  private static applyBasicFormatting(worksheet: any, totalRows: number, XLSX: any) {
    // Set column widths
    const colWidths = [
      { wch: 25 }, // First column (category/label)
      { wch: 30 }, // Second column (description/name)
      { wch: 15 }, // Third column (numbers)
      { wch: 15 }, // Fourth column (numbers)
      { wch: 20 }, // Fifth column (amounts)
      { wch: 15 } // Sixth column (percentages/averages)
    ]
    worksheet['!cols'] = colWidths

    // Set row heights for better spacing
    worksheet['!rows'] = [
      { hpt: 30 }, // Title row
      { hpt: 25 }, // Period row
      { hpt: 15 }, // Empty row
      { hpt: 25 }, // Section headers
      { hpt: 15 } // Empty row
    ]

    // Merge cells untuk main headers
    const merges = [
      { s: { r: 0, c: 0 }, e: { r: 0, c: 5 } }, // Main title
      { s: { r: 1, c: 0 }, e: { r: 1, c: 5 } } // Period
    ]

    // Find and add merges for section headers
    const sectionHeaders = [
      'RINGKASAN PERIODE',
      'INVOICE',
      'RINGKASAN METODE PEMBAYARAN',
      'RINGKASAN KATEGORI',
      'RINGKASAN ITEM'
    ]

    for (let i = 0; i < totalRows; i++) {
      const cell = worksheet[XLSX.utils.encode_cell({ r: i, c: 0 })]
      if (cell && sectionHeaders.includes(cell.v)) {
        merges.push({ s: { r: i, c: 0 }, e: { r: i, c: 5 } })
      }
    }

    worksheet['!merges'] = merges

    // Apply number formatting untuk currency cells
    this.applyNumberFormatting(worksheet, totalRows, XLSX)
  }

  /**
   * Apply number formatting for currency
   */
  private static applyNumberFormatting(worksheet: any, totalRows: number, XLSX: any) {
    // Apply currency formatting to amount columns
    for (let row = 0; row < totalRows; row++) {
      // Check columns that might contain currency values (columns 1, 4, 5)
      ;[1, 4, 5].forEach(col => {
        const cellAddress = XLSX.utils.encode_cell({ r: row, c: col })
        const cell = worksheet[cellAddress]

        if (cell && typeof cell.v === 'number' && cell.v > 1000) {
          // Apply Indonesian currency format for large numbers
          cell.z = '#,##0'
          cell.t = 'n'
        }
      })
    }

    // Apply formatting to specific sections
    this.applySectionFormatting(worksheet, totalRows, XLSX)
  }

  /**
   * Apply specific formatting to sections
   */
  private static applySectionFormatting(worksheet: any, totalRows: number, XLSX: any) {
    // Find and format table headers and total rows
    const headerKeywords = ['No', 'Metode Pembayaran', 'Nama', 'Kategori', 'Produk']
    const totalKeywords = ['TOTAL', 'Subtotal']

    for (let row = 0; row < totalRows; row++) {
      const cell = worksheet[XLSX.utils.encode_cell({ r: row, c: 0 })]

      if (cell) {
        // Format table headers
        if (headerKeywords.some(keyword => cell.v === keyword)) {
          for (let col = 0; col < 6; col++) {
            const headerCellAddress = XLSX.utils.encode_cell({ r: row, c: col })
            const headerCell = worksheet[headerCellAddress]
            if (headerCell) {
              headerCell.s = {
                font: { bold: true },
                fill: { fgColor: { rgb: 'F3F4F6' } },
                border: {
                  bottom: { style: 'medium', color: { rgb: '000000' } }
                }
              }
            }
          }
        }

        // Format total rows
        if (totalKeywords.some(keyword => cell.v?.toString().startsWith(keyword))) {
          for (let col = 0; col < 6; col++) {
            const totalCellAddress = XLSX.utils.encode_cell({ r: row, c: col })
            const totalCell = worksheet[totalCellAddress]
            if (totalCell) {
              totalCell.s = {
                font: { bold: true },
                border: {
                  top: { style: 'medium', color: { rgb: '000000' } }
                }
              }
            }
          }
        }

        // Format section headers
        const sectionHeaders = [
          'RINGKASAN PERIODE',
          'INVOICE',
          'RINGKASAN METODE PEMBAYARAN',
          'RINGKASAN KATEGORI',
          'RINGKASAN ITEM'
        ]
        if (sectionHeaders.includes(cell.v)) {
          cell.s = {
            font: { bold: true, color: { rgb: '662D91' } },
            fill: { fgColor: { rgb: 'F8F9FA' } }
          }
        }
      }
    }
  }

  /**
   * Generate filename with timestamp
   */
  private static generateFilename(prefix: 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}.xlsx`
  }

  /**
   * Export custom sales data to Excel with configuration
   */
  static async exportCustomSalesData(
    salesData: SalesReportData,
    options?: {
      includeSections?: {
        ringkasan?: boolean
        invoice?: boolean
        paymentMethods?: boolean
        categories?: boolean
        products?: boolean
      }
      customFilename?: string
      sheetName?: string
    }
  ) {
    try {
      const XLSX = await import('xlsx')
      const worksheetData: any[][] = []

      // Always include title and period
      worksheetData.push(['LAPORAN TRANSAKSI'])
      worksheetData.push([
        `Periode: ${salesData.profitLoss.date_from.split('T')[0]} - ${salesData.profitLoss.date_to.split('T')[0]}`
      ])
      worksheetData.push([])

      const sections = options?.includeSections || {
        ringkasan: true,
        invoice: true,
        paymentMethods: true,
        categories: true,
        products: true
      }

      // Conditionally add sections based on options
      if (sections.ringkasan) {
        worksheetData.push(['RINGKASAN PERIODE'])
        worksheetData.push([])
        // Add ringkasan data...
        const ringkasanData = [
          ['Total Penjualan:', `Rp ${salesData.profitLoss.summary.total_revenue.toLocaleString('id-ID')}`],
          ['Total Diskon:', `Rp ${salesData.profitLoss.summary.total_discount.toLocaleString('id-ID')}`],
          ['Total Pajak:', `Rp ${salesData.profitLoss.summary.total_tax.toLocaleString('id-ID')}`],
          ['Total:', `Rp ${salesData.profitLoss.summary.total_revenue.toLocaleString('id-ID')}`]
        ]
        ringkasanData.forEach(row => worksheetData.push([row[0], row[1]]))
        worksheetData.push([])
        worksheetData.push([])
      }

      // Add other sections similarly based on options...

      const workbook = XLSX.utils.book_new()
      const worksheet = XLSX.utils.aoa_to_sheet(worksheetData)

      this.applyBasicFormatting(worksheet, worksheetData.length, XLSX)

      const sheetName = options?.sheetName || 'Laporan Transaksi'
      XLSX.utils.book_append_sheet(workbook, worksheet, sheetName)

      const exportFilename = options?.customFilename || this.generateFilename('Custom_Sales_Report')
      XLSX.writeFile(workbook, exportFilename)

      return { success: true, filename: exportFilename }
    } catch (error) {
      console.error('Error exporting custom sales report to Excel:', error)
      return { success: false, error: 'Failed to export Excel file' }
    }
  }
}
