package appconfig

import (
	"context"
	"errors"
	"fmt"
	"time"

	"hyapp-admin-server/internal/appctx"
	"hyapp-admin-server/internal/middleware"
	"hyapp-admin-server/internal/modules/shared"
	"hyapp-admin-server/internal/response"
	activityv1 "hyapp.local/api/proto/activity/v1"

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

type floatingScreenConfigRequest struct {
	Enabled         bool  `json:"enabled"`
	GameWinMinCoins int64 `json:"gameWinMinCoins" binding:"required,min=1,max=1000000000000"`
}

type floatingScreenConfigDTO struct {
	AppCode          string `json:"appCode"`
	Enabled          bool   `json:"enabled"`
	GameWinMinCoins  int64  `json:"gameWinMinCoins"`
	UpdatedByAdminID int64  `json:"updatedByAdminId"`
	CreatedAtMS      int64  `json:"createdAtMs"`
	UpdatedAtMS      int64  `json:"updatedAtMs"`
}

func (s *AppConfigService) GetFloatingScreenConfig(ctx context.Context, appCode string) (floatingScreenConfigDTO, error) {
	if s == nil || s.activity == nil {
		return floatingScreenConfigDTO{}, errors.New("activity broadcast config is unavailable")
	}
	appCode = appctx.Normalize(appCode)
	resp, err := s.activity.GetGameWinBroadcastConfig(ctx, &activityv1.GetGameWinBroadcastConfigRequest{
		Meta: &activityv1.RequestMeta{Caller: "admin-server", AppCode: appCode, SentAtMs: time.Now().UTC().UnixMilli()},
	})
	if err != nil {
		return floatingScreenConfigDTO{}, err
	}
	return floatingScreenConfigFromProto(appCode, resp.GetConfig()), nil
}

func (s *AppConfigService) UpdateFloatingScreenConfig(ctx context.Context, appCode string, request floatingScreenConfigRequest, operatorAdminID int64) (floatingScreenConfigDTO, error) {
	if s == nil || s.activity == nil {
		return floatingScreenConfigDTO{}, errors.New("activity broadcast config is unavailable")
	}
	appCode = appctx.Normalize(appCode)
	resp, err := s.activity.UpdateGameWinBroadcastConfig(ctx, &activityv1.UpdateGameWinBroadcastConfigRequest{
		Meta:            &activityv1.RequestMeta{Caller: "admin-server", AppCode: appCode, SentAtMs: time.Now().UTC().UnixMilli()},
		Enabled:         request.Enabled,
		MinWinCoins:     request.GameWinMinCoins,
		OperatorAdminId: operatorAdminID,
	})
	if err != nil {
		return floatingScreenConfigDTO{}, err
	}
	return floatingScreenConfigFromProto(appCode, resp.GetConfig()), nil
}

func floatingScreenConfigFromProto(appCode string, config *activityv1.GameWinBroadcastConfig) floatingScreenConfigDTO {
	if config == nil {
		return floatingScreenConfigDTO{AppCode: appctx.Normalize(appCode)}
	}
	return floatingScreenConfigDTO{
		AppCode:          appctx.Normalize(appCode),
		Enabled:          config.GetEnabled(),
		GameWinMinCoins:  config.GetMinWinCoins(),
		UpdatedByAdminID: config.GetUpdatedByAdminId(),
		CreatedAtMS:      config.GetCreatedAtMs(),
		UpdatedAtMS:      config.GetUpdatedAtMs(),
	}
}

func (h *Handler) GetFloatingScreenConfig(c *gin.Context) {
	item, err := h.service.GetFloatingScreenConfig(c.Request.Context(), appctx.FromContext(c.Request.Context()))
	if err != nil {
		response.ServerError(c, "获取飘屏配置失败")
		return
	}
	response.OK(c, item)
}

func (h *Handler) UpdateFloatingScreenConfig(c *gin.Context) {
	var request floatingScreenConfigRequest
	if err := c.ShouldBindJSON(&request); err != nil {
		response.BadRequest(c, "中奖金币阈值必须在 1 到 1000000000000 之间")
		return
	}
	item, err := h.service.UpdateFloatingScreenConfig(c.Request.Context(), appctx.FromContext(c.Request.Context()), request, int64(middleware.CurrentUserID(c)))
	if err != nil {
		response.BadRequest(c, err.Error())
		return
	}
	// 审计记录明确保留 App、启停和阈值，便于定位一次运营调整为何改变了实时飘屏数量。
	shared.OperationLog(c, h.audit, "update-game-win-floating-screen", "game_win_broadcast_configs", "success", fmt.Sprintf("app_code=%s enabled=%t min_win_coins=%d", item.AppCode, item.Enabled, item.GameWinMinCoins))
	response.OK(c, item)
}
