package admin

import (
	"strconv"

	"github.com/gofiber/fiber/v2"

	"github.com/break/junhong_cmp_fiber/internal/gateway"
	"github.com/break/junhong_cmp_fiber/internal/model/dto"
	deviceService "github.com/break/junhong_cmp_fiber/internal/service/device"
	"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"
)

type DeviceHandler struct {
	service       *deviceService.Service
	gatewayClient *gateway.Client
}

func NewDeviceHandler(service *deviceService.Service, gatewayClient *gateway.Client) *DeviceHandler {
	return &DeviceHandler{
		service:       service,
		gatewayClient: gatewayClient,
	}
}

func (h *DeviceHandler) List(c *fiber.Ctx) error {
	var req dto.ListDeviceRequest
	if err := c.QueryParser(&req); err != nil {
		return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
	}

	result, err := h.service.List(c.UserContext(), &req)
	if err != nil {
		return err
	}

	return response.SuccessWithPagination(c, result.List, result.Total, result.Page, result.PageSize)
}

func (h *DeviceHandler) GetByID(c *fiber.Ctx) error {
	idStr := c.Params("id")
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		return errors.New(errors.CodeInvalidParam, "无效的设备ID")
	}

	result, err := h.service.Get(c.UserContext(), uint(id))
	if err != nil {
		return err
	}

	return response.Success(c, result)
}

func (h *DeviceHandler) GetByIMEI(c *fiber.Ctx) error {
	imei := c.Params("imei")
	if imei == "" {
		return errors.New(errors.CodeInvalidParam, "设备号不能为空")
	}

	result, err := h.service.GetByDeviceNo(c.UserContext(), imei)
	if err != nil {
		return err
	}

	return response.Success(c, result)
}

func (h *DeviceHandler) Delete(c *fiber.Ctx) error {
	userType := middleware.GetUserTypeFromContext(c.UserContext())
	if userType != constants.UserTypeSuperAdmin && userType != constants.UserTypePlatform {
		return errors.New(errors.CodeForbidden, "仅平台用户可删除设备")
	}

	idStr := c.Params("id")
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		return errors.New(errors.CodeInvalidParam, "无效的设备ID")
	}

	if err := h.service.Delete(c.UserContext(), uint(id)); err != nil {
		return err
	}

	return response.Success(c, nil)
}

func (h *DeviceHandler) ListCards(c *fiber.Ctx) error {
	idStr := c.Params("id")
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		return errors.New(errors.CodeInvalidParam, "无效的设备ID")
	}

	result, err := h.service.ListBindings(c.UserContext(), uint(id))
	if err != nil {
		return err
	}

	return response.Success(c, result)
}

func (h *DeviceHandler) BindCard(c *fiber.Ctx) error {
	userType := middleware.GetUserTypeFromContext(c.UserContext())
	if userType != constants.UserTypeSuperAdmin && userType != constants.UserTypePlatform {
		return errors.New(errors.CodeForbidden, "仅平台用户可绑定卡到设备")
	}

	idStr := c.Params("id")
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		return errors.New(errors.CodeInvalidParam, "无效的设备ID")
	}

	var req dto.BindCardToDeviceRequest
	if err := c.BodyParser(&req); err != nil {
		return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
	}
	req.ID = uint(id)

	result, err := h.service.BindCard(c.UserContext(), uint(id), &req)
	if err != nil {
		return err
	}

	return response.Success(c, result)
}

func (h *DeviceHandler) UnbindCard(c *fiber.Ctx) error {
	userType := middleware.GetUserTypeFromContext(c.UserContext())
	if userType != constants.UserTypeSuperAdmin && userType != constants.UserTypePlatform {
		return errors.New(errors.CodeForbidden, "仅平台用户可解绑设备的卡")
	}

	idStr := c.Params("id")
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		return errors.New(errors.CodeInvalidParam, "无效的设备ID")
	}

	cardIdStr := c.Params("cardId")
	cardId, err := strconv.ParseUint(cardIdStr, 10, 64)
	if err != nil {
		return errors.New(errors.CodeInvalidParam, "无效的卡ID")
	}

	result, err := h.service.UnbindCard(c.UserContext(), uint(id), uint(cardId))
	if err != nil {
		return err
	}

	return response.Success(c, result)
}

func (h *DeviceHandler) Allocate(c *fiber.Ctx) error {
	var req dto.AllocateDevicesRequest
	if err := c.BodyParser(&req); err != nil {
		return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
	}

	userID := middleware.GetUserIDFromContext(c.UserContext())
	shopID := middleware.GetShopIDFromContext(c.UserContext())

	var shopIDPtr *uint
	if shopID > 0 {
		shopIDPtr = &shopID
	}

	result, err := h.service.AllocateDevices(c.UserContext(), &req, userID, shopIDPtr)
	if err != nil {
		return err
	}

	return response.Success(c, result)
}

func (h *DeviceHandler) Recall(c *fiber.Ctx) error {
	var req dto.RecallDevicesRequest
	if err := c.BodyParser(&req); err != nil {
		return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
	}

	userID := middleware.GetUserIDFromContext(c.UserContext())
	shopID := middleware.GetShopIDFromContext(c.UserContext())

	var shopIDPtr *uint
	if shopID > 0 {
		shopIDPtr = &shopID
	}

	result, err := h.service.RecallDevices(c.UserContext(), &req, userID, shopIDPtr)
	if err != nil {
		return err
	}

	return response.Success(c, result)
}

func (h *DeviceHandler) BatchSetSeriesBinding(c *fiber.Ctx) error {
	var req dto.BatchSetDeviceSeriesBindngRequest
	if err := c.BodyParser(&req); err != nil {
		return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
	}

	ctx := c.UserContext()
	userType := middleware.GetUserTypeFromContext(ctx)

	var operatorShopID *uint
	if userType == constants.UserTypeAgent {
		shopID := middleware.GetShopIDFromContext(ctx)
		if shopID > 0 {
			operatorShopID = &shopID
		}
	}

	result, err := h.service.BatchSetSeriesBinding(ctx, &req, operatorShopID)
	if err != nil {
		return err
	}

	return response.Success(c, result)
}

// GetGatewayInfo 查询设备信息
func (h *DeviceHandler) GetGatewayInfo(c *fiber.Ctx) error {
	imei := c.Params("imei")
	if imei == "" {
		return errors.New(errors.CodeInvalidParam, "设备号不能为空")
	}

	// 验证权限：查询数据库确认设备存在且用户有权限访问
	_, err := h.service.GetByDeviceNo(c.UserContext(), imei)
	if err != nil {
		return errors.New(errors.CodeNotFound, "设备不存在或无权限访问")
	}

	// 调用 Gateway
	resp, err := h.gatewayClient.GetDeviceInfo(c.UserContext(), &gateway.DeviceInfoReq{
		DeviceID: imei,
	})
	if err != nil {
		return err
	}

	return response.Success(c, resp)
}

// GetGatewaySlots 查询设备卡槽信息
func (h *DeviceHandler) GetGatewaySlots(c *fiber.Ctx) error {
	imei := c.Params("imei")
	if imei == "" {
		return errors.New(errors.CodeInvalidParam, "设备号不能为空")
	}

	// 验证权限：查询数据库确认设备存在且用户有权限访问
	_, err := h.service.GetByDeviceNo(c.UserContext(), imei)
	if err != nil {
		return errors.New(errors.CodeNotFound, "设备不存在或无权限访问")
	}

	// 调用 Gateway
	resp, err := h.gatewayClient.GetSlotInfo(c.UserContext(), &gateway.DeviceInfoReq{
		DeviceID: imei,
	})
	if err != nil {
		return err
	}

	return response.Success(c, resp)
}

// SetSpeedLimit 设置设备限速
func (h *DeviceHandler) SetSpeedLimit(c *fiber.Ctx) error {
	imei := c.Params("imei")
	if imei == "" {
		return errors.New(errors.CodeInvalidParam, "设备号不能为空")
	}

	var req gateway.SpeedLimitReq
	if err := c.BodyParser(&req); err != nil {
		return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
	}

	// 验证权限：查询数据库确认设备存在且用户有权限访问
	_, err := h.service.GetByDeviceNo(c.UserContext(), imei)
	if err != nil {
		return errors.New(errors.CodeNotFound, "设备不存在或无权限访问")
	}

	// 调用 Gateway
	req.DeviceID = imei
	err = h.gatewayClient.SetSpeedLimit(c.UserContext(), &req)
	if err != nil {
		return err
	}

	return response.Success(c, nil)
}

// SetWiFi 设置设备 WiFi
func (h *DeviceHandler) SetWiFi(c *fiber.Ctx) error {
	imei := c.Params("imei")
	if imei == "" {
		return errors.New(errors.CodeInvalidParam, "设备号不能为空")
	}

	var req gateway.WiFiReq
	if err := c.BodyParser(&req); err != nil {
		return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
	}

	// 验证权限：查询数据库确认设备存在且用户有权限访问
	_, err := h.service.GetByDeviceNo(c.UserContext(), imei)
	if err != nil {
		return errors.New(errors.CodeNotFound, "设备不存在或无权限访问")
	}

	// 调用 Gateway
	req.DeviceID = imei
	err = h.gatewayClient.SetWiFi(c.UserContext(), &req)
	if err != nil {
		return err
	}

	return response.Success(c, nil)
}

// SwitchCard 切换设备使用的卡
func (h *DeviceHandler) SwitchCard(c *fiber.Ctx) error {
	imei := c.Params("imei")
	if imei == "" {
		return errors.New(errors.CodeInvalidParam, "设备号不能为空")
	}

	var req gateway.SwitchCardReq
	if err := c.BodyParser(&req); err != nil {
		return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
	}

	// 验证权限：查询数据库确认设备存在且用户有权限访问
	_, err := h.service.GetByDeviceNo(c.UserContext(), imei)
	if err != nil {
		return errors.New(errors.CodeNotFound, "设备不存在或无权限访问")
	}

	// 调用 Gateway
	req.DeviceID = imei
	err = h.gatewayClient.SwitchCard(c.UserContext(), &req)
	if err != nil {
		return err
	}

	return response.Success(c, nil)
}

// RebootDevice 重启设备
func (h *DeviceHandler) RebootDevice(c *fiber.Ctx) error {
	imei := c.Params("imei")
	if imei == "" {
		return errors.New(errors.CodeInvalidParam, "设备号不能为空")
	}

	// 验证权限：查询数据库确认设备存在且用户有权限访问
	_, err := h.service.GetByDeviceNo(c.UserContext(), imei)
	if err != nil {
		return errors.New(errors.CodeNotFound, "设备不存在或无权限访问")
	}

	// 调用 Gateway
	err = h.gatewayClient.RebootDevice(c.UserContext(), &gateway.DeviceOperationReq{
		DeviceID: imei,
	})
	if err != nil {
		return err
	}

	return response.Success(c, nil)
}

// ResetDevice 恢复设备出厂设置
func (h *DeviceHandler) ResetDevice(c *fiber.Ctx) error {
	imei := c.Params("imei")
	if imei == "" {
		return errors.New(errors.CodeInvalidParam, "设备号不能为空")
	}

	// 验证权限：查询数据库确认设备存在且用户有权限访问
	_, err := h.service.GetByDeviceNo(c.UserContext(), imei)
	if err != nil {
		return errors.New(errors.CodeNotFound, "设备不存在或无权限访问")
	}

	// 调用 Gateway
	err = h.gatewayClient.ResetDevice(c.UserContext(), &gateway.DeviceOperationReq{
		DeviceID: imei,
	})
	if err != nil {
		return err
	}

	return response.Success(c, nil)
}
