package server

import (
	"fmt"
	"net/http"
	"strconv"
	"time"

	"github.com/a-h/templ"
	"github.com/labstack/echo/v4"
	u "github.com/rjNemo/underscore"

	"github.com/rjNemo/rentease/internal/config"
	"github.com/rjNemo/rentease/internal/constant"
	"github.com/rjNemo/rentease/internal/service/booking"
	"github.com/rjNemo/rentease/internal/view"
)

func handleReportsPage() echo.HandlerFunc {
	return func(c echo.Context) error {
		monthStr := c.QueryParam("month")
		month, err := strconv.Atoi(monthStr)
		if err != nil || month < 1 || month > 12 {
			month = int(time.Now().Month())
		}

		yearStr := c.QueryParam("year")
		_, err = strconv.Atoi(yearStr)
		if err != nil {
			yearStr = time.Now().Format("2006")
		}
		return renderTempl(c, http.StatusOK, view.Reports(constant.Months, month, yearStr))
	}
}

func handleReportCompute(bs *booking.Service, hc *config.Host) echo.HandlerFunc {
	return func(c echo.Context) error {
		period := c.FormValue("period")
		if !u.Contains([]string{"month", "year"}, period) {
			return &echo.HTTPError{
				Code:    http.StatusBadRequest,
				Message: fmt.Sprintf("%q is not a valid period", period),
			}
		}

		monthStr := c.FormValue("month")
		month, err := strconv.Atoi(monthStr)
		if err != nil || month < 1 || month > 12 {
			return &echo.HTTPError{
				Code:    http.StatusBadRequest,
				Message: fmt.Sprintf("%q is not a valid month", month),
			}
		}

		yearStr := c.FormValue("year")
		year, err := strconv.Atoi(yearStr)
		if err != nil {
			return &echo.HTTPError{
				Code:    http.StatusBadRequest,
				Message: fmt.Sprintf("%q is not a valid year", year),
			}
		}

		r := bs.Report(period, month, year)

		reportVm := &view.ReportViewModel{
			Total:        strconv.FormatFloat(r.Total, 'f', 2, 64),
			PlatformFees: strconv.FormatFloat(r.PlatformFees, 'f', 2, 64),
			Fee:          strconv.FormatFloat(r.Fee, 'f', 2, 64),
			Profit:       strconv.FormatFloat(r.Profit, 'f', 2, 64),
			CardTotal:    strconv.FormatFloat(r.CardTotal, 'f', 2, 64),
			BookingFees:  strconv.FormatFloat(r.BookingFees, 'f', 2, 64),
			PdfUrl:       templ.URL(fmt.Sprintf("%s/pdf?period=%s&month=%d&year=%d", constant.RouteReports, period, month, year)),
			Lines: u.Map(r.Lines, func(l *booking.Line) *view.ReportLine {
				return &view.ReportLine{
					Id:           l.InvoiceNumber(hc),
					Url:          templ.SafeURL(fmt.Sprintf("%s/%d", constant.RouteBooking, l.Id)),
					Total:        strconv.FormatFloat(l.Total, 'f', 2, 64),
					CustomerName: l.CustomerName,
					From:         l.From.Format(time.DateOnly),
					To:           l.To.Format(time.DateOnly),
					Platform:     l.Platform,
					PlatformFees: strconv.FormatFloat(l.PlatformFees, 'f', 2, 64),
					Fee:          strconv.FormatFloat(l.Fee(), 'f', 2, 64),
					Profit:       strconv.FormatFloat(l.Profit(), 'f', 2, 64),
				}
			}),
		}

		return renderTempl(c, http.StatusOK, view.ReportSection(reportVm))
	}
}
