package service

import (
	"cold-delivery/app/admin/model"
	"cold-delivery/app/admin/service/dto"
	"cold-delivery/common/actions"
	cDto "cold-delivery/common/dto"
	"cold-delivery/common/global"
	model2 "cold-delivery/common/model"
	"errors"
	"fmt"
	"gogs.baozhida.cn/zoie/OAuth-core/service"
	"gorm.io/gorm"
	"time"
)

type IceRaft struct {
	service.Service
}

// GetPage 获取IceRaft列表
func (e *IceRaft) GetPage(c *dto.IceRaftGetPageReq, list *[]model.IceRaft, count *int64, p *actions.DataPermission) error {
	var err error
	var data model.IceRaft

	if c.PageSize == 9999 {
		err = e.Orm.Model(&data).
			Scopes(
				actions.Permission(data.TableName(), p),
			).
			Find(list).Limit(-1).Offset(-1).
			Count(count).Error
	} else {
		err = e.Orm.Model(&data).
			Scopes(
				cDto.MakeCondition(c.GetNeedSearch()),
				cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
				actions.Permission(data.TableName(), p),
			).
			Find(list).Limit(-1).Offset(-1).
			Count(count).Error
	}
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return global.GetFailedErr
	}
	return nil
}
func IceRaftNameRecordStatusScopes(status string) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if len(status) == 0 {
			return db
		}
		if status == "0" {
			return db.Where("ice_raft_record.status is null")

		}
		return db.Where("ice_raft_record.status = ?", status)
	}
}
func IceRaftNameRecordIceLockerIdScopes(iceLockerId int) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if iceLockerId == 0 {
			return db
		}
		return db.Where("ice_raft_record.ice_locker_id = ? and ice_raft_record.cooler_box_id = 0", iceLockerId)
	}
}

func IceRaftNameRecordCoolerBoxIdScopes(coolerBoxId int) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if coolerBoxId == 0 {
			return db
		}
		return db.Where("ice_raft_record.cooler_box_id = ?", coolerBoxId)
	}
}

func (e *IceRaft) GetRecordPage(c *dto.IceRaftGetNewestRecordPageReq, list *[]model.IceRaft, count *int64, p *actions.DataPermission) error {
	var err error
	var data model.IceRaft

	if c.PageSize == 9999 {
		err = e.Orm.Model(&data).
			Scopes(
				actions.Permission(data.TableName(), p),
			).
			Where("ice_raft.status = '2'").
			Joins("left join ice_raft_record on ice_raft.ice_raft_record_id = ice_raft_record.id").
			Preload("IceRaftRecord.IceLocker").
			Preload("IceRaftRecord.CoolerBox").
			Order("FIELD(ice_raft_record.status,'2','','1','3','4')").
			Find(list).Limit(-1).Offset(-1).
			Count(count).Error
	} else {
		err = e.Orm.Model(&data).
			Scopes(
				cDto.MakeCondition(c.GetNeedSearch()),
				cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
				actions.Permission(data.TableName(), p),
				IceRaftNameRecordStatusScopes(c.Status),
				IceRaftNameRecordIceLockerIdScopes(c.IceLockerId),
				IceRaftNameRecordCoolerBoxIdScopes(c.CoolerBoxId),
			).
			Where("ice_raft.status = '2'").
			Joins("left join ice_raft_record on ice_raft.ice_raft_record_id = ice_raft_record.id").
			Preload("IceRaftRecord.IceLocker").
			Preload("IceRaftRecord.CoolerBox").
			Order("FIELD(ice_raft_record.status,'2','','1','3','4')").
			Find(list).Limit(-1).Offset(-1).
			Count(count).Error
	}
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return global.GetFailedErr
	}
	return nil
}

// Get 获取IceRaft对象
func (e *IceRaft) Get(d *dto.IceRaftGetReq, iceRaftModel *model.IceRaft, p *actions.DataPermission) error {
	err := e.Orm.
		Scopes(actions.Permission(iceRaftModel.TableName(), p)).
		First(iceRaftModel, d.GetId()).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return global.GetNotFoundOrNoPermissionErr
		}
		return global.GetFailedErr
	}

	return nil
}

// Insert 创建IceRaft对象
func (e *IceRaft) Insert(c *dto.IceRaftInsertReq) error {
	var err error
	var data model.IceRaft

	tx := e.Orm.Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()

	for _, code := range c.CodeList {
		var k int64
		err = tx.Model(&data).Where("code = ? and dept_id = ?", code, c.DeptId).Count(&k).Error
		if err != nil {
			e.Log.Errorf("db error: %s", err)
			return global.CreateFailedErr
		}
		// 冰排编号已存在
		if k > 0 {
			continue
		}

		// 添加冰排
		data.Id = 0
		c.Generate(&data, code)
		err = tx.Create(&data).Error
		if err != nil {
			e.Log.Errorf("db error: %s", err)
			return global.CreateFailedErr
		}
	}

	return nil

}

// Update 修改IceRaft对象
func (e *IceRaft) Update(c *dto.IceRaftUpdateReq, p *actions.DataPermission) error {
	var err error

	tx := e.Orm.Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()

	var iceRaftModel = model.IceRaft{}
	// 查询冰排是否存在
	err = e.Orm.Scopes(actions.Permission(iceRaftModel.TableName(), p)).
		First(&iceRaftModel, c.GetId()).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return global.UpdateNotFoundOrNoPermissionErr
		}
		return global.UpdateFailedErr
	}

	if iceRaftModel.Code != c.Code {
		var k int64
		var data = model.IceRaft{}
		err = tx.Model(&data).Where("code = ? and dept_id = ?", c.Code, iceRaftModel.DeptId).Count(&k).Error
		if err != nil {
			e.Log.Errorf("db error: %s", err)
			return global.CreateFailedErr
		}
		if k > 0 {
			err = errors.New("冰排编号已存在！")
			e.Log.Errorf("db error: %s", err)
			return err
		}
	}

	c.Generate(&iceRaftModel)
	err = tx.Save(&iceRaftModel).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return global.UpdateFailedErr
	}

	c.Id = iceRaftModel.Id
	return nil
}

// Remove 删除IceRaft
func (e *IceRaft) Remove(c *dto.IceRaftDeleteReq, p *actions.DataPermission) error {
	var err error

	tx := e.Orm.Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()

	var iceRaftModel model.IceRaft

	// 查询冰排是否存在
	err = e.Orm.Scopes(actions.Permission(iceRaftModel.TableName(), p)).
		First(&iceRaftModel, c.GetId()).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return global.DeleteNotFoundOrNoPermissionErr
		}
		return global.DeleteFailedErr
	}

	db := tx.Delete(&iceRaftModel)

	if err = db.Error; err != nil {
		e.Log.Errorf("db error: %s", err)
		return global.DeleteFailedErr
	}
	if db.RowsAffected == 0 {
		return global.DeleteNotFoundOrNoPermissionErr
	}

	return nil
}
func (e *IceRaft) InStorage(c *dto.IceRaftInStorageReq, p *actions.DataPermission) error {
	var err error

	tx := e.Orm.Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	// 查询冷冻柜信息
	var iceLockerModel model.IceLocker
	err = e.Orm.Scopes(actions.Permission(iceLockerModel.TableName(), p)).
		First(&iceLockerModel, c.IceLockerId).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return errors.New("获取冷冻柜信息失败")
	}
	if iceLockerModel.Status != model.IceLockerStatusNormal {
		err = errors.New("冷冻柜状态异常")
		return err
	}

	for _, code := range c.Code {
		// 查询冰排是否存在
		var iceRaftModel model.IceRaft
		err = e.Orm.Scopes(actions.Permission(iceRaftModel.TableName(), p)).
			Where("code = ?", code).
			Preload("IceRaftRecord").
			First(&iceRaftModel).Error
		if err != nil {
			// 冰排编号不存在，添加
			if errors.Is(err, gorm.ErrRecordNotFound) {
				iceRaftModel.Code = code
				iceRaftModel.Status = model.IceRaftStatusNormal
				iceRaftModel.DeptId = p.DeptId
				iceRaftModel.CreateBy = p.UserId
				err = tx.Create(&iceRaftModel).Error
				if err != nil {
					e.Log.Errorf("db error: %s", err)
					return errors.New(fmt.Sprintf("添加冰排【%s】信息失败", code))
				}
			} else {
				e.Log.Errorf("db error: %s", err)
				return errors.New("获取冰排信息失败")
			}

		}

		if iceRaftModel.Status != model.IceRaftStatusNormal {
			err = errors.New(fmt.Sprintf("冰排【%s】状态异常", code))
			return err
		}

		if iceRaftModel.IceRaftRecord.Status == model.IceRaftRecordStatusFreezing || iceRaftModel.IceRaftRecord.Status == model.IceRaftRecordStatusWaitUse {
			err = errors.New(fmt.Sprintf("冰排【%s】状态为%s，入库失败！", code, model.GetIceRaftRecordStatus(iceRaftModel.IceRaftRecord.Status)))
			return err
		}

		// 更新冰排状态 使用中 -> 已完成
		err = tx.Model(&model.IceRaftRecord{}).
			Where("ice_raft_id = ? and status = ?", iceRaftModel.Id, model.IceRaftRecordStatusUsing).
			Updates(map[string]interface{}{
				"status": model.IceRaftRecordStatusFinish,
			}).Error

		// 添加冰排记录
		var iceRaftRecordModel = model.IceRaftRecord{
			IceLockerId:   iceLockerModel.Id,
			IceRaftId:     iceRaftModel.Id,
			Status:        model.IceRaftRecordStatusFreezing,
			InStorageTime: model2.Time(time.Now()),
			FreezeClaim:   c.FreezeClaim,
			DeptBy: model2.DeptBy{
				DeptId: p.DeptId,
			},
		}
		err = tx.Create(&iceRaftRecordModel).Error
		if err != nil {
			e.Log.Errorf("db error: %s", err)
			return errors.New("添加冰排记录失败")
		}

		// 更新冰排使用记录
		err = tx.Model(&iceRaftModel).
			Where("id = ?", iceRaftModel.Id).
			Updates(map[string]interface{}{
				"ice_raft_record_id": iceRaftRecordModel.Id,
			}).Error
		if err != nil {
			e.Log.Errorf("db error: %s", err)
			return errors.New("关联冰排记录失败")
		}

	}

	return nil
}
func (e *IceRaft) OutStorage(c *dto.IceRaftOutStorageReq, p *actions.DataPermission) error {
	var err error

	tx := e.Orm.Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	// 查询保温箱信息
	var coolerBoxModel model.CoolerBox
	err = e.Orm.Scopes(actions.Permission(coolerBoxModel.TableName(), p)).
		First(&coolerBoxModel, c.CoolerBoxId).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return errors.New("获取保温箱信息失败")
	}
	if coolerBoxModel.Status != model.CoolerBoxStatusNormal {
		err = errors.New("保温箱状态异常")
		return err
	}

	for _, code := range c.Code {
		// 查询冰排是否存在
		var iceRaftModel model.IceRaft
		err = e.Orm.Scopes(actions.Permission(iceRaftModel.TableName(), p)).
			Where("code = ?", code).
			Preload("IceRaftRecord").
			First(&iceRaftModel).Error
		if err != nil {
			e.Log.Errorf("db error: %s", err)
			return errors.New("获取冰排信息失败")
		}

		if iceRaftModel.Status != model.IceRaftStatusNormal {
			err = errors.New(fmt.Sprintf("冰排【%s】状态异常", code))
			return err
		}

		// 获取冰排记录
		var iceRaftRecordModel model.IceRaftRecord
		err = e.Orm.Scopes(actions.Permission(iceRaftRecordModel.TableName(), p)).
			Where("ice_raft_id = ?", iceRaftModel.Id).
			First(&iceRaftRecordModel, iceRaftModel.IceRaftRecordId).Error
		if err != nil {
			e.Log.Errorf("db error: %s", err)
			return errors.New("获取冰排记录失败")
		}

		if len(iceRaftRecordModel.OutStorageTime.String()) > 0 {
			err = errors.New(fmt.Sprintf("冰排【%s】已出库，禁止出库！", code))
			return err
		}

		inTime := iceRaftRecordModel.InStorageTime.Local()
		if inTime.Add(time.Hour * time.Duration(iceRaftRecordModel.FreezeClaim)).After(time.Now()) {
			err = errors.New(fmt.Sprintf("冰排【%s】未达到冷冻时长，禁止出库", code))
			return err
		}

		iceRaftRecordModel.Status = model.IceRaftRecordStatusUsing
		iceRaftRecordModel.CoolerBoxId = coolerBoxModel.Id
		iceRaftRecordModel.OutStorageTime = model2.Time(time.Now())
		err = tx.Save(&iceRaftRecordModel).Error
		if err != nil {
			e.Log.Errorf("db error: %s", err)
			return errors.New("保存冰排记录失败")
		}

	}

	return nil
}

// 查询保温箱关联的冰排
func (e *IceRaft) GetPageByCoolerBoxId(coolerBoxId int, list *[]string, p *actions.DataPermission) error {
	var data model.IceRaft
	err := e.Orm.Model(&data).
		Select("code").
		Scopes(
			actions.Permission(data.TableName(), p),
			IceRaftNameRecordStatusScopes(model.IceRaftRecordStatusUsing),
			IceRaftNameRecordCoolerBoxIdScopes(coolerBoxId),
		).
		Joins("left join ice_raft_record on ice_raft.ice_raft_record_id = ice_raft_record.id").
		Find(list).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return global.GetFailedErr
	}
	return nil
}

type IceRaftRecord struct {
	service.Service
}

// GetPage 获取IceRaft列表
func (e *IceRaftRecord) GetPage(c *dto.IceRaftRecordGetPageReq, list *[]model.IceRaftRecord, count *int64, p *actions.DataPermission) error {
	var err error
	var data model.IceRaftRecord

	if c.PageSize == 9999 {
		err = e.Orm.Model(&data).
			Scopes(
				actions.Permission(data.TableName(), p),
			).
			Preload("IceLocker").
			Preload("CoolerBox").
			Find(list).Limit(-1).Offset(-1).
			Count(count).Error
	} else {
		err = e.Orm.Model(&data).
			Scopes(
				cDto.MakeCondition(c.GetNeedSearch()),
				cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
				actions.Permission(data.TableName(), p),
			).
			Preload("IceLocker").
			Preload("CoolerBox").
			Find(list).Limit(-1).Offset(-1).
			Count(count).Error
	}
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return global.GetFailedErr
	}
	return nil
}

// Update 修改IceRaft对象
func (e *IceRaftRecord) Update(c *dto.IceRaftRecordUpdateReq, p *actions.DataPermission) error {
	var err error

	tx := e.Orm.Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()

	var iceRaftRecordModel = model.IceRaftRecord{}
	// 查询冰排是否存在
	err = e.Orm.Scopes(actions.Permission(iceRaftRecordModel.TableName(), p)).
		First(&iceRaftRecordModel, c.GetId()).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return global.UpdateNotFoundOrNoPermissionErr
		}
		return global.UpdateFailedErr
	}

	iceRaftRecordModel.IceLockerId = c.IceLockerId
	iceRaftRecordModel.FreezeClaim = c.FreezeClaim
	if len(iceRaftRecordModel.OutStorageTime.String()) > 0 {
		iceRaftRecordModel.CoolerBoxId = c.CoolerBoxId
	}
	err = tx.Save(&iceRaftRecordModel).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return global.UpdateFailedErr
	}

	c.Id = iceRaftRecordModel.Id
	return nil
}

// Remove 删除IceRaft
func (e *IceRaftRecord) Remove(c *dto.IceRaftRecordDeleteReq, p *actions.DataPermission) error {
	var err error

	tx := e.Orm.Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()

	var iceRaftRecordModel model.IceRaftRecord

	// 查询冰排是否存在
	err = e.Orm.Scopes(actions.Permission(iceRaftRecordModel.TableName(), p)).
		First(&iceRaftRecordModel, c.GetId()).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return global.DeleteNotFoundOrNoPermissionErr
		}
		return global.DeleteFailedErr
	}

	db := tx.Delete(&iceRaftRecordModel)

	if err = db.Error; err != nil {
		e.Log.Errorf("db error: %s", err)
		return global.DeleteFailedErr
	}
	if db.RowsAffected == 0 {
		return global.DeleteNotFoundOrNoPermissionErr
	}
	// 更改冰排关联状态

	var iceRaftModel model.IceRaft
	var secondIceRaftRecordModel model.IceRaftRecord
	err = e.Orm.Scopes(actions.Permission(iceRaftModel.TableName(), p)).
		First(&iceRaftModel, iceRaftRecordModel.IceRaftId).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return global.DeleteFailedErr
	}
	err = e.Orm.Scopes(actions.Permission(secondIceRaftRecordModel.TableName(), p)).
		Where("ice_raft_id = ? and id != ?", iceRaftRecordModel.IceRaftId, iceRaftRecordModel.Id).
		First(&secondIceRaftRecordModel).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			iceRaftModel.IceRaftRecordId = 0
		}
	}
	iceRaftModel.IceRaftRecordId = secondIceRaftRecordModel.Id
	err = tx.Save(&iceRaftModel).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return global.UpdateFailedErr
	}
	return nil
}
