package admin

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

	dto "github.com/break/junhong_cmp_fiber/internal/model/dto"
	assetService "github.com/break/junhong_cmp_fiber/internal/service/asset"
	deviceService "github.com/break/junhong_cmp_fiber/internal/service/device"
	iotCardService "github.com/break/junhong_cmp_fiber/internal/service/iot_card"
	pollingSvc "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"
)

// AssetHandler 资产管理处理器
// 提供统一的资产解析、实时状态、套餐查询、停复机、停用、轮询管控等接口
type AssetHandler struct {
	assetService          *assetService.Service
	deviceService         *deviceService.Service
	iotCardStopResume     *iotCardService.StopResumeService
	assetPolling          *pollingSvc.AssetPollingService
	assetLifecycleService AssetLifecycleService
}

// NewAssetHandler 创建资产管理处理器
func NewAssetHandler(
	assetSvc *assetService.Service,
	deviceSvc *deviceService.Service,
	iotCardStopResume *iotCardService.StopResumeService,
	assetPolling *pollingSvc.AssetPollingService,
) *AssetHandler {
	return &AssetHandler{
		assetService:      assetSvc,
		deviceService:     deviceSvc,
		iotCardStopResume: iotCardStopResume,
		assetPolling:      assetPolling,
	}
}

// SetLifecycleService 注入生命周期服务（用于 Deactivate 接口）
func (h *AssetHandler) SetLifecycleService(svc AssetLifecycleService) {
	h.assetLifecycleService = svc
}

// resolveByIdentifier 通过标识符解析资产，用于各处理器的公共逻辑
func (h *AssetHandler) resolveByIdentifier(c *fiber.Ctx) (*dto.AssetResolveResponse, error) {
	identifier := c.Params("identifier")
	if identifier == "" {
		return nil, errors.New(errors.CodeInvalidParam, "标识符不能为空")
	}
	return h.assetService.Resolve(c.UserContext(), identifier)
}

// Resolve 通过任意标识符解析资产（设备或卡）
// GET /api/admin/assets/resolve/:identifier
func (h *AssetHandler) Resolve(c *fiber.Ctx) error {
	identifier := c.Params("identifier")
	if identifier == "" {
		return errors.New(errors.CodeInvalidParam, "标识符不能为空")
	}

	result, err := h.assetService.Resolve(c.UserContext(), identifier)
	if err != nil {
		return err
	}

	return response.Success(c, result)
}

// RealtimeStatus 获取资产实时状态
// GET /api/admin/assets/:identifier/realtime-status
func (h *AssetHandler) RealtimeStatus(c *fiber.Ctx) error {
	asset, err := h.resolveByIdentifier(c)
	if err != nil {
		return err
	}

	result, err := h.assetService.GetRealtimeStatus(c.UserContext(), asset.AssetType, asset.AssetID)
	if err != nil {
		return err
	}

	return response.Success(c, result)
}

// Refresh 刷新资产状态（调网关同步）
// POST /api/admin/assets/:identifier/refresh
func (h *AssetHandler) Refresh(c *fiber.Ctx) error {
	userType := middleware.GetUserTypeFromContext(c.UserContext())
	if userType == constants.UserTypeEnterprise {
		return errors.New(errors.CodeForbidden, "企业账号无权主动刷新资产状态")
	}

	asset, err := h.resolveByIdentifier(c)
	if err != nil {
		return err
	}

	result, err := h.assetService.Refresh(c.UserContext(), asset.AssetType, asset.AssetID)
	if err != nil {
		return err
	}

	return response.Success(c, result)
}

// Packages 获取资产所有套餐列表（支持分页，默认 page=1 pageSize=50）
// GET /api/admin/assets/:identifier/packages
func (h *AssetHandler) Packages(c *fiber.Ctx) error {
	asset, err := h.resolveByIdentifier(c)
	if err != nil {
		return err
	}

	page := c.QueryInt("page", 1)
	pageSize := c.QueryInt("page_size", 50)

	result, err := h.assetService.GetPackages(c.UserContext(), asset.AssetType, asset.AssetID, page, pageSize)
	if err != nil {
		return err
	}

	return response.Success(c, result)
}

// CurrentPackage 获取资产当前生效套餐
// GET /api/admin/assets/:identifier/current-package
func (h *AssetHandler) CurrentPackage(c *fiber.Ctx) error {
	asset, err := h.resolveByIdentifier(c)
	if err != nil {
		return err
	}

	result, err := h.assetService.GetCurrentPackage(c.UserContext(), asset.AssetType, asset.AssetID)
	if err != nil {
		return err
	}

	return response.Success(c, result)
}

// Stop 停机（设备批量停机，单卡停机）
// POST /api/admin/assets/:identifier/stop
func (h *AssetHandler) Stop(c *fiber.Ctx) error {
	asset, err := h.resolveByIdentifier(c)
	if err != nil {
		return err
	}

	switch asset.AssetType {
	case "device":
		result, devErr := h.deviceService.StopDevice(c.UserContext(), asset.AssetID)
		if devErr != nil {
			return devErr
		}
		return response.Success(c, result)
	case "card":
		if asset.ICCID == "" {
			return errors.New(errors.CodeInternalError, "卡 ICCID 为空，无法停机")
		}
		if cardErr := h.iotCardStopResume.ManualStopCard(c.UserContext(), asset.ICCID); cardErr != nil {
			return cardErr
		}
		return response.Success(c, nil)
	default:
		return errors.New(errors.CodeInvalidParam, "不支持的资产类型")
	}
}

// Start 复机（设备批量复机，单卡复机）
// POST /api/admin/assets/:identifier/start
func (h *AssetHandler) Start(c *fiber.Ctx) error {
	asset, err := h.resolveByIdentifier(c)
	if err != nil {
		return err
	}

	switch asset.AssetType {
	case "device":
		if devErr := h.deviceService.StartDevice(c.UserContext(), asset.AssetID); devErr != nil {
			return devErr
		}
		return response.Success(c, nil)
	case "card":
		if asset.ICCID == "" {
			return errors.New(errors.CodeInternalError, "卡 ICCID 为空，无法复机")
		}
		if cardErr := h.iotCardStopResume.ManualStartCard(c.UserContext(), asset.ICCID); cardErr != nil {
			return cardErr
		}
		return response.Success(c, nil)
	default:
		return errors.New(errors.CodeInvalidParam, "不支持的资产类型")
	}
}

// Deactivate 停用资产
// PATCH /api/admin/assets/:identifier/deactivate
func (h *AssetHandler) Deactivate(c *fiber.Ctx) error {
	if h.assetLifecycleService == nil {
		return errors.New(errors.CodeInternalError, "资产生命周期服务未配置")
	}

	asset, err := h.resolveByIdentifier(c)
	if err != nil {
		return err
	}

	switch asset.AssetType {
	case "device":
		if devErr := h.assetLifecycleService.DeactivateDevice(c.UserContext(), asset.AssetID); devErr != nil {
			return devErr
		}
	case "card":
		if cardErr := h.assetLifecycleService.DeactivateIotCard(c.UserContext(), asset.AssetID); cardErr != nil {
			return cardErr
		}
	default:
		return errors.New(errors.CodeInvalidParam, "不支持的资产类型")
	}

	return response.Success(c, nil)
}

// Orders 查询资产历史订单（支持跨代追溯）
// GET /api/admin/assets/:identifier/orders
func (h *AssetHandler) Orders(c *fiber.Ctx) error {
	identifier := c.Params("identifier")
	if identifier == "" {
		return errors.New(errors.CodeInvalidParam, "标识符不能为空")
	}

	page := c.QueryInt("page", 1)
	pageSize := c.QueryInt("page_size", 20)
	includePrevious := c.QueryBool("include_previous", false)

	result, err := h.assetService.GetOrders(c.UserContext(), identifier, page, pageSize, includePrevious)
	if err != nil {
		return err
	}

	return response.Success(c, result)
}

// UpdatePollingStatus 更新资产轮询状态
// PATCH /api/admin/assets/:identifier/polling-status
func (h *AssetHandler) UpdatePollingStatus(c *fiber.Ctx) error {
	identifier := c.Params("identifier")
	if identifier == "" {
		return errors.New(errors.CodeInvalidParam)
	}

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

	asset, err := h.assetService.Resolve(c.UserContext(), identifier)
	if err != nil {
		return err
	}

	_ = middleware.GetUserIDFromContext(c.UserContext())

	if h.assetPolling == nil {
		return errors.New(errors.CodeInternalError, "轮询管控服务未配置")
	}

	pollingAssetType := asset.AssetType
	if pollingAssetType == "card" {
		pollingAssetType = "iot_card"
	}

	if err := h.assetPolling.UpdatePollingStatus(c.UserContext(), pollingAssetType, asset.AssetID, req.EnablePolling); err != nil {
		return err
	}

	return response.Success(c, &dto.UpdateAssetPollingStatusResponse{
		AssetType:     asset.AssetType,
		AssetID:       asset.AssetID,
		EnablePolling: req.EnablePolling,
	})
}
