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"
	"errors"
	"gogs.baozhida.cn/zoie/OAuth-core/pkg"
	"gogs.baozhida.cn/zoie/OAuth-core/pkg/utils"
	"gogs.baozhida.cn/zoie/OAuth-core/service"
	"gorm.io/gorm"
)

type Customer struct {
	service.Service
}

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

	err = e.Orm.
		Scopes(
			cDto.MakeCondition(c.GetNeedSearch()),
			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
			actions.UserPermission(data.TableName(), p),
		).
		Where("user_type = ?", model.UserTypeCustomer).
		Find(&userList).Limit(-1).Offset(-1).
		Count(count).Error

	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return global.GetFailedErr
	}

	*list = userList
	return nil
}

// Get 获取Customer对象
func (e *Customer) Get(d *dto.CustomerGetReq, p *actions.DataPermission, userModel *model.SysUser) error {
	var data model.SysUser
	//var post model.SysPost
	err := e.Orm.Model(&data).
		Scopes(actions.UserPermission(data.TableName(), p)).
		First(userModel, 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 创建Customer对象
func (e *Customer) Insert(c *dto.CustomerInsertReq) error {
	var err error
	tx := e.Orm.Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()

	var dept model.SysDept
	var deptCount int64
	err = e.Orm.Model(&dept).Where("id = ?", c.DeptId).Count(&deptCount).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return global.CreateFailedErr
	}
	if deptCount == 0 {
		err = errors.New("公司不存在！")
		e.Log.Errorf("db error: %s", err)
		return err
	}

	var data model.SysUser
	var i int64
	err = e.Orm.Model(&data).Where("username = ?", c.Username).Count(&i).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return global.CreateFailedErr
	}
	if i > 0 {
		err = errors.New("用户名已存在！")
		e.Log.Errorf("db error: %s", err)
		return err
	}

	var uuid string
	for {
		uuid = utils.GetUUID()
		var j int64
		err = e.Orm.Model(&data).Where("uuid = ?", uuid).Count(&j).Error
		if err != nil {
			continue
		}
		if j == 0 {
			break
		}
	}
	c.Generate(&data)
	data.Uuid = uuid
	err = tx.Create(&data).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return global.CreateFailedErr
	}
	c.Id = data.Id

	return nil
}

// Update 修改Customer对象
func (e *Customer) Update(c *dto.CustomerUpdateReq, p *actions.DataPermission) error {
	var err error
	tx := e.Orm.Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	var userModel model.SysUser
	err = e.Orm.
		Scopes(actions.UserPermission(userModel.TableName(), p)).
		First(&userModel, 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
	}

	c.Generate(&userModel)
	err = tx.Model(&userModel).Where("id = ?", &userModel.Id).
		Omit("password", "salt").Updates(&userModel).Error
	if err != nil {
		if errors.Is(err, model.ErrForbidUpdateSysRole) {
			return model.ErrForbidUpdateSysRole
		}
		e.Log.Errorf("db error: %s", err)
		return global.UpdateFailedErr
	}
	return nil
}

// UpdateStatus 更新用户状态
func (e *Customer) UpdateStatus(c *dto.UpdateCustomerStatusReq, p *actions.DataPermission) error {
	var userModel model.SysUser
	err := e.Orm.
		Scopes(actions.UserPermission(userModel.TableName(), p)).
		First(&userModel, 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
	}
	err = e.Orm.Table(userModel.TableName()).Where("id = ? ", c.Id).Updates(c).Error
	if err != nil {
		if errors.Is(err, model.ErrForbidUpdateSysRole) {
			return model.ErrForbidUpdateSysRole
		}
		e.Log.Errorf("db error: %s", err)
		return global.UpdateFailedErr
	}
	return nil
}

// ResetPwd 重置用户密码
func (e *Customer) ResetPwd(c *dto.ResetCustomerPwdReq, p *actions.DataPermission) error {
	var userModel model.SysUser
	err := e.Orm.
		Scopes(actions.UserPermission(userModel.TableName(), p)).
		First(&userModel, 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
	}
	c.Generate(&userModel)
	err = e.Orm.Omit("username", "nick_name", "phone", "role_id", "avatar", "sex").Save(&userModel).Error
	if err != nil {
		if errors.Is(err, model.ErrForbidUpdateSysRole) {
			return model.ErrForbidUpdateSysRole
		}
		e.Log.Errorf("db error: %s", err)
		return global.UpdateFailedErr
	}
	return nil
}

// Remove 删除Customer
func (e *Customer) Remove(c *dto.CustomerDeleteReq, p *actions.DataPermission) error {
	var err error
	tx := e.Orm.Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	var data model.SysUser
	db := e.Orm.Model(&data).
		Scopes(actions.UserPermission(data.TableName(), p)).
		Find(&data, c.GetId())
	if err = db.Error; err != nil {
		e.Log.Errorf("db error: %s", err)
		return err
	}
	if db.RowsAffected == 0 {
		return global.DeleteNotFoundOrNoPermissionErr
	}

	if err = tx.Delete(&data, c.GetId()).Error; err != nil {
		if errors.Is(err, model.ErrForbidDeleteSysRole) {
			return model.ErrForbidDeleteSysRole
		}
		e.Log.Errorf("db error: %s", err)
		return err
	}
	return nil
}

// UpdatePwd 修改Customer对象密码
func (e *Customer) UpdatePwd(id int, oldPassword, newPassword string) error {
	var err error

	if newPassword == "" {
		return nil
	}
	c := &model.SysUser{}

	err = e.Orm.Model(c).
		Select("id", "password", "salt").
		First(c, id).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return global.UpdateNotFoundOrNoPermissionErr
		}
		return errors.New("密码修改失败")
	}
	var ok bool
	ok, err = pkg.CompareHashAndPassword(c.Password, oldPassword)
	if err != nil {
		e.Log.Errorf("CompareHashAndPassword error, %s", err.Error())
		return errors.New("密码修改失败")
	}
	if !ok {
		err = errors.New("incorrect Password")
		e.Log.Warnf("user[%d] %s", id, err.Error())
		return err
	}
	c.Password = newPassword
	db := e.Orm.Model(c).Where("id = ?", id).
		Select("Password", "Salt").
		Updates(c)
	if err = db.Error; err != nil {
		if errors.Is(err, model.ErrForbidUpdateSysRole) {
			return model.ErrForbidUpdateSysRole
		}
		e.Log.Errorf("db error: %s", err)
		return errors.New("密码修改失败")
	}
	return nil
}

func (e *Customer) GetProfile(c *dto.CustomerById, user *model.SysUser) error {
	err := e.Orm.Preload("Dept").First(user, c.GetId()).Error
	if err != nil {
		return err
	}

	return nil
}
