package cprelation

import (
	"errors"
	"fmt"

	"hyapp-admin-server/internal/appctx"
	"hyapp-admin-server/internal/integration/activityclient"
	"hyapp-admin-server/internal/middleware"
	"hyapp-admin-server/internal/modules/shared"
	"hyapp-admin-server/internal/response"

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

type Handler struct {
	service *Service
	audit   shared.OperationLogger
}

func New(userDB DB, audit shared.OperationLogger) *Handler {
	return NewWithActivity(userDB, nil, audit)
}

func NewWithActivity(userDB DB, activity activityclient.Client, audit shared.OperationLogger) *Handler {
	return &Handler{service: NewService(userDB, activity), audit: audit}
}

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

func (h *Handler) ListRelationships(c *gin.Context) {
	items, err := h.service.ListRelationships(c.Request.Context(), appctx.FromContext(c.Request.Context()), cpListOptionsFromContext(c))
	if err != nil {
		if errors.Is(err, ErrInvalidArgument) {
			response.BadRequest(c, err.Error())
			return
		}
		response.ServerError(c, "获取用户关系列表失败")
		return
	}
	response.OK(c, items)
}

func (h *Handler) ListApplications(c *gin.Context) {
	items, err := h.service.ListApplications(c.Request.Context(), appctx.FromContext(c.Request.Context()), cpListOptionsFromContext(c))
	if err != nil {
		if errors.Is(err, ErrInvalidArgument) {
			response.BadRequest(c, err.Error())
			return
		}
		response.ServerError(c, "获取CP申请列表失败")
		return
	}
	response.OK(c, items)
}

func (h *Handler) UpdateConfig(c *gin.Context) {
	var req updateRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.BadRequest(c, "CP配置参数不正确")
		return
	}
	if req.WeeklyRank != nil {
		// CP 周榜已经拆成独立活动入口；旧接口保留兼容字段，但写入必须同时具备周榜活动权限，避免只拿到关系配置权限的后台用户绕过新菜单。
		if !middleware.HasPermission(c, "cp-weekly-rank:update") {
			response.Forbidden(c, "没有操作权限")
			return
		}
		req.WeeklyRank.UpdatedByAdminID = int64(middleware.CurrentUserID(c))
	}
	config, err := h.service.UpdateConfig(c.Request.Context(), appctx.FromContext(c.Request.Context()), req)
	if err != nil {
		if errors.Is(err, ErrInvalidArgument) {
			response.BadRequest(c, err.Error())
			return
		}
		response.ServerError(c, "更新CP配置失败")
		return
	}
	shared.OperationLogWithResourceID(c, h.audit, "update-cp-config", "user_cp_relation_configs", config.AppCode, "success",
		fmt.Sprintf("relations=%d", len(config.Relations)))
	response.OK(c, config)
}

func cpListOptionsFromContext(c *gin.Context) cpListOptions {
	options := shared.ListOptions(c)
	return cpListOptions{
		Page:         options.Page,
		PageSize:     options.PageSize,
		Status:       options.Status,
		RelationType: firstQuery(c, "relation_type", "relationType"),
	}
}

func firstQuery(c *gin.Context, keys ...string) string {
	for _, key := range keys {
		if value := c.Query(key); value != "" {
			return value
		}
	}
	return ""
}
