package admin

import (
	"github.com/gofiber/fiber/v2"

	"github.com/break/junhong_cmp_fiber/internal/model"
	"github.com/break/junhong_cmp_fiber/internal/model/dto"
	"github.com/break/junhong_cmp_fiber/internal/service/polling"
	"github.com/break/junhong_cmp_fiber/pkg/constants"
	"github.com/break/junhong_cmp_fiber/pkg/errors"
	"github.com/break/junhong_cmp_fiber/pkg/response"
)

// PollingAlertHandler 轮询告警处理器
type PollingAlertHandler struct {
	service *polling.AlertService
}

// NewPollingAlertHandler 创建轮询告警处理器
func NewPollingAlertHandler(service *polling.AlertService) *PollingAlertHandler {
	return &PollingAlertHandler{service: service}
}

// CreateRule 创建告警规则
// @Summary 创建轮询告警规则
// @Description 创建新的轮询告警规则
// @Tags 轮询管理-告警
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param request body dto.CreatePollingAlertRuleReq true "创建请求"
// @Success 200 {object} response.Response{data=dto.PollingAlertRuleResp}
// @Router /api/admin/polling-alert-rules [post]
func (h *PollingAlertHandler) CreateRule(c *fiber.Ctx) error {
	ctx := c.UserContext()

	var req dto.CreatePollingAlertRuleReq
	if err := c.BodyParser(&req); err != nil {
		return errors.New(errors.CodeInvalidParam)
	}

	rule := &model.PollingAlertRule{
		RuleName:             req.RuleName,
		TaskType:             req.TaskType,
		MetricType:           req.MetricType,
		Operator:             req.Operator,
		Threshold:            req.Threshold,
		AlertLevel:           req.AlertLevel,
		CooldownMinutes:      req.CooldownMinutes,
		NotificationChannels: req.NotifyChannels,
	}

	if err := h.service.CreateRule(ctx, rule); err != nil {
		return err
	}

	return response.Success(c, h.toRuleResp(rule))
}

// ListRules 获取告警规则列表
// @Summary 获取轮询告警规则列表
// @Description 获取所有轮询告警规则
// @Tags 轮询管理-告警
// @Accept json
// @Produce json
// @Security BearerAuth
// @Success 200 {object} response.Response{data=dto.PollingAlertRuleListResp}
// @Router /api/admin/polling-alert-rules [get]
func (h *PollingAlertHandler) ListRules(c *fiber.Ctx) error {
	ctx := c.UserContext()

	rules, err := h.service.ListRules(ctx)
	if err != nil {
		return err
	}

	items := make([]*dto.PollingAlertRuleResp, 0, len(rules))
	for _, rule := range rules {
		items = append(items, h.toRuleResp(rule))
	}

	return response.Success(c, &dto.PollingAlertRuleListResp{Items: items})
}

// GetRule 获取告警规则详情
// @Summary 获取轮询告警规则详情
// @Description 获取指定轮询告警规则的详细信息
// @Tags 轮询管理-告警
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path int true "规则ID"
// @Success 200 {object} response.Response{data=dto.PollingAlertRuleResp}
// @Router /api/admin/polling-alert-rules/{id} [get]
func (h *PollingAlertHandler) GetRule(c *fiber.Ctx) error {
	ctx := c.UserContext()
	id, err := c.ParamsInt("id")
	if err != nil || id <= 0 {
		return errors.New(errors.CodeInvalidParam, "无效的规则ID")
	}

	rule, err := h.service.GetRule(ctx, uint(id))
	if err != nil {
		return err
	}

	return response.Success(c, h.toRuleResp(rule))
}

// UpdateRule 更新告警规则
// @Summary 更新轮询告警规则
// @Description 更新指定轮询告警规则
// @Tags 轮询管理-告警
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path int true "规则ID"
// @Param request body dto.UpdatePollingAlertRuleReq true "更新请求"
// @Success 200 {object} response.Response
// @Router /api/admin/polling-alert-rules/{id} [put]
func (h *PollingAlertHandler) UpdateRule(c *fiber.Ctx) error {
	ctx := c.UserContext()
	id, err := c.ParamsInt("id")
	if err != nil || id <= 0 {
		return errors.New(errors.CodeInvalidParam, "无效的规则ID")
	}

	var req dto.UpdatePollingAlertRuleReq
	if err := c.BodyParser(&req); err != nil {
		return errors.New(errors.CodeInvalidParam)
	}

	updates := make(map[string]interface{})
	if req.RuleName != nil {
		updates["rule_name"] = *req.RuleName
	}
	if req.Threshold != nil {
		updates["threshold"] = *req.Threshold
	}
	if req.AlertLevel != nil {
		updates["alert_level"] = *req.AlertLevel
	}
	if req.Status != nil {
		updates["status"] = *req.Status
	}
	if req.CooldownMinutes != nil {
		updates["cooldown_minutes"] = *req.CooldownMinutes
	}
	if req.NotifyChannels != nil {
		updates["notification_channels"] = *req.NotifyChannels
	}

	if err := h.service.UpdateRule(ctx, uint(id), updates); err != nil {
		return err
	}

	return response.Success(c, nil)
}

// DeleteRule 删除告警规则
// @Summary 删除轮询告警规则
// @Description 删除指定轮询告警规则
// @Tags 轮询管理-告警
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path int true "规则ID"
// @Success 200 {object} response.Response
// @Router /api/admin/polling-alert-rules/{id} [delete]
func (h *PollingAlertHandler) DeleteRule(c *fiber.Ctx) error {
	ctx := c.UserContext()
	id, err := c.ParamsInt("id")
	if err != nil || id <= 0 {
		return errors.New(errors.CodeInvalidParam, "无效的规则ID")
	}

	if err := h.service.DeleteRule(ctx, uint(id)); err != nil {
		return err
	}

	return response.Success(c, nil)
}

// ListHistory 获取告警历史
// @Summary 获取轮询告警历史
// @Description 获取轮询告警历史记录
// @Tags 轮询管理-告警
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param rule_id query int false "规则ID"
// @Param page query int false "页码"
// @Param page_size query int false "每页数量"
// @Success 200 {object} response.Response{data=dto.PollingAlertHistoryListResp}
// @Router /api/admin/polling-alert-history [get]
func (h *PollingAlertHandler) ListHistory(c *fiber.Ctx) error {
	ctx := c.UserContext()

	var req dto.ListPollingAlertHistoryReq
	if err := c.QueryParser(&req); err != nil {
		return errors.New(errors.CodeInvalidParam)
	}

	if req.Page < 1 {
		req.Page = 1
	}
	if req.PageSize < 1 || req.PageSize > 100 {
		req.PageSize = 20
	}

	histories, total, err := h.service.ListHistory(ctx, req.Page, req.PageSize, req.RuleID)
	if err != nil {
		return err
	}

	items := make([]*dto.PollingAlertHistoryResp, 0, len(histories))
	for _, h := range histories {
		items = append(items, &dto.PollingAlertHistoryResp{
			ID:           h.ID,
			RuleID:       h.RuleID,
			RuleName:     "", // 历史记录中没有规则名称，需要单独查询
			TaskType:     h.TaskType,
			MetricType:   h.MetricType,
			AlertLevel:   h.AlertLevel,
			Threshold:    h.Threshold,
			CurrentValue: h.CurrentValue,
			Message:      h.AlertMessage,
			CreatedAt:    h.CreatedAt,
		})
	}

	return response.Success(c, &dto.PollingAlertHistoryListResp{
		Items:    items,
		Total:    total,
		Page:     req.Page,
		PageSize: req.PageSize,
	})
}

func (h *PollingAlertHandler) toRuleResp(rule *model.PollingAlertRule) *dto.PollingAlertRuleResp {
	return &dto.PollingAlertRuleResp{
		ID:              rule.ID,
		RuleName:        rule.RuleName,
		TaskType:        rule.TaskType,
		TaskTypeName:    h.getTaskTypeName(rule.TaskType),
		MetricType:      rule.MetricType,
		MetricTypeName:  h.getMetricTypeName(rule.MetricType),
		Operator:        rule.Operator,
		Threshold:       rule.Threshold,
		AlertLevel:      rule.AlertLevel,
		Status:          int(rule.Status),
		CooldownMinutes: rule.CooldownMinutes,
		NotifyChannels:  rule.NotificationChannels,
		CreatedAt:       rule.CreatedAt,
		UpdatedAt:       rule.UpdatedAt,
	}
}

func (h *PollingAlertHandler) getTaskTypeName(taskType string) string {
	switch taskType {
	case constants.TaskTypePollingRealname:
		return "实名检查"
	case constants.TaskTypePollingCarddata:
		return "流量检查"
	case constants.TaskTypePollingPackage:
		return "套餐检查"
	default:
		return taskType
	}
}

func (h *PollingAlertHandler) getMetricTypeName(metricType string) string {
	switch metricType {
	case "queue_size":
		return "队列积压"
	case "success_rate":
		return "成功率"
	case "avg_duration":
		return "平均耗时"
	case "concurrency":
		return "并发数"
	default:
		return metricType
	}
}
