// internal/utils/excel_export.go
package utils

import (
	"bytes"
	"fmt"

	"github.com/xuri/excelize/v2"
)

// ExcelExporter handles Excel file generation
type ExcelExporter struct {
	file      *excelize.File
	sheetName string
	rowIndex  int
}

// NewExcelExporter creates a new Excel exporter
func NewExcelExporter() *ExcelExporter {
	f := excelize.NewFile()
	return &ExcelExporter{
		file:      f,
		sheetName: "Sheet1",
		rowIndex:  1,
	}
}

// SetSheetName sets the active sheet name
func (e *ExcelExporter) SetSheetName(name string) {
	e.file.SetSheetName("Sheet1", name)
	e.sheetName = name
}

// AddRow adds a row of data
func (e *ExcelExporter) AddRow(data []string) error {
	for colIndex, value := range data {
		cell := fmt.Sprintf("%s%d", getColumnName(colIndex), e.rowIndex)
		if err := e.file.SetCellValue(e.sheetName, cell, value); err != nil {
			return err
		}
	}
	e.rowIndex++
	return nil
}

// AddHeader adds a header row with bold style
func (e *ExcelExporter) AddHeader(headers []string) error {
	style, err := e.file.NewStyle(&excelize.Style{
		Font: &excelize.Font{
			Bold: true,
		},
		Fill: excelize.Fill{
			Type:    "pattern",
			Color:   []string{"#D3D3D3"},
			Pattern: 1,
		},
	})
	if err != nil {
		return err
	}

	for colIndex, header := range headers {
		cell := fmt.Sprintf("%s%d", getColumnName(colIndex), e.rowIndex)
		if err := e.file.SetCellValue(e.sheetName, cell, header); err != nil {
			return err
		}
		if err := e.file.SetCellStyle(e.sheetName, cell, cell, style); err != nil {
			return err
		}
	}
	e.rowIndex++
	return nil
}

// AutoSizeColumns auto-sizes columns
func (e *ExcelExporter) AutoSizeColumns(columnCount int) {
	for i := 0; i < columnCount; i++ {
		col := getColumnName(i)
		e.file.SetColWidth(e.sheetName, col, col, 15)
	}
}

// Output returns the Excel file as bytes
func (e *ExcelExporter) Output() (*bytes.Buffer, error) {
	buf := new(bytes.Buffer)
	if err := e.file.Write(buf); err != nil {
		return nil, err
	}
	return buf, nil
}

// getColumnName converts column index to Excel column name (A, B, C, ..., AA, AB, ...)
func getColumnName(index int) string {
	name := ""
	for index >= 0 {
		name = string(rune('A'+(index%26))) + name
		index = index/26 - 1
	}
	return name
}