package api

import (
	"fmt"
	"net/http"
	"time"

	"strconv"

	"licserver/internal/model"
	"licserver/internal/service"
	"licserver/internal/utils"

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

type DeviceHandler struct {
	deviceService *service.DeviceService
	config        *utils.Config
}

func NewDeviceHandler(deviceService *service.DeviceService, config *utils.Config) *DeviceHandler {

	return &DeviceHandler{deviceService: deviceService, config: config}

}

func (h *DeviceHandler) CreateDevice(c *gin.Context) {

	var input service.DeviceCreateInput

	if err := c.ShouldBindJSON(&input); err != nil {

		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})

		return

	}

	if err := h.deviceService.CreateDevice(&input); err != nil {

		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})

		return

	}

	c.JSON(http.StatusOK, gin.H{"message": "设备创建成功"})

}

func (h *DeviceHandler) GetDevices(c *gin.Context) {

	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))

	pageSize, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))

	params := &service.DeviceQueryParams{

		UID: c.Query("uid"),

		DeviceType: c.Query("deviceType"),

		Company: c.Query("company"),

		LicenseType: c.Query("licenseType"),

		Status: c.Query("status"),

		Page: page,

		PageSize: pageSize,
	}

	devices, total, err := h.deviceService.GetDevices(params)

	if err != nil {

		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})

		return

	}

	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "获取设备列表成功",
		"count":   total,
		"data":    devices,
	})

}

func (h *DeviceHandler) UpdateStartCount(c *gin.Context) {
	uid := c.Param("uid")

	// 更新启动次数
	err := h.deviceService.UpdateStartCount(uid)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":  -1,
			"error": err.Error(),
		})
		return
	}

	// 获取更新后的设备信息
	device, err := h.deviceService.GetDevice(uid)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":  -1,
			"error": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "启动次数更新成功",
		"data": gin.H{
			"start_count":    device.StartCount,
			"status":         device.Status,
			"last_active_at": device.LastActiveAt,
		},
	})
}

func (h *DeviceHandler) UpdateDevice(c *gin.Context) {

	uid := c.Param("uid")

	var updates map[string]interface{}

	if err := c.ShouldBindJSON(&updates); err != nil {

		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})

		return

	}

	if err := h.deviceService.UpdateDevice(uid, updates); err != nil {

		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})

		return

	}

	c.JSON(http.StatusOK, gin.H{"message": "设备更新成功"})

}

func (h *DeviceHandler) DeleteDevice(c *gin.Context) {

	uid := c.Param("uid")

	if err := h.deviceService.DeleteDevice(uid); err != nil {

		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})

		return

	}

	c.JSON(http.StatusOK, gin.H{"message": "设备删除成功"})

}

func (h *DeviceHandler) RegisterDevice(c *gin.Context) {
	var input service.DeviceRegisterInput

	// 检查Content-Type
	if c.ContentType() != "application/json" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Content-Type must be application/json"})
		return
	}

	// 绑定JSON数据
	if err := c.ShouldBindJSON(&input); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":  -1,
			"error": "无效的请求数据: " + err.Error(),
		})
		return
	}

	// 验证必填字段
	if input.UID == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":  -1,
			"error": "设备UID不能为空",
		})
		return
	}

	if input.DeviceModel == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":  -1,
			"error": "设备型号不能为空",
		})
		return
	}

	// 注册设备
	if err := h.deviceService.RegisterDevice(&input, c.ClientIP()); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":  -1,
			"error": err.Error(),
		})
		return
	}

	status := "未激活"
	if input.LicenseCode != "" {
		status = "已激活"
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": fmt.Sprintf("设备注册成功,当前状态:%s", status),
		"data": gin.H{
			"uid":          input.UID,
			"device_model": input.DeviceModel,
			"status":       status,
		},
	})
}

func (h *DeviceHandler) ValidateDevice(c *gin.Context) {
	uid := c.Param("uid")

	device, err := h.deviceService.GetDevice(uid)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":  -1,
			"error": err.Error(),
		})
		return
	}

	// 验证设备状态
	if err := h.deviceService.ValidateDevice(uid); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":  -1,
			"error": err.Error(),
		})
		return
	}

	// 准备加密响应数据
	response := utils.DeviceValidateResponse{
		Status:      device.Status,
		LicenseType: device.LicenseType,
		ExpireTime:  device.ExpireTime.Format(time.RFC3339),
		StartCount:  device.StartCount,
		MaxUses:     device.MaxUses,
		Timestamp:   time.Now().Unix(),
	}

	// 加密响应
	encrypted, err := utils.EncryptResponse(response, []byte(h.config.Security.EncryptKey))
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":  -1,
			"error": "加密响应失败: " + err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code": 0,
		"data": encrypted,
	})
}

func (h *DeviceHandler) BindLicense(c *gin.Context) {
	uid := c.Param("uid")
	var input struct {
		LicenseCode string `json:"license_code" binding:"required"`
	}

	if err := c.ShouldBindJSON(&input); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if err := h.deviceService.BindLicense(uid, input.LicenseCode); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "授权码绑定成功",
	})
}

func (h *DeviceHandler) UnbindLicense(c *gin.Context) {
	uid := c.Param("uid")

	if err := h.deviceService.UnbindLicense(uid); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "授权码解绑成功",
	})
}

func (h *DeviceHandler) GetLicenseInfo(c *gin.Context) {

	deviceUID := c.Param("uid")

	device, err := h.deviceService.GetLicenseInfo(deviceUID)

	if err != nil {

		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})

		return

	}

	c.JSON(http.StatusOK, device)

}

func (h *DeviceHandler) CheckLicenseStatus(c *gin.Context) {

	deviceUID := c.Param("uid")

	status, err := h.deviceService.CheckLicenseStatus(deviceUID)

	if err != nil {

		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})

		return

	}

	c.JSON(http.StatusOK, gin.H{

		"status": status,
	})

}

func (h *DeviceHandler) CheckUpdate(c *gin.Context) {
	deviceUID := c.Param("uid")
	currentVersion := c.Query("version")

	update, err := h.deviceService.CheckUpdate(deviceUID, currentVersion)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, update)
}

func (h *DeviceHandler) CreateDeviceModel(c *gin.Context) {
	var model model.DeviceModel
	if err := c.ShouldBindJSON(&model); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	model.CreatedBy = c.GetUint("userID")
	model.Status = "active"

	if err := h.deviceService.CreateDeviceModel(&model); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "设备型号创建成功",
		"data":    model,
	})
}

func (h *DeviceHandler) GetDeviceModels(c *gin.Context) {
	modelName := c.Query("model_name")
	deviceType := c.Query("device_type")
	company := c.Query("company")
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))

	models, total, err := h.deviceService.GetDeviceModels(modelName, deviceType, company, page, pageSize)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":  0,
		"msg":   "",
		"count": total,
		"data":  models,
	})
}

func (h *DeviceHandler) UpdateDeviceModel(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的ID"})
		return
	}

	var input model.DeviceModel
	if err := c.ShouldBindJSON(&input); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if err := h.deviceService.UpdateDeviceModel(uint(id), &input); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":  -1,
			"error": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "设备型号更新成功",
	})
}

func (h *DeviceHandler) DeleteDeviceModel(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的ID"})
		return
	}

	if err := h.deviceService.DeleteDeviceModel(uint(id)); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "设备型号删除成功",
	})
}

func (h *DeviceHandler) BatchDeleteDeviceModels(c *gin.Context) {
	var input struct {
		IDs []uint `json:"ids" binding:"required"`
	}

	if err := c.ShouldBindJSON(&input); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if err := h.deviceService.BatchDeleteDeviceModels(input.IDs); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "设备型号批量删除成功",
	})
}

func (h *DeviceHandler) GetRegisteredDevices(c *gin.Context) {
	uid := c.Query("uid")
	deviceModel := c.Query("device_model")
	status := c.Query("status")
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))

	devices, total, err := h.deviceService.GetRegisteredDevices(uid, deviceModel, status, page, pageSize)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":  0,
		"msg":   "",
		"count": total,
		"data":  devices,
	})
}

func (h *DeviceHandler) GetDeviceLogs(c *gin.Context) {
	uid := c.Param("uid")
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))

	logs, total, err := h.deviceService.GetDeviceLogs(uid, page, pageSize)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":  0,
		"msg":   "",
		"count": total,
		"data":  logs,
	})
}