package handlers

import (
	"aggios-app/backend/internal/api/middleware"
	"aggios-app/backend/internal/domain"
	"encoding/csv"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strings"

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

// ExportLeads handles exporting leads in different formats
func (h *CRMHandler) ExportLeads(w http.ResponseWriter, r *http.Request) {
	tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
	if tenantID == "" {
		w.WriteHeader(http.StatusBadRequest)
		json.NewEncoder(w).Encode(map[string]string{"error": "Missing tenant_id"})
		return
	}

	format := r.URL.Query().Get("format")
	if format == "" {
		format = "csv"
	}

	customerID := r.URL.Query().Get("customer_id")
	campaignID := r.URL.Query().Get("campaign_id")

	var leads []domain.CRMLead
	var err error

	if campaignID != "" {
		leads, err = h.repo.GetLeadsByListID(campaignID)
	} else if customerID != "" {
		leads, err = h.repo.GetLeadsByTenant(tenantID)
		// Filter by customer manually
		filtered := []domain.CRMLead{}
		for _, lead := range leads {
			if lead.CustomerID != nil && *lead.CustomerID == customerID {
				filtered = append(filtered, lead)
			}
		}
		leads = filtered
	} else {
		leads, err = h.repo.GetLeadsByTenant(tenantID)
	}

	if err != nil {
		log.Printf("ExportLeads: Error fetching leads: %v", err)
		w.WriteHeader(http.StatusInternalServerError)
		json.NewEncoder(w).Encode(map[string]string{"error": "Failed to fetch leads"})
		return
	}

	switch strings.ToLower(format) {
	case "json":
		exportJSON(w, leads)
	case "xlsx", "excel":
		exportXLSX(w, leads)
	default:
		exportCSV(w, leads)
	}
}

func exportJSON(w http.ResponseWriter, leads []domain.CRMLead) {
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Content-Disposition", "attachment; filename=leads.json")

	json.NewEncoder(w).Encode(map[string]interface{}{
		"leads": leads,
		"count": len(leads),
	})
}

func exportCSV(w http.ResponseWriter, leads []domain.CRMLead) {
	w.Header().Set("Content-Type", "text/csv")
	w.Header().Set("Content-Disposition", "attachment; filename=leads.csv")

	writer := csv.NewWriter(w)
	defer writer.Flush()

	// Header
	header := []string{"ID", "Nome", "Email", "Telefone", "Status", "Origem", "Notas", "Tags", "Criado Em"}
	writer.Write(header)

	// Data
	for _, lead := range leads {
		tags := ""
		if len(lead.Tags) > 0 {
			tags = strings.Join(lead.Tags, ", ")
		}

		phone := ""
		if lead.Phone != "" {
			phone = lead.Phone
		}

		notes := ""
		if lead.Notes != "" {
			notes = lead.Notes
		}

		row := []string{
			lead.ID,
			lead.Name,
			lead.Email,
			phone,
			lead.Status,
			lead.Source,
			notes,
			tags,
			lead.CreatedAt.Format("02/01/2006 15:04"),
		}
		writer.Write(row)
	}
}

func exportXLSX(w http.ResponseWriter, leads []domain.CRMLead) {
	f := excelize.NewFile()
	defer f.Close()

	sheetName := "Leads"
	index, err := f.NewSheet(sheetName)
	if err != nil {
		log.Printf("Error creating sheet: %v", err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	// Set active sheet
	f.SetActiveSheet(index)

	// Header style
	headerStyle, _ := f.NewStyle(&excelize.Style{
		Font: &excelize.Font{
			Bold: true,
			Size: 12,
		},
		Fill: excelize.Fill{
			Type:    "pattern",
			Color:   []string{"#4472C4"},
			Pattern: 1,
		},
		Alignment: &excelize.Alignment{
			Horizontal: "center",
			Vertical:   "center",
		},
	})

	// Headers
	headers := []string{"ID", "Nome", "Email", "Telefone", "Status", "Origem", "Notas", "Tags", "Criado Em"}
	for i, header := range headers {
		cell := fmt.Sprintf("%s1", string(rune('A'+i)))
		f.SetCellValue(sheetName, cell, header)
		f.SetCellStyle(sheetName, cell, cell, headerStyle)
	}

	// Data
	for i, lead := range leads {
		row := i + 2

		tags := ""
		if len(lead.Tags) > 0 {
			tags = strings.Join(lead.Tags, ", ")
		}

		phone := ""
		if lead.Phone != "" {
			phone = lead.Phone
		}

		notes := ""
		if lead.Notes != "" {
			notes = lead.Notes
		}

		f.SetCellValue(sheetName, fmt.Sprintf("A%d", row), lead.ID)
		f.SetCellValue(sheetName, fmt.Sprintf("B%d", row), lead.Name)
		f.SetCellValue(sheetName, fmt.Sprintf("C%d", row), lead.Email)
		f.SetCellValue(sheetName, fmt.Sprintf("D%d", row), phone)
		f.SetCellValue(sheetName, fmt.Sprintf("E%d", row), lead.Status)
		f.SetCellValue(sheetName, fmt.Sprintf("F%d", row), lead.Source)
		f.SetCellValue(sheetName, fmt.Sprintf("G%d", row), notes)
		f.SetCellValue(sheetName, fmt.Sprintf("H%d", row), tags)
		f.SetCellValue(sheetName, fmt.Sprintf("I%d", row), lead.CreatedAt.Format("02/01/2006 15:04"))
	}

	// Auto-adjust column widths
	for i := 0; i < len(headers); i++ {
		col := string(rune('A' + i))
		f.SetColWidth(sheetName, col, col, 15)
	}
	f.SetColWidth(sheetName, "B", "B", 25) // Nome
	f.SetColWidth(sheetName, "C", "C", 30) // Email
	f.SetColWidth(sheetName, "G", "G", 40) // Notas

	// Delete default sheet if exists
	f.DeleteSheet("Sheet1")

	w.Header().Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
	w.Header().Set("Content-Disposition", "attachment; filename=leads.xlsx")

	if err := f.Write(w); err != nil {
		log.Printf("Error writing xlsx: %v", err)
	}
}
