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/middleware"
	"github.com/break/junhong_cmp_fiber/pkg/response"
)

// PollingManualTriggerHandler 轮询手动触发处理器
type PollingManualTriggerHandler struct {
	service *polling.ManualTriggerService
}

// NewPollingManualTriggerHandler 创建轮询手动触发处理器
func NewPollingManualTriggerHandler(service *polling.ManualTriggerService) *PollingManualTriggerHandler {
	return &PollingManualTriggerHandler{service: service}
}

// TriggerSingle 单卡手动触发
// @Summary 单卡手动触发
// @Description 触发单张卡的轮询任务
// @Tags 轮询管理-手动触发
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param request body dto.TriggerSingleReq true "触发请求"
// @Success 200 {object} response.Response
// @Router /api/admin/polling-manual-trigger/single [post]
func (h *PollingManualTriggerHandler) TriggerSingle(c *fiber.Ctx) error {
	ctx := c.UserContext()

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

	userID := middleware.GetUserIDFromContext(ctx)
	if userID == 0 {
		return errors.New(errors.CodeUnauthorized)
	}

	if err := h.service.TriggerSingle(ctx, req.CardID, req.TaskType, userID); err != nil {
		return err
	}

	return response.Success(c, nil)
}

// TriggerBatch 批量手动触发
// @Summary 批量手动触发
// @Description 批量触发多张卡的轮询任务
// @Tags 轮询管理-手动触发
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param request body dto.TriggerBatchReq true "触发请求"
// @Success 200 {object} response.Response{data=dto.ManualTriggerLogResp}
// @Router /api/admin/polling-manual-trigger/batch [post]
func (h *PollingManualTriggerHandler) TriggerBatch(c *fiber.Ctx) error {
	ctx := c.UserContext()

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

	userID := middleware.GetUserIDFromContext(ctx)
	if userID == 0 {
		return errors.New(errors.CodeUnauthorized)
	}

	log, err := h.service.TriggerBatch(ctx, req.CardIDs, req.TaskType, userID)
	if err != nil {
		return err
	}

	return response.Success(c, h.toLogResp(log))
}

// TriggerByCondition 条件筛选触发
// @Summary 条件筛选触发
// @Description 根据条件筛选卡并触发轮询任务
// @Tags 轮询管理-手动触发
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param request body dto.TriggerByConditionReq true "触发请求"
// @Success 200 {object} response.Response{data=dto.ManualTriggerLogResp}
// @Router /api/admin/polling-manual-trigger/by-condition [post]
func (h *PollingManualTriggerHandler) TriggerByCondition(c *fiber.Ctx) error {
	ctx := c.UserContext()

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

	userID := middleware.GetUserIDFromContext(ctx)
	if userID == 0 {
		return errors.New(errors.CodeUnauthorized)
	}

	filter := &polling.ConditionFilter{
		CardStatus:    req.CardStatus,
		CarrierCode:   req.CarrierCode,
		CardType:      req.CardType,
		ShopID:        req.ShopID,
		PackageIDs:    req.PackageIDs,
		EnablePolling: req.EnablePolling,
		Limit:         req.Limit,
	}

	log, err := h.service.TriggerByCondition(ctx, filter, req.TaskType, userID)
	if err != nil {
		return err
	}

	return response.Success(c, h.toLogResp(log))
}

// GetStatus 获取触发状态
// @Summary 获取手动触发状态
// @Description 获取当前用户的手动触发状态
// @Tags 轮询管理-手动触发
// @Accept json
// @Produce json
// @Security BearerAuth
// @Success 200 {object} response.Response{data=dto.ManualTriggerStatusResp}
// @Router /api/admin/polling-manual-trigger/status [get]
func (h *PollingManualTriggerHandler) GetStatus(c *fiber.Ctx) error {
	ctx := c.UserContext()

	userID := middleware.GetUserIDFromContext(ctx)
	if userID == 0 {
		return errors.New(errors.CodeUnauthorized)
	}

	// 获取正在运行的任务
	runningTasks, err := h.service.GetRunningTasks(ctx, userID)
	if err != nil {
		return err
	}

	items := make([]*dto.ManualTriggerLogResp, 0, len(runningTasks))
	for _, log := range runningTasks {
		items = append(items, h.toLogResp(log))
	}

	queueSizes := make(map[string]int64)
	for _, taskType := range []string{
		constants.TaskTypePollingRealname,
		constants.TaskTypePollingCarddata,
		constants.TaskTypePollingPackage,
		constants.TaskTypePollingProtect,
	} {
		size, _ := h.service.GetQueueSize(ctx, taskType)
		queueSizes[taskType] = size
	}

	return response.Success(c, &dto.ManualTriggerStatusResp{
		RunningTasks: items,
		QueueSizes:   queueSizes,
	})
}

// ListHistory 获取触发历史
// @Summary 获取手动触发历史
// @Description 获取手动触发历史记录
// @Tags 轮询管理-手动触发
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param task_type query string false "任务类型筛选"
// @Param page query int false "页码"
// @Param page_size query int false "每页数量"
// @Success 200 {object} response.Response{data=dto.ManualTriggerLogListResp}
// @Router /api/admin/polling-manual-trigger/history [get]
func (h *PollingManualTriggerHandler) ListHistory(c *fiber.Ctx) error {
	ctx := c.UserContext()

	var req dto.ListManualTriggerLogReq
	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
	}

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

	items := make([]*dto.ManualTriggerLogResp, 0, len(logs))
	for _, log := range logs {
		items = append(items, h.toLogResp(log))
	}

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

// CancelTrigger 取消触发任务
// @Summary 取消手动触发任务
// @Description 取消正在执行的手动触发任务
// @Tags 轮询管理-手动触发
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param request body dto.CancelTriggerReq true "取消请求"
// @Success 200 {object} response.Response
// @Router /api/admin/polling-manual-trigger/cancel [post]
func (h *PollingManualTriggerHandler) CancelTrigger(c *fiber.Ctx) error {
	ctx := c.UserContext()

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

	userID := middleware.GetUserIDFromContext(ctx)
	if userID == 0 {
		return errors.New(errors.CodeUnauthorized)
	}

	if err := h.service.CancelTrigger(ctx, req.TriggerID, userID); err != nil {
		return err
	}

	return response.Success(c, nil)
}

func (h *PollingManualTriggerHandler) toLogResp(log *model.PollingManualTriggerLog) *dto.ManualTriggerLogResp {
	return &dto.ManualTriggerLogResp{
		ID:              log.ID,
		TaskType:        log.TaskType,
		TaskTypeName:    h.getTaskTypeName(log.TaskType),
		TriggerType:     log.TriggerType,
		TriggerTypeName: h.getTriggerTypeName(log.TriggerType),
		TotalCount:      log.TotalCount,
		ProcessedCount:  log.ProcessedCount,
		SuccessCount:    log.SuccessCount,
		FailedCount:     log.FailedCount,
		Status:          log.Status,
		StatusName:      h.getStatusName(log.Status),
		TriggeredBy:     log.TriggeredBy,
		TriggeredAt:     log.TriggeredAt,
		CompletedAt:     log.CompletedAt,
	}
}

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

func (h *PollingManualTriggerHandler) getTriggerTypeName(triggerType string) string {
	switch triggerType {
	case "single":
		return "单卡触发"
	case "batch":
		return "批量触发"
	case "by_condition":
		return "条件筛选"
	default:
		return triggerType
	}
}

func (h *PollingManualTriggerHandler) getStatusName(status string) string {
	switch status {
	case constants.PollingManualTriggerStatusPending:
		return "待处理"
	case constants.PollingManualTriggerStatusProcessing:
		return "处理中"
	case constants.PollingManualTriggerStatusCompleted:
		return "已完成"
	case constants.PollingManualTriggerStatusCancelled:
		return "已取消"
	default:
		return status
	}
}
