package Admin

import (
	dto "astrology-api/dto_admin"
	"astrology-api/services_admin"
	"astrology-api/utils"

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

// SettingsController backs the finance section of the admin general settings
// screen: the platform commission, the consultation billing rules, and the
// schedule the settlement job runs on.
type SettingsController struct {
	settingsService services_admin.SettingsService
}

func NewSettingsController(
	settingsService services_admin.SettingsService,
) *SettingsController {

	return &SettingsController{
		settingsService: settingsService,
	}
}

// GetGeneralSettings returns the stored values plus the derived cron
// expression, a plain-English description of the schedule and when it next
// fires.
//
// GET /api/admin/settings/general
func (c *SettingsController) GetGeneralSettings(ctx *gin.Context) {

	response, err := c.settingsService.GetGeneralSettings()

	if err != nil {
		utils.InternalServerError(ctx, err)
		return
	}

	utils.Success(ctx, "General settings", response)
}

// UpdateGeneralSettings saves a partial update. Only the fields present in the
// body are written, so the screen can save one field at a time.
//
// The cron expression is derived from the frequency, day and time for WEEKLY
// and MONTHLY — a value sent for those is ignored rather than left to
// disagree with the parts.
//
// PUT /api/admin/settings/general
func (c *SettingsController) UpdateGeneralSettings(ctx *gin.Context) {

	var request dto.UpdateGeneralSettingsRequest

	if err := ctx.ShouldBindJSON(&request); err != nil {
		utils.BadRequest(ctx, err.Error())
		return
	}

	response, err := c.settingsService.UpdateGeneralSettings(request)

	if err != nil {
		utils.BadRequest(ctx, err.Error())
		return
	}

	utils.Updated(ctx, "General settings updated", response)
}

//------------------------------------------------
// Chat
//------------------------------------------------

// GetChatSettings returns the chat screen's configuration, plus whether Agora
// is configured at all.
//
// agora_configured false means every accept will fail at token-minting time,
// so the panel should render it as a red banner rather than a quiet field.
//
// GET /api/admin/settings/chat
func (c *SettingsController) GetChatSettings(ctx *gin.Context) {

	response, err := c.settingsService.GetChatSettings()

	if err != nil {
		utils.InternalServerError(ctx, err)
		return
	}

	utils.Success(ctx, "Chat settings", response)
}

// UpdateChatSettings is a partial update: only the fields present are written.
//
// The Agora credentials are read-only here. They live in the environment
// because the certificate is a signing key, and a settings screen that could
// rotate one of the pair without the other is a guaranteed outage.
//
// PUT /api/admin/settings/chat
func (c *SettingsController) UpdateChatSettings(ctx *gin.Context) {

	var request dto.UpdateChatSettingsRequest

	if err := ctx.ShouldBindJSON(&request); err != nil {
		utils.BadRequest(ctx, err.Error())
		return
	}

	response, err := c.settingsService.UpdateChatSettings(request)

	if err != nil {
		utils.BadRequest(ctx, err.Error())
		return
	}

	utils.Updated(ctx, "Chat settings updated", response)
}
