package service

import (
	"errors"
	"fmt"

	"licserver/internal/model"

	"time"

	"gorm.io/gorm"
)

type DeviceService struct {
	db *gorm.DB

	licenseService *LicenseService
}

func NewDeviceService(db *gorm.DB, licenseService *LicenseService) *DeviceService {

	return &DeviceService{

		db: db,

		licenseService: licenseService,
	}

}

type DeviceRegisterInput struct {
	UID         string `json:"uid" binding:"required"`
	DeviceModel string `json:"device_model" binding:"required"`
	LicenseCode string `json:"license_code,omitempty"`
}

func (s *DeviceService) RegisterDevice(input *DeviceRegisterInput, ip string) error {
	// 检查设备型号是否存在且处于启用状态
	var deviceModel model.DeviceModel
	if err := s.db.Where("model_name = ? AND status = ?", input.DeviceModel, "active").First(&deviceModel).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("设备型号不存在或已禁用")
		}
		return err
	}

	// 检查设备是否已注册
	var count int64
	s.db.Model(&model.Device{}).Where("uid = ?", input.UID).Count(&count)
	if count > 0 {
		return errors.New("设备已注册")
	}

	// 创建设备记录
	device := &model.Device{
		UID:          input.UID,
		DeviceType:   deviceModel.DeviceType,
		DeviceModel:  input.DeviceModel,
		Company:      deviceModel.Company,
		RegisterTime: time.Now(),
		Status:       "inactive",
		LastActiveAt: time.Now(),
		StartCount:   0,
	}

	// 如果提供了授权码，进行授权绑定
	if input.LicenseCode != "" {
		license, err := s.licenseService.GetLicenseByCode(input.LicenseCode)
		if err != nil {
			return err
		}

		if license.Status != "unused" {
			return errors.New("授权码已被使用")
		}

		device.Status = "active"
		device.LicenseCode = license.Code
		device.LicenseType = license.LicenseType
		device.MaxUses = license.MaxUses
		device.Duration = license.Duration

		if license.LicenseType == "time" {
			device.ExpireTime = time.Now().Add(time.Duration(license.Duration) * time.Minute)
		}
	}

	return s.db.Transaction(func(tx *gorm.DB) error {
		// 创建设备记录
		if err := tx.Create(device).Error; err != nil {
			return err
		}

		// 如果有授权码，更新授权码状态
		if device.LicenseCode != "" {
			if err := tx.Model(&model.LicenseCode{}).Where("code = ?", device.LicenseCode).
				Updates(map[string]interface{}{
					"status":  "used",
					"used_by": input.UID,
					"used_at": time.Now(),
				}).Error; err != nil {
				return err
			}
		}

		// 记录设备日志
		log := model.DeviceLog{
			DeviceUID: input.UID,
			Action:    "register",
			Message:   fmt.Sprintf("设备注册成功，状态：%s", device.Status),
			Status:    "success",
			IP:        ip,
		}
		if err := tx.Create(&log).Error; err != nil {
			return err
		}

		return nil
	})
}

func (s *DeviceService) ValidateDevice(uid string) error {
	var device model.Device
	if err := s.db.Where("uid = ?", uid).First(&device).Error; err != nil {
		return errors.New("设备未注册")
	}

	// 更新最后活跃时间
	device.LastActiveAt = time.Now()

	// 如果设备已激活，检查授权状态
	if device.Status == "active" {
		if device.LicenseCode != "" {
			if err := s.licenseService.CheckLicenseValidity(device.LicenseCode); err != nil {
				device.Status = "expired"
				s.db.Save(&device)
				return errors.New("设备授权已过期")
			}
		}
	}

	return s.db.Save(&device).Error
}

func (s *DeviceService) GetDevices(params *DeviceQueryParams) ([]model.Device, int64, error) {

	var devices []model.Device

	var total int64

	query := s.db.Model(&model.Device{})

	if params.UID != "" {

		query = query.Where("uid LIKE ?", "%"+params.UID+"%")

	}

	if params.DeviceType != "" {

		query = query.Where("device_type = ?", params.DeviceType)

	}

	if params.Company != "" {

		query = query.Where("company LIKE ?", "%"+params.Company+"%")

	}

	if params.LicenseType != "" {

		query = query.Where("license_type = ?", params.LicenseType)

	}

	if params.Status != "" {

		query = query.Where("status = ?", params.Status)

	}

	query.Count(&total)

	if params.Page > 0 && params.PageSize > 0 {

		offset := (params.Page - 1) * params.PageSize

		query = query.Offset(offset).Limit(params.PageSize)

	}

	err := query.Find(&devices).Error

	return devices, total, err

}

func (s *DeviceService) UpdateStartCount(uid string) error {
	var device model.Device
	if err := s.db.Where("uid = ?", uid).First(&device).Error; err != nil {
		return err
	}

	// 更新启动次数和最后活跃时间
	device.StartCount++
	device.LastActiveAt = time.Now()

	// 如果设备已激活，检查授权状态
	if device.Status == "active" {
		// 检查授权码有效性
		if device.LicenseCode != "" {
			if err := s.licenseService.CheckLicenseValidity(device.LicenseCode); err != nil {
				device.Status = "expired"
			}
		}
		// 检查次数限制
		if device.LicenseType == "count" && device.StartCount >= device.MaxUses {
			device.Status = "expired"
		}
	}

	// 记录设备日志
	log := model.DeviceLog{
		DeviceUID: uid,
		Action:    "start",
		Message:   fmt.Sprintf("设备启动，当前次数：%d", device.StartCount),
		Status:    "success",
	}

	return s.db.Transaction(func(tx *gorm.DB) error {
		if err := tx.Save(&device).Error; err != nil {
			return err
		}
		return tx.Create(&log).Error
	})
}

func (s *DeviceService) UpdateDevice(uid string, updates map[string]interface{}) error {

	return s.db.Model(&model.Device{}).Where("uid = ?", uid).Updates(updates).Error

}

func (s *DeviceService) DeleteDevice(uid string) error {

	return s.db.Where("uid = ?", uid).Delete(&model.Device{}).Error

}

func (s *DeviceService) GetLicenseInfo(deviceUID string) (*model.Device, error) {

	var device model.Device

	if err := s.db.Where("uid = ?", deviceUID).First(&device).Error; err != nil {

		return nil, errors.New("设备不存在")

	}

	return &device, nil

}

func (s *DeviceService) CheckLicenseStatus(deviceUID string) (string, error) {

	var device model.Device

	if err := s.db.Where("uid = ?", deviceUID).First(&device).Error; err != nil {

		return "", errors.New("设备不存在")

	}

	if device.LicenseCode == "" {

		return "未授权", nil

	}

	if device.Status != "active" {

		return device.Status, nil

	}

	switch device.LicenseType {

	case "时间段":

		if time.Now().After(device.ExpireTime) {

			device.Status = "expired"

			s.db.Save(&device)

			return "已过期", nil

		}

	case "启动次数":

		if device.StartCount >= device.MaxUses {

			device.Status = "expired"

			s.db.Save(&device)

			return "已达到使用上限", nil

		}

	}

	return "正常", nil

}

type DeviceQueryParams struct {
	UID         string
	DeviceType  string
	Company     string
	LicenseType string
	Status      string
	Page        int
	PageSize    int
}

type DeviceCreateInput struct {
	UID         string `json:"uid" binding:"required"`
	DeviceType  string `json:"device_type" binding:"required"`
	DeviceModel string `json:"device_model" binding:"required"`
	Company     string `json:"company"`
}

func (s *DeviceService) CreateDevice(input *DeviceCreateInput) error {
	// 检查设备UID���否已存在
	var count int64
	if err := s.db.Model(&model.Device{}).Where("uid = ?", input.UID).Count(&count).Error; err != nil {
		return err
	}
	if count > 0 {
		return errors.New("设备UID已存在")
	}

	// 创建设备记录
	device := &model.Device{
		UID:          input.UID,
		DeviceType:   input.DeviceType,
		DeviceModel:  input.DeviceModel,
		Company:      input.Company,
		RegisterTime: time.Now(),
		Status:       "inactive", // 初始状态为未激活
	}

	return s.db.Create(device).Error
}

// 添加更新检查方法
func (s *DeviceService) CheckUpdate(deviceUID, currentVersion string) (*model.FileUpload, error) {
	// 获取设备信息
	var device model.Device
	if err := s.db.Where("uid = ?", deviceUID).First(&device).Error; err != nil {
		return nil, errors.New("设备不存在")
	}

	// 检查设备状态
	if device.Status != "active" {
		return nil, errors.New("设备未激活或已过期")
	}

	// 查找最新的更新文件
	var update model.FileUpload
	err := s.db.Where("device_model = ? AND is_update = ?", device.DeviceModel, true).
		Order("created_at DESC").
		First(&update).Error

	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, nil // 没有可用更新
		}
		return nil, err
	}

	// 比较版本
	if update.Version <= currentVersion && !update.ForceUpdate {
		return nil, nil // 当前版本已是最新
	}

	return &update, nil
}

// 添加设备型号相关的方法

// CreateDeviceModel 创建设备型号
func (s *DeviceService) CreateDeviceModel(model_ *model.DeviceModel) error {
	// 检查型号名称是否已存在
	var count int64
	s.db.Model(&model.DeviceModel{}).Where("model_name = ?", model_.ModelName).Count(&count)
	if count > 0 {
		return errors.New("设备型号已存在")
	}

	return s.db.Create(model_).Error
}

// UpdateDeviceModel 更新设备型号
func (s *DeviceService) UpdateDeviceModel(id uint, input *model.DeviceModel) error {
	// 检查设备型号是否存在
	var existingModel model.DeviceModel
	if err := s.db.First(&existingModel, id).Error; err != nil {
		return errors.New("设备型号不存在")
	}

	// 如果型号名称发生变更，需要检查是否存在冲突
	if input.ModelName != existingModel.ModelName {
		// 检查新的型号名称是否与其他型号冲突（排除自身）
		var count int64
		s.db.Model(&model.DeviceModel{}).
			Where("model_name = ? AND id != ?", input.ModelName, id).
			Count(&count)
		if count > 0 {

			return fmt.Errorf("设备型号[%d]:%s已存在", id, input.ModelName)
		}

		// 检查是否有设备正在使用此型号
		var deviceCount int64
		s.db.Model(&model.Device{}).
			Where("device_model = ?", existingModel.ModelName).
			Count(&deviceCount)
		if deviceCount > 0 {
			return errors.New("该型号下存在设备，无法修改型号名称")
		}
	}

	// 更新设备型号信息
	updates := map[string]interface{}{
		"device_type": input.DeviceType,
		"company":     input.Company,
		"status":      input.Status,
		"remark":      input.Remark,
	}

	// 只有当型号名称变更时才更新
	if input.ModelName != existingModel.ModelName {
		updates["model_name"] = input.ModelName
	}

	return s.db.Model(&existingModel).Updates(updates).Error
}

// DeleteDeviceModel 删除设备型号
func (s *DeviceService) DeleteDeviceModel(id uint) error {
	// 检查是否有设备使用此型号
	var count int64
	s.db.Model(&model.DeviceModel{}).Where("device_model = ?", id).Count(&count)
	if count > 0 {
		return errors.New("该型号下存在设备，无法删除")
	}

	return s.db.Delete(&model.DeviceModel{}, id).Error
}

// GetDeviceModels 获取设备型号列表
func (s *DeviceService) GetDeviceModels(modelName, deviceType, company string, page, pageSize int) ([]model.DeviceModel, int64, error) {
	var models []model.DeviceModel
	var total int64

	query := s.db.Model(&model.DeviceModel{})

	if modelName != "" {
		query = query.Where("model_name LIKE ?", "%"+modelName+"%")
	}
	if deviceType != "" {
		query = query.Where("device_type = ?", deviceType)
	}
	if company != "" {
		query = query.Where("company LIKE ?", "%"+company+"%")
	}

	// 取总数
	query.Count(&total)

	// 分页查询
	if page > 0 && pageSize > 0 {
		offset := (page - 1) * pageSize
		query = query.Offset(offset).Limit(pageSize)
	}

	// 查询设备型号列表
	if err := query.Find(&models).Error; err != nil {
		return nil, 0, err
	}

	// 查询每个型号下的设备数量
	for i := range models {
		var count int64
		s.db.Model(&model.Device{}).Where("device_model = ?", models[i].ModelName).Count(&count)
		models[i].DeviceCount = int(count)
	}

	return models, total, nil
}

// BatchDeleteDeviceModels 批量删除设备型号
func (s *DeviceService) BatchDeleteDeviceModels(ids []uint) error {
	// 检查是否有设备使用这些型号
	var count int64
	s.db.Model(&model.Device{}).Where("device_model IN (?)", ids).Count(&count)
	if count > 0 {
		return errors.New("选中的型号中存在正在使用的型号，无法删除")
	}

	return s.db.Delete(&model.DeviceModel{}, ids).Error
}

// GetRegisteredDevices 获取已注册设备列表
func (s *DeviceService) GetRegisteredDevices(uid, deviceModel, status string, page, pageSize int) ([]model.Device, int64, error) {
	var devices []model.Device
	var total int64

	query := s.db.Model(&model.Device{})

	if uid != "" {
		query = query.Where("uid LIKE ?", "%"+uid+"%")
	}
	if deviceModel != "" {
		query = query.Where("device_model = ?", deviceModel)
	}
	if status != "" {
		query = query.Where("status = ?", status)
	}

	// 获取总数
	query.Count(&total)

	// 分页查询
	if page > 0 && pageSize > 0 {
		offset := (page - 1) * pageSize
		query = query.Offset(offset).Limit(pageSize)
	}

	err := query.Order("created_at DESC").Find(&devices).Error
	return devices, total, err
}

// BindLicense 绑定授权码
func (s *DeviceService) BindLicense(uid string, licenseCode string) error {
	var device model.Device
	if err := s.db.Where("uid = ?", uid).First(&device).Error; err != nil {
		return errors.New("设备不存在")
	}

	// 检查设备当前状态
	if device.LicenseCode != "" {
		return errors.New("设备已绑定授权码，请先解绑")
	}

	// 验证授权码
	license, err := s.licenseService.GetLicenseByCode(licenseCode)
	if err != nil {
		return err
	}

	if license.Status != "unused" {
		return errors.New("授权码已被使用")
	}

	// 根据授权类型处理
	switch license.LicenseType {
	case "time":
		if license.Duration <= 0 {
			return errors.New("无效的授权时长")
		}
		device.ExpireTime = time.Now().Add(time.Duration(license.Duration) * time.Minute)
		device.Duration = license.Duration
		device.MaxUses = 0
	case "count":
		if license.MaxUses <= 0 {
			return errors.New("无效的使用次数")
		}
		device.ExpireTime = time.Time{} // 清空过期时间
		device.Duration = 0
		device.MaxUses = license.MaxUses
		device.StartCount = 0 // 重置启动次数
	case "permanent":
		device.ExpireTime = time.Time{} // 清空过期时间
		device.Duration = 0
		device.MaxUses = 0
	default:
		return errors.New("无效的授权类型")
	}

	// 更新设备基本信息
	device.LicenseCode = licenseCode
	device.LicenseType = license.LicenseType
	device.Status = "active"
	device.LastActiveAt = time.Now()

	return s.db.Transaction(func(tx *gorm.DB) error {
		// 更新设备信息
		if err := tx.Save(&device).Error; err != nil {
			return err
		}

		// 更新授权码状态
		if err := tx.Model(&model.LicenseCode{}).Where("code = ?", licenseCode).
			Updates(map[string]interface{}{
				"status":  "used",
				"used_by": uid,
				"used_at": time.Now(),
			}).Error; err != nil {
			return err
		}

		// 记录设备日志
		log := model.DeviceLog{
			DeviceUID: uid,
			Action:    "bind_license",
			Message:   fmt.Sprintf("绑定%s授权码: %s", getLicenseTypeText(license.LicenseType), licenseCode),
			Status:    "success",
		}
		if err := tx.Create(&log).Error; err != nil {
			return err
		}

		return nil
	})
}

// 获取授权类型的中文描述
func getLicenseTypeText(licenseType string) string {
	switch licenseType {
	case "time":
		return "时间"
	case "count":
		return "次数"
	case "permanent":
		return "永久"
	default:
		return "未知"
	}
}

// UnbindLicense 解绑授权码
func (s *DeviceService) UnbindLicense(uid string) error {
	var device model.Device
	if err := s.db.Where("uid = ?", uid).First(&device).Error; err != nil {
		return errors.New("设备不存在")
	}

	if device.LicenseCode == "" {
		return errors.New("设备未绑定授权码")
	}

	oldLicenseCode := device.LicenseCode

	return s.db.Transaction(func(tx *gorm.DB) error {
		// 更新设备信息
		if err := tx.Model(&device).Updates(map[string]interface{}{
			"license_code": "",
			"license_type": "",
			"status":       "inactive",
			"expire_time":  nil,
			"max_uses":     0,
			"duration":     0,
		}).Error; err != nil {
			return err
		}

		// 更新授权码状态
		if err := tx.Model(&model.LicenseCode{}).Where("code = ?", oldLicenseCode).
			Updates(map[string]interface{}{
				"status":  "unused",
				"used_by": "",
				"used_at": nil,
			}).Error; err != nil {
			return err
		}

		// 记录设备日志
		log := model.DeviceLog{
			DeviceUID: uid,
			Action:    "unbind_license",
			Message:   fmt.Sprintf("解绑授权码: %s", oldLicenseCode),
			Status:    "success",
		}
		if err := tx.Create(&log).Error; err != nil {
			return err
		}

		return nil
	})
}

// GetDeviceLogs 获取设备日志
func (s *DeviceService) GetDeviceLogs(uid string, page, pageSize int) ([]model.DeviceLog, int64, error) {
	var logs []model.DeviceLog
	var total int64

	query := s.db.Model(&model.DeviceLog{}).Where("device_uid = ?", uid)

	// 获取总数
	query.Count(&total)

	// 分页查询
	if page > 0 && pageSize > 0 {
		offset := (page - 1) * pageSize
		query = query.Offset(offset).Limit(pageSize)
	}

	err := query.Order("created_at DESC").Find(&logs).Error
	return logs, total, err
}

func (s *DeviceService) GetDevice(uid string) (*model.Device, error) {
	var device model.Device
	if err := s.db.Where("uid = ?", uid).First(&device).Error; err != nil {
		return nil, errors.New("设备不存在")
	}
	return &device, nil
}
