package Astrologer

import (
	"astrology-api/helpers"
	services_astrologer "astrology-api/services_astrologer"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
)

///////////////////////////////////////////////////////////
// Settlement Controller
///////////////////////////////////////////////////////////
//
// The astrologer app's settlement screens. Read-only: an earning is released
// by an admin and credited by the settlement job, and only what has reached
// the wallet can be withdrawn.

type SettlementController struct {
	service services_astrologer.WalletService
}

func NewSettlementController(
	service services_astrologer.WalletService,
) *SettlementController {

	return &SettlementController{
		service: service,
	}
}

///////////////////////////////////////////////////////////
// Upcoming
///////////////////////////////////////////////////////////

// GetUpcomingSettlement is the "what am I owed" screen: everything billed to a
// customer that has not been credited yet, split into awaiting review,
// approved, and on hold, with the date the next settlement run is due.
//
// GET /api/astrologer/settlement/upcoming
func (c *SettlementController) GetUpcomingSettlement(ctx *gin.Context) {

	userID := ctx.MustGet("user_id").(uint)

	response, err := c.service.GetUpcomingSettlement(userID)

	if err != nil {

		ctx.JSON(
			http.StatusBadRequest,
			helpers.ErrorResponse(err.Error()),
		)

		return
	}

	ctx.JSON(
		http.StatusOK,
		helpers.SuccessResponse(
			"Upcoming settlement fetched successfully.",
			response,
		),
	)
}

///////////////////////////////////////////////////////////
// History
///////////////////////////////////////////////////////////

// GetSettlementHistory lists the settlement batches credited to this
// astrologer, newest first. page / limit come off the query string.
//
// GET /api/astrologer/settlement/history
func (c *SettlementController) GetSettlementHistory(ctx *gin.Context) {

	userID := ctx.MustGet("user_id").(uint)

	page := 1
	limit := 10

	if value, err := strconv.Atoi(ctx.DefaultQuery("page", "1")); err == nil && value > 0 {
		page = value
	}

	if value, err := strconv.Atoi(ctx.DefaultQuery("limit", "10")); err == nil && value > 0 {
		limit = value
	}

	response, err := c.service.GetSettlementBatches(userID, page, limit)

	if err != nil {

		ctx.JSON(
			http.StatusBadRequest,
			helpers.ErrorResponse(err.Error()),
		)

		return
	}

	ctx.JSON(
		http.StatusOK,
		helpers.SuccessResponse(
			"Settlement history fetched successfully.",
			response,
		),
	)
}

// GetSettlementDetail opens one batch and lists the sessions it closed.
//
// GET /api/astrologer/settlement/history/:id
func (c *SettlementController) GetSettlementDetail(ctx *gin.Context) {

	userID := ctx.MustGet("user_id").(uint)

	id, err := strconv.Atoi(ctx.Param("id"))

	if err != nil || id <= 0 {

		ctx.JSON(
			http.StatusBadRequest,
			helpers.ErrorResponse("Invalid settlement id"),
		)

		return
	}

	response, err := c.service.GetSettlementBatchDetail(userID, uint(id))

	if err != nil {

		ctx.JSON(
			http.StatusBadRequest,
			helpers.ErrorResponse(err.Error()),
		)

		return
	}

	ctx.JSON(
		http.StatusOK,
		helpers.SuccessResponse(
			"Settlement detail fetched successfully.",
			response,
		),
	)
}

///////////////////////////////////////////////////////////
// Consultation earnings
///////////////////////////////////////////////////////////

// GetConsultationEarnings lists every billed session and where its money has
// got to.
//
// This is the screen to open after a consultation. settlement/history answers
// a narrower question than its name suggests — it lists credited BATCHES, and
// a batch only exists once an admin has approved sessions and the settlement
// job has run. Until then it is empty, correctly, and this endpoint is where
// the earnings actually are.
//
// GET /api/astrologer/settlement/consultations?status=&medium=&page=&limit=
func (c *SettlementController) GetConsultationEarnings(ctx *gin.Context) {

	userID := ctx.MustGet("user_id").(uint)

	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
	limit, _ := strconv.Atoi(ctx.DefaultQuery("limit", "20"))

	response, err := c.service.GetConsultationEarnings(
		userID,
		ctx.DefaultQuery("status", "ALL"),
		ctx.DefaultQuery("medium", "ALL"),
		page,
		limit,
	)

	if err != nil {

		ctx.JSON(
			http.StatusBadRequest,
			helpers.ErrorResponse(err.Error()),
		)

		return
	}

	ctx.JSON(
		http.StatusOK,
		helpers.SuccessResponse(
			"Consultation earnings fetched successfully.",
			response,
		),
	)
}
