package dashboard

import (
	"strconv"

	"github.com/gin-gonic/gin"
	"hyapp-admin-server/internal/appctx"
	"hyapp-admin-server/internal/config"
	"hyapp-admin-server/internal/integration/userclient"
	"hyapp-admin-server/internal/middleware"
	"hyapp-admin-server/internal/repository"
	"hyapp-admin-server/internal/response"
)

type Handler struct {
	service *DashboardService
}

func New(store *repository.Store, cfg config.Config, user userclient.Client, options ...Option) *Handler {
	return &Handler{service: NewService(store, cfg, user, options...)}
}

// NewWithService 复用已构建的 DashboardService；社交 BI 模块与大屏共享同一份外部源路由。
func NewWithService(service *DashboardService) *Handler {
	return &Handler{service: service}
}

func (h *Handler) DashboardOverview(c *gin.Context) {
	overview, err := h.service.Overview()
	if err != nil {
		response.ServerError(c, "获取总览失败")
		return
	}
	response.OK(c, overview)
}

func (h *Handler) UserProfileOverview(c *gin.Context) {
	overview, err := h.service.UserProfileOverview(c.Request.Context(), UserProfileOverviewQuery{
		// app_code 显式 query 用于后台页面切换 App；未传时回退鉴权中间件写入的 X-App-Code，
		// 避免页面只切 Header App 后仍静默读取 lalu。
		AppCode: c.DefaultQuery("app_code", appctx.FromContext(c.Request.Context())),
		StatTZ:  c.Query("stat_tz"),
		StartMS: parseInt64(c.Query("start_ms")),
		EndMS:   parseInt64(c.Query("end_ms")),
	})
	if err != nil {
		// 对外继续返回稳定的通用文案，真实依赖/SQL 错误挂到 Gin request errors；access log 才能用
		// request_id 还原失败节点，同时避免把数据库结构或内部地址泄露给后台浏览器。
		_ = c.Error(err)
		response.ServerError(c, "获取用户画像总览失败")
		return
	}
	response.OK(c, overview)
}

func (h *Handler) StatisticsOverview(c *gin.Context) {
	overview, err := h.service.StatisticsOverview(c.Request.Context(), StatisticsQuery{
		AppCode:       c.DefaultQuery("app_code", "lalu"),
		StatTZ:        c.Query("stat_tz"),
		StartMS:       parseInt64(c.Query("start_ms")),
		EndMS:         parseInt64(c.Query("end_ms")),
		SeriesStartMS: parseInt64(c.Query("series_start_ms")),
		SeriesEndMS:   parseInt64(c.Query("series_end_ms")),
		RegionID:      parseInt64(c.Query("region_id")),
		CountryID:     parseInt64(c.Query("country_id")),
	})
	if err != nil {
		response.ServerError(c, "获取统计总览失败")
		return
	}
	response.OK(c, overview)
}

func (h *Handler) SelfGameStatisticsOverview(c *gin.Context) {
	overview, err := h.service.SelfGameStatisticsOverview(c.Request.Context(), SelfGameStatisticsQuery{
		AppCode:   c.DefaultQuery("app_code", "lalu"),
		StatTZ:    c.Query("stat_tz"),
		RequestID: middleware.CurrentRequestID(c),
		StartMS:   parseInt64(c.Query("start_ms")),
		EndMS:     parseInt64(c.Query("end_ms")),
		RegionID:  parseInt64(c.Query("region_id")),
		CountryID: parseInt64(c.Query("country_id")),
		GameID:    c.Query("game_id"),
	})
	if err != nil {
		response.ServerError(c, "获取自研游戏统计失败")
		return
	}
	response.OK(c, overview)
}

func (h *Handler) PlatformGrantUsers(c *gin.Context) {
	page, err := h.service.PlatformGrantUsers(c.Request.Context(), PlatformGrantStatisticsQuery{
		AppCode:   c.DefaultQuery("app_code", "lalu"),
		StatTZ:    c.Query("stat_tz"),
		RequestID: middleware.CurrentRequestID(c),
		StartMS:   parseInt64(c.Query("start_ms")),
		EndMS:     parseInt64(c.Query("end_ms")),
		StatDay:   c.Query("stat_day"),
		RegionID:  parseInt64(c.Query("region_id")),
		CountryID: parseInt64(c.Query("country_id")),
		Source:    firstNonEmpty(c.Query("source"), c.Query("event_type")),
		Page:      parseInt(c.Query("page")),
		PageSize:  parseInt(firstNonEmpty(c.Query("page_size"), c.Query("pageSize"))),
	})
	if err != nil {
		response.ServerError(c, "获取平台发放金币用户明细失败")
		return
	}
	response.OK(c, page)
}

func (h *Handler) PlatformGrantRecords(c *gin.Context) {
	page, err := h.service.PlatformGrantRecords(c.Request.Context(), PlatformGrantStatisticsQuery{
		AppCode:   c.DefaultQuery("app_code", "lalu"),
		StatTZ:    c.Query("stat_tz"),
		StartMS:   parseInt64(c.Query("start_ms")),
		EndMS:     parseInt64(c.Query("end_ms")),
		StatDay:   c.Query("stat_day"),
		RegionID:  parseInt64(c.Query("region_id")),
		CountryID: parseInt64(c.Query("country_id")),
		UserID:    parseInt64(c.Query("user_id")),
		Source:    firstNonEmpty(c.Query("source"), c.Query("event_type")),
		Page:      parseInt(c.Query("page")),
		PageSize:  parseInt(firstNonEmpty(c.Query("page_size"), c.Query("pageSize"))),
	})
	if err != nil {
		response.ServerError(c, "获取平台发放金币来源明细失败")
		return
	}
	response.OK(c, page)
}

func parseInt64(value string) int64 {
	parsed, _ := strconv.ParseInt(value, 10, 64)
	return parsed
}

func parseInt(value string) int {
	parsed, _ := strconv.Atoi(value)
	return parsed
}

func firstNonEmpty(values ...string) string {
	for _, value := range values {
		if value != "" {
			return value
		}
	}
	return ""
}
