package service

import (
	"fmt"
	"iot_manager_service/app/device/dao"
	"iot_manager_service/app/device/model"
	"iot_manager_service/app/system/service"
	"iot_manager_service/util/common"
	"iot_manager_service/util/logger"
	"sort"
	"time"
)

// 中间件管理服务
var LightStrategyService = new(lightStrategyService)

type lightStrategyService struct{}

func (s *lightStrategyService) Get(id int) (*model.LightStrategyDetail, *common.Errors) {
	// 创建查询实例
	strategy := &dao.LightStrategy{
		ID: id,
	}
	err := strategy.GetStrategy()
	if err != nil {
		return nil, common.FailResponse(err.Error(), nil)
	}

	lightStrategy := &model.LightStrategyDetail{
		LightStrategy: *strategy,
	}

	lightStrategy.TimeConditionList = TimeConditionService.GetByLightId(id)

	if len(lightStrategy.TimeConditionList) > 0 {
		lightStrategy.LightType = "时间"
	}
	lightStrategy.LightType = lightStrategy.LightType + "策略"
	return lightStrategy, nil
}

func (s *lightStrategyService) CreateOrUpdate(userId int64, tenantId string, req *model.LightStrategyDetail) *common.Errors {
	// 创建查询实例
	strategy := req
	logger.Logger.Errorf("CreateOrUpdate strategy = %+v \n", strategy)
	strategy.TenantId = tenantId
	strategy.UpdateUser = userId
	strategy.UpdateTime = time.Now()

	if len(strategy.LightConditionList) == 0 {
		for i := 0; i < len(strategy.LightConditionDetailList); i++ {
			var detail = strategy.LightConditionDetailList[i]
			condition := dao.LightCondition{
				ID:         detail.ID,
				Remark:     detail.Remark,
				LightId:    detail.LightId,
				Luminance:  detail.Luminance,
				ScopeStart: detail.ScopeStart,
				ScopeEnd:   detail.ScopeEnd,
			}
			strategy.LightConditionList = append(strategy.LightConditionList, condition)
		}
	}
	if len(strategy.TimeConditionList) == 0 {
		for i := 0; i < len(strategy.TimeConditionDetailList); i++ {
			var detail = strategy.TimeConditionDetailList[i]
			condition := dao.TimeCondition{
				ID:        detail.ID,
				Remark:    detail.Remark,
				LightId:   detail.LightId,
				Luminance: detail.Luminance,
				StartTime: detail.StartTime,
				EndTime:   detail.EndTime,
				Sunshine:  detail.Sunshine,
			}
			strategy.TimeConditionList = append(strategy.TimeConditionList, condition)
		}
	}

	if req.ID == 0 {
		strategy.CreateTime = time.Now()
		strategy.CreateUser = userId
		strategy.Status = 1
		if strategy.IsExistedBySN() {
			logger.Logger.Errorf("Create GetstrategyID err \n")
			return common.ParamsInvalidResponse("编码不能重复，请重新填写！", nil)
		}
	}

	//用于比较光照度重叠
	var overlapList []dao.LightCondition
	for _, lightCondition := range strategy.LightConditionList {
		if (lightCondition.ScopeStart != 0 && lightCondition.ScopeEnd == 0) || (lightCondition.
			ScopeStart == 0 && lightCondition.ScopeEnd != 0) {
			return common.ParamsInvalidResponse("光照度请填写完整", nil)
		} else if lightCondition.ScopeEnd > 0 && lightCondition.ScopeStart >= lightCondition.ScopeEnd {
			return common.ParamsInvalidResponse("光照度起始值不能大于结束值", nil)
		}
		overlapList = append(overlapList, lightCondition)

		if lightCondition.ID == 0 {
			lightCondition.CreateUser = userId
			lightCondition.CreateTime = time.Now()
		} else {
			lightCondition.UpdateUser = userId
			lightCondition.UpdateTime = time.Now()
		}
		lightCondition.LightId = req.ID

	}
	//光照条件查询是否区间重叠
	if len(overlapList) > 0 {
		sort.SliceIsSorted(overlapList, func(i, j int) bool {
			return overlapList[i].
				ScopeStart < overlapList[j].ScopeStart
		})
		tmp := -1
		for _, overLap := range overlapList {
			if tmp >= overLap.ScopeStart {
				return common.ParamsInvalidResponse("光照条件区间有重叠", nil)
			}
			tmp = overLap.ScopeEnd
		}
	}

	// 时间策略参数校验
	var timeList []dao.TimeCondition
	for _, timeCondition := range strategy.TimeConditionList {
		if timeCondition.Sunshine == 0 {
			timeCondition.Sunshine = 1
		}
		if timeCondition.Sunshine == 1 && (timeCondition.StartTime == "" && timeCondition.EndTime == "") {
			return common.FailResponse(model.TimeConditionNull, nil)
		}
		if (timeCondition.StartTime == "" && timeCondition.EndTime != "") || (timeCondition.
			StartTime != "" && timeCondition.EndTime == "") {
			return common.FailResponse(model.TimeConditionNull, nil)
		} else if timeCondition.EndTime != "" && timeCondition.StartTime >= timeCondition.EndTime {
			return common.FailResponse(model.TimeConditionInvalid, nil)
		}
		if timeCondition.ID == 0 {
			timeCondition.CreateUser = userId
			timeCondition.CreateTime = time.Now()
		} else {
			timeCondition.UpdateUser = userId
			timeCondition.UpdateTime = time.Now()
		}
		timeCondition.LightId = req.ID
		if timeCondition.ID == 0 {
			timeCondition.CreateUser = userId
			timeCondition.CreateTime = time.Now()
		}
		timeCondition.UpdateUser = userId
		timeCondition.UpdateTime = time.Now()

		timeList = append(timeList, timeCondition)
	}

	//存数据库
	if strategy.ID == 0 {
		if err := strategy.Create(); err != nil {
			logger.Logger.Errorf("Create err = %s \n", err.Error())
			return common.FailResponse(err.Error(), nil)
		}
	} else {
		if err := strategy.Update(); err != nil {
			logger.Logger.Errorf("Update err = %s \n", err.Error())
			return common.FailResponse(err.Error(), nil)
		}
	}

	//存策略条件
	_ = TimeConditionService.Save(timeList, strategy.ID)
	_ = LightConditionService.Save(strategy.LightConditionList, strategy.ID)

	//todo 调用设备云端的新增或修改

	//todo 自动续期
	//strategy.IsAutomaticRenewal

	service.OperationHisService.Save(userId, tenantId, common.OperationCreate, common.ModuleTypeDevice,
		common.DeviceTypeLightStrategy, common.GetDeviceObject(strategy.ID, strategy.LightName), common.OperationSuccess)
	return common.SuccessResponse(common.Succeeded, nil)
}

func (s *lightStrategyService) List(searchValue string, current, size int) ([]model.LightStrategyDetail, int64, *common.Errors) {
	strategy := dao.LightStrategy{}
	if searchValue != "" {
		strategy.LightSn = searchValue
	}

	offset := (current - 1) * size
	limit := size
	strategies, total, err := strategy.GetStrategies(offset, limit)
	if err != nil {
		return nil, 0, common.FailResponse(err.Error(), nil)
	}

	timeConditions, _ := TimeConditionService.GetAll()
	timeConditionsMap := make(map[int]dao.TimeCondition)
	for _, timeCondition := range timeConditions {
		timeConditionsMap[timeCondition.LightId] = timeCondition
	}

	year := time.Now().Year()
	var details []model.LightStrategyDetail
	for _, strategy := range strategies {
		if strategy.IsAllYear == model.IsYear {
			strategy.StartTime = fmt.Sprintf("%d-01-01", year)
			strategy.StartTime = fmt.Sprintf("%d-12-31", year)
		}
		detail := model.LightStrategyDetail{LightStrategy: strategy}
		if timeCondition, isExist := timeConditionsMap[strategy.ID]; isExist {
			//开启日出日落
			if timeCondition.Sunshine == 2 {
				timeCondition.StartTime = "日落"
				timeCondition.EndTime = "日出"
			}
			str := []string{}
			str = append(str, fmt.Sprintf("开灯时段：%s ~ %s , 灯光亮度：%d%%", timeCondition.StartTime,
				timeCondition.EndTime, timeCondition.Luminance))
			detail.CombinationStr = str
		}
		lightStrategy := &model.LightStrategyDetail{
			LightStrategy: strategy,
		}
		lightStrategy.TimeConditionList = TimeConditionService.GetByLightId(strategy.ID)
		if len(lightStrategy.TimeConditionList) > 0 {
			lightStrategy.LightType = "时间"
		}
		detail.LightType = lightStrategy.LightType + "策略"

		details = append(details, detail)
	}
	return details, total, nil
}

func (s *lightStrategyService) Remove(userId int64, tenantId string, id int) *common.Errors {
	// 创建查询实例
	strategy := &dao.LightStrategy{
		ID:         id,
		IsDeleted:  1,
		UpdateUser: userId,
		UpdateTime: time.Now(),
	}
	err := strategy.Delete()
	if err != nil {
		return common.FailResponse(err.Error(), nil)
	}
	service.OperationHisService.Save(userId, tenantId, common.OperationRemove, common.ModuleTypeDevice,
		common.DeviceTypeLightStrategy, common.GetDeviceObject(strategy.ID, strategy.LightName), common.OperationSuccess)
	return nil
}

func (s *lightStrategyService) GetOne(id int) (*dao.LightStrategy, *common.Errors) {
	strategy := &dao.LightStrategy{
		ID: id,
	}
	err := strategy.GetStrategy()
	if err != nil {
		return nil, nil
	}
	return strategy, nil
}
