package payroll

import (
	excelread "business-engine/internal/excel_read"
	"business-engine/internal/gencsv"
	"business-engine/internal/genpdf"
	"encoding/json"
	"fmt"
	"log/slog"
	"net/http"
	"slices"
	"time"
)

type EmployeeHandler struct {
	service Service
	logger  *slog.Logger
}

func NewEmployeeHandler(service Service, logger *slog.Logger) *EmployeeHandler {
	return &EmployeeHandler{
		service: service,
		logger:  logger,
	}
}

func (h *EmployeeHandler) ListEmployees(w http.ResponseWriter, r *http.Request) {
	month := time.Date(2025, time.September, 1, 0, 0, 0, 0, time.UTC)
	employees, err := h.service.GenerateMonthlyRun(r.Context(), month)
	if err != nil {
		h.logger.Error("failed to get employees", "error", err)
		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	if err := json.NewEncoder(w).Encode(employees); err != nil {
		h.logger.Error("failed to encode response", "error", err)
		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
	}
}

func (h *EmployeeHandler) RunPayroll(w http.ResponseWriter, r *http.Request) {
	month := time.Date(2025, time.September, 1, 0, 0, 0, 0, time.UTC)
	employeeData := excelread.ReadEmployeeData()

	var payrollStatements []excelread.PayrollStatement
	for _, employeeRow := range employeeData {
		input, err := h.service.FetchPayrollInput(r.Context(), month, employeeRow.Vorname, employeeRow.Nachname)
		if err != nil {
			h.logger.Error("could not fetch payroll input", "error", err)
			// http.Error(w, "Internal Server Error", http.StatusInternalServerError)
		}
		statement := excelread.GeneratePayrollStatement(employeeRow, input)
		payrollStatements = append(payrollStatements, statement)
	}

	slices.SortFunc(payrollStatements, func(a, b excelread.PayrollStatement) int {
		if a.Tourengeld < b.Tourengeld {
			return 1
		}
		if a.Tourengeld > b.Tourengeld {
			return -1
		}
		return 0
	})

	payrollStatements[0].TourengeldBonus = 500
	payrollStatements[1].TourengeldBonus = 400
	payrollStatements[2].TourengeldBonus = 300

	h.logger.Info("generating csv salary statements")
	err := gencsv.GeneratePayrollStatementCSV(payrollStatements)
	if err != nil {
		h.logger.Error("could not generate payroll statement csv", "error", err)
	}
	h.logger.Info("generating pdf salary statements")
	for _, stmt := range payrollStatements {
		err := genpdf.GenerateSalaryStatement(stmt, fmt.Sprintf("%s_%s.pdf", month.Format("2006-01"), fmt.Sprintf("%s %s", stmt.Vorname, stmt.Nachname)), month)
		if err != nil {
			h.logger.Error("could not generate salary statement pdf", "error", err)
		}
	}

	w.Header().Set("Content-Type", "application/json")
	if err := json.NewEncoder(w).Encode(payrollStatements); err != nil {
		h.logger.Error("failed to encode response", "error", err)
		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
	}
}
