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

export class ExcelExportSalesProductService {
  /**
   * Export Product Sales Report to Excel
   */
  static async exportProductSalesToExcel(productData: ProductSalesReport, 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 PENJUALAN PRODUK']) // Row 0 - Main title
      worksheetData.push([`Periode: ${productData.date_from.split('T')[0]} - ${productData.date_to.split('T')[0]}`]) // Row 1 - Period
      worksheetData.push([]) // Empty row

      // 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
      }
      productSummary.averageRevenue =
        productSummary.totalQuantitySold > 0 ? productSummary.totalRevenue / productSummary.totalQuantitySold : 0

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

      const summaryData = [
        ['Total Quantity Sold:', productSummary.totalQuantitySold.toString()],
        ['Total Orders:', productSummary.totalOrders.toString()],
        ['Total Revenue:', `Rp ${productSummary.totalRevenue.toLocaleString('id-ID')}`],
        ['Average Revenue per Item:', `Rp ${productSummary.averageRevenue.toLocaleString('id-ID')}`]
      ]

      summaryData.forEach(row => {
        worksheetData.push([row[0], row[1]]) // Only 2 columns needed
      })

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

      // Product Details Section Header
      worksheetData.push(['RINCIAN PRODUK']) // Section header
      worksheetData.push([]) // Empty row

      // 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[]>
        ) || {}

      // Header row untuk tabel product data
      const headerRow = ['Kategori', 'Produk', 'Qty', 'Order', 'Pendapatan', 'Rata Rata']
      worksheetData.push(headerRow)

      // 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 = [
              '', // Empty for category column (indented effect)
              item.product_name,
              item.quantity_sold,
              item.order_count || 0,
              item.revenue, // Store as number for Excel formatting
              item.average_price // Store as number for Excel formatting
            ]
            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 categorySubtotalRow = [
            `Subtotal ${categoryName}`,
            '',
            categoryTotalQty,
            categoryTotalOrders,
            categoryTotalRevenue,
            ''
          ]
          worksheetData.push(categorySubtotalRow)
          worksheetData.push([]) // Empty row between categories
        })

      // Grand total
      const grandTotalRow = [
        'TOTAL KESELURUHAN',
        '',
        productSummary.totalQuantitySold,
        productSummary.totalOrders,
        productSummary.totalRevenue,
        ''
      ]
      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, 'Penjualan Produk')

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

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

      return { success: true, filename: exportFilename }
    } catch (error) {
      console.error('Error exporting 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 }, // Kategori
      { wch: 40 }, // Produk
      { wch: 12 }, // Qty
      { wch: 12 }, // Order
      { wch: 20 }, // Pendapatan
      { wch: 18 } // Rata Rata
    ]
    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 }, // Summary header
      { hpt: 15 } // Empty row
    ]

    // Merge cells untuk headers
    const merges = [
      { s: { r: 0, c: 0 }, e: { r: 0, c: 5 } }, // Title (span across all columns)
      { s: { r: 1, c: 0 }, e: { r: 1, c: 5 } }, // Period (span across all columns)
      { s: { r: 3, c: 0 }, e: { r: 3, c: 5 } } // Summary header (span across all columns)
    ]

    // Find and add merge for product details header
    for (let i = 0; i < totalRows; i++) {
      const cell = worksheet[XLSX.utils.encode_cell({ r: i, c: 0 })]
      if (cell && cell.v === 'RINCIAN PRODUK') {
        merges.push({ s: { r: i, c: 0 }, e: { r: i, c: 5 } }) // Span across all columns
        break
      }
    }

    worksheet['!merges'] = merges

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

  /**
   * Apply number formatting for currency and styling
   */
  private static applyNumberFormatting(worksheet: any, totalRows: number, XLSX: any) {
    // Find table data start (after header row)
    let dataStartRow = -1
    for (let i = 0; i < totalRows; i++) {
      const cell = worksheet[XLSX.utils.encode_cell({ r: i, c: 0 })]
      if (cell && cell.v === 'Kategori') {
        dataStartRow = i + 1
        break
      }
    }

    if (dataStartRow === -1) return

    // Apply currency formatting to Pendapatan and Rata Rata columns (columns 4 and 5)
    for (let row = dataStartRow; row < totalRows; row++) {
      // Pendapatan column (index 4)
      const revenueCell = worksheet[XLSX.utils.encode_cell({ r: row, c: 4 })]
      if (revenueCell && typeof revenueCell.v === 'number') {
        revenueCell.z = '#,##0'
        revenueCell.t = 'n'
      }

      // Rata Rata column (index 5)
      const avgCell = worksheet[XLSX.utils.encode_cell({ r: row, c: 5 })]
      if (avgCell && typeof avgCell.v === 'number') {
        avgCell.z = '#,##0'
        avgCell.t = 'n'
      }
    }

    // Apply styling to header row
    const headerRowIndex = dataStartRow - 1
    for (let col = 0; col < 6; col++) {
      const cellAddress = XLSX.utils.encode_cell({ r: headerRowIndex, c: col })
      const cell = worksheet[cellAddress]

      if (cell) {
        // Apply bold formatting (basic approach for SheetJS)
        cell.s = {
          font: { bold: true },
          fill: { fgColor: { rgb: 'F3F4F6' } }, // Light gray background
          border: {
            bottom: { style: 'medium', color: { rgb: '000000' } }
          }
        }
      }
    }

    // Apply styling to category headers and totals
    for (let row = dataStartRow; row < totalRows; row++) {
      const cell = worksheet[XLSX.utils.encode_cell({ r: row, c: 0 })]

      if (cell && cell.v) {
        const cellValue = cell.v.toString()

        // Style category headers (uppercase text without "Subtotal" or "TOTAL")
        if (
          cellValue === cellValue.toUpperCase() &&
          !cellValue.includes('Subtotal') &&
          !cellValue.includes('TOTAL') &&
          cellValue.length > 0
        ) {
          for (let col = 0; col < 6; col++) {
            const categoryCellAddress = XLSX.utils.encode_cell({ r: row, c: col })
            const categoryCell = worksheet[categoryCellAddress]
            if (categoryCell) {
              categoryCell.s = {
                font: { bold: true, color: { rgb: '36175E' } },
                fill: { fgColor: { rgb: 'F8F8F8' } }
              }
            }
          }
        }

        // Style subtotal and total rows
        if (cellValue.startsWith('Subtotal') || cellValue.startsWith('TOTAL')) {
          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' } }
                }
              }
            }
          }
        }
      }
    }
  }

  /**
   * 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 Product Sales data with custom configuration
   */
  static async exportCustomProductData(
    productData: ProductSalesReport,
    options?: {
      includeSummary?: boolean
      customFilename?: string
      sheetName?: string
      groupByCategory?: boolean
    }
  ) {
    try {
      const XLSX = await import('xlsx')
      const worksheetData: any[][] = []

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

      // Optional summary
      if (options?.includeSummary !== false) {
        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
        }

        worksheetData.push(['RINGKASAN PERIODE'])
        worksheetData.push([])
        const summaryData = [
          ['Total Quantity Sold:', productSummary.totalQuantitySold.toString()],
          ['Total Orders:', productSummary.totalOrders.toString()],
          ['Total Revenue:', `Rp ${productSummary.totalRevenue.toLocaleString('id-ID')}`]
        ]
        summaryData.forEach(row => worksheetData.push([row[0], row[1]]))
        worksheetData.push([])
        worksheetData.push([])
      }

      worksheetData.push(['RINCIAN PRODUK'])
      worksheetData.push([])

      // Header row
      const headerRow =
        options?.groupByCategory !== false
          ? ['Kategori', 'Produk', 'Qty', 'Order', 'Pendapatan', 'Rata Rata']
          : ['Produk', 'Kategori', 'Qty', 'Order', 'Pendapatan', 'Rata Rata']
      worksheetData.push(headerRow)

      // Add product data based on grouping option
      if (options?.groupByCategory !== false) {
        // Group by category (default)
        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[]>
          ) || {}

        Object.keys(groupedProducts)
          .sort()
          .forEach(categoryName => {
            const categoryProducts = groupedProducts[categoryName]
            worksheetData.push([categoryName.toUpperCase(), '', '', '', '', ''])
            categoryProducts.forEach(item => {
              worksheetData.push([
                '',
                item.product_name,
                item.quantity_sold,
                item.order_count || 0,
                item.revenue,
                item.average_price
              ])
            })
          })
      } else {
        // Flat list without grouping
        productData.data?.forEach(item => {
          worksheetData.push([
            item.product_name,
            item.category_name,
            item.quantity_sold,
            item.order_count || 0,
            item.revenue,
            item.average_price
          ])
        })
      }

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

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

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

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

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