package adminpush

import (
	"errors"
	"strconv"

	"hfb_sys/backend/internal/middleware"
	"hfb_sys/backend/pkg/response"

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

type Handler struct {
	service *Service
}

func NewHandler(service *Service) *Handler {
	return &Handler{service: service}
}

// ── 渠道 ──

func (h *Handler) ListChannels(c *gin.Context) {
	items, err := h.service.ListChannels(c.Request.Context())
	if err != nil {
		writePushError(c, err)
		return
	}
	response.OK(c, gin.H{"items": items})
}

func (h *Handler) CreateChannel(c *gin.Context) {
	if _, ok := currentAdminID(c); !ok {
		response.Unauthorized(c, "缺少管理员上下文")
		return
	}
	var req CreateChannelRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.BadRequest(c, "名称、类型和配置不能为空")
		return
	}
	item, err := h.service.CreateChannel(c.Request.Context(), req)
	if err != nil {
		writePushError(c, err)
		return
	}
	response.Created(c, item)
}

func (h *Handler) TestChannel(c *gin.Context) {
	if _, ok := currentAdminID(c); !ok {
		response.Unauthorized(c, "缺少管理员上下文")
		return
	}
	id, err := parseID(c)
	if err != nil {
		response.BadRequest(c, "ID 不正确")
		return
	}
	if err := h.service.TestChannel(c.Request.Context(), id); err != nil {
		writePushError(c, err)
		return
	}
	response.OK(c, gin.H{"sent": true})
}

func (h *Handler) UpdateChannel(c *gin.Context) {
	if _, ok := currentAdminID(c); !ok {
		response.Unauthorized(c, "缺少管理员上下文")
		return
	}
	id, err := parseID(c)
	if err != nil {
		response.BadRequest(c, "ID 不正确")
		return
	}
	var req UpdateChannelRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.BadRequest(c, "请求格式不正确")
		return
	}
	item, err := h.service.UpdateChannel(c.Request.Context(), id, req)
	if err != nil {
		writePushError(c, err)
		return
	}
	response.OK(c, item)
}

func (h *Handler) DeleteChannel(c *gin.Context) {
	if _, ok := currentAdminID(c); !ok {
		response.Unauthorized(c, "缺少管理员上下文")
		return
	}
	id, err := parseID(c)
	if err != nil {
		response.BadRequest(c, "ID 不正确")
		return
	}
	if err := h.service.DeleteChannel(c.Request.Context(), id); err != nil {
		writePushError(c, err)
		return
	}
	response.OK(c, gin.H{"deleted": true})
}

// ── 规则 ──

func (h *Handler) ListRules(c *gin.Context) {
	items, err := h.service.ListRules(c.Request.Context())
	if err != nil {
		writePushError(c, err)
		return
	}
	response.OK(c, gin.H{"items": items})
}

func (h *Handler) UpdateRule(c *gin.Context) {
	if _, ok := currentAdminID(c); !ok {
		response.Unauthorized(c, "缺少管理员上下文")
		return
	}
	id, err := parseID(c)
	if err != nil {
		response.BadRequest(c, "ID 不正确")
		return
	}
	var req UpdateRuleRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.BadRequest(c, "请求格式不正确")
		return
	}
	item, err := h.service.UpdateRule(c.Request.Context(), id, req)
	if err != nil {
		writePushError(c, err)
		return
	}
	response.OK(c, item)
}

// ── 辅助 ──

func parseID(c *gin.Context) (uint64, error) {
	return strconv.ParseUint(c.Param("id"), 10, 64)
}

func currentAdminID(c *gin.Context) (uint64, bool) {
	value, ok := c.Get(middleware.ContextAdminID)
	if !ok {
		return 0, false
	}
	adminID, ok := value.(uint64)
	return adminID, ok
}

func writePushError(c *gin.Context, err error) {
	switch {
	case errors.Is(err, ErrDependencyUnavailable):
		response.ServiceUnavailable(c, "数据库未连接")
	case errors.Is(err, ErrChannelNotFound):
		response.NotFound(c, "推送渠道不存在")
	case errors.Is(err, ErrRuleNotFound):
		response.NotFound(c, "推送规则不存在")
	case errors.Is(err, ErrInvalidChannel):
		response.BadRequest(c, "渠道类型或配置不正确")
	default:
		response.InternalServerError(c, "推送服务暂时不可用")
	}
}
