package domain

import (
	"fmt"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/constant"
	"time"
)

const (
	DefaultAdminUserCode = "ADMIN01"
)

// 用户类型
const (
	UserTypeEmployee       = 1
	UserTypeCooperation    = 2
	UserTypeVisitor        = 4 // 游客
	UserTypeOperationAdmin = 8 // 运营管理员
	UserTypeCompanyAdmin   = 1024
)

// 用户状态
const (
	UserStatusEnable  UserStatus = 1
	UserStatusDisable UserStatus = 2
	UserStatusDestroy UserStatus = 3
)

const (
	UserUpdateEvent = "user_update"
	UserDeleteEvent = "user_delete"
	UserCreateEvent = "user_create"
	UserEnableEvent = "user_enable" //禁用启用事件
	UserSyncEvent   = "user_sync"   // 用户同步
)

// 用户
type User struct {
	// 用户Id 用户唯一标识
	UserId int64 `json:"userId,omitempty"`
	// 企业id
	CompanyId int64 `json:"companyId,omitempty"`
	// 用户基础数据id
	UserBaseId int64 `json:"userBaseId,omitempty"`
	// 用户类型  1:企业内部用户(内部添加) 2:共创用户   1024:企业注册用户(注册添加)
	UserType int `json:"userType,omitempty"`
	// 用户编号 企业内标识
	UserCode string `json:"userCode,omitempty"`
	// 组织机构
	OrganizationId int64 `json:"organizationId,omitempty"`
	// 所属部门
	DepartmentId int64 `json:"departmentId,omitempty"`
	// 用户关联的组织
	UserOrg []*Org `json:"userOrg,omitempty"`
	// 用户关联的角色
	UserRole []*Role `json:"userRole,omitempty"`
	// 收藏的菜单(工作台)(菜单编码列表)
	FavoriteMenus []string `json:"favoriteMenus,omitempty"`
	// 共创信息 (共创用户有效)
	CooperationInfo *CooperationInfo `json:"cooperationInfo,omitempty"`
	// 状态(1:启用  2:禁用  3:注销)
	EnableStatus int `json:"enableStatus,omitempty"`
	// 扩展数据
	Ext *Ext `json:"ext,omitempty"`
	// 创建时间
	CreatedAt time.Time `json:"createdAt,omitempty"`
	// 更新时间
	UpdatedAt time.Time `json:"updatedAt,omitempty"`

	// 用户信息 (冗余,数据存在userBase里面)
	UserInfo *UserInfo `json:"userInfo,omitempty"`
	// 企业id
	Company *Company `json:"company,omitempty"`
	// 组织机构
	Organization *Org `json:"org,omitempty"`
	// 部门
	Department *Department `json:"department,omitempty"`
	// 收藏
	Favorite *Favorite `json:"favorite"`
}

type UserRepository interface {
	Save(user *User) (*User, error)
	Remove(user *User) (*User, error)
	FindOne(queryOptions map[string]interface{}) (*User, error)
	Find(queryOptions map[string]interface{}) (int64, []*User, error)
}

func (user *User) Identify() interface{} {
	if user.UserId == 0 {
		return nil
	}
	return user.UserId
}

func (user *User) Update(data map[string]interface{}) error {
	//if companyId, ok := data["companyId"]; ok {
	//	user.CompanyId = companyId.(int64)
	//}
	if userBaseId, ok := data["userBaseId"]; ok {
		user.UserBaseId = userBaseId.(int64)
	}
	//if userType, ok := data["userType"]; ok {
	//	user.UserType = userType.(int)
	//}
	//if userCode, ok := data["userCode"]; ok {
	//	user.UserCode = userCode.(string)
	//}
	if organizationId, ok := data["organizationId"]; ok {
		user.OrganizationId = organizationId.(int64)
	}
	if departmentId, ok := data["departmentId"]; ok {
		user.DepartmentId = departmentId.(int64)
	}
	//if userName, ok := data["userName"]; ok {
	//	user.UserInfo.UserName = userName.(string)
	//}
	//if phone, ok := data["phone"]; ok {
	//	user.UserInfo.Phone = phone.(string)
	//}
	//if avatar, ok := data["avatar"]; ok {
	//	user.UserInfo.Avatar = avatar.(string)
	//}
	//if email, ok := data["email"]; ok {
	//	user.UserInfo.Email = email.(string)
	//}
	if userOrg, ok := data["userOrg"]; ok {
		user.UserOrg = userOrg.([]*Org)
	}
	if userRole, ok := data["userRole"]; ok {
		user.UserRole = userRole.([]*Role)
	}
	if favoriteMenus, ok := data["favoriteMenus"]; ok {
		user.FavoriteMenus = favoriteMenus.([]string)
	}
	if cooperationCompany, ok := data["cooperationCompany"]; ok {
		user.CooperationInfo.CooperationCompany = cooperationCompany.(string)
	}
	if cooperationDeadline, ok := data["cooperationDeadline"]; ok {
		user.CooperationInfo.CooperationDeadline = cooperationDeadline.(time.Time)
	}
	if enableStatus, ok := data["enableStatus"]; ok {
		user.EnableStatus = enableStatus.(int)
	}
	if userName, ok := data["userName"]; ok {
		user.Ext.UserName = userName.(string)
	}
	if orgName, ok := data["orgName"]; ok {
		user.Ext.OrgName = orgName.(string)
	}
	if phone, ok := data["phone"]; ok {
		user.Ext.Phone = phone.(string)
	}
	if depName, ok := data["depName"]; ok {
		user.Ext.DepName = depName.(string)
	}
	if parentDepName, ok := data["parentDepName"]; ok {
		user.Ext.ParentDepName = parentDepName.(string)
	}
	if updatedAt, ok := data["updatedAt"]; ok {
		user.UpdatedAt = updatedAt.(time.Time)
	}
	return nil
}

type UserStatus int

/*****   1.基础模块函数  *****/
// DestroyAccount  注销账号
//
// accountAfter 变更后的账号
func (user *User) DestroyAccount(accountAfter string) error {
	if err := user.SetEnableStatus(int(UserStatusDestroy)); err != nil {
		return err
	}
	user.Ext.Phone = accountAfter
	return nil
}

func (user *User) SetEnableStatus(enableStatus int) error {
	userStatus := UserStatus(user.EnableStatus)
	if userStatus == UserStatusDestroy {
		return fmt.Errorf("账号已注销")
	}
	if user.EnableStatus == enableStatus {
		return nil //fmt.Errorf("重复设置状态")
	}
	if !(enableStatus == int(UserStatusEnable) || enableStatus == int(UserStatusDisable) || enableStatus == int(UserStatusDestroy)) {
		return fmt.Errorf("非法启用状态")
	}
	user.EnableStatus = enableStatus
	return nil
}

func (user *User) UserOrgIds() []int64 {
	var orgIds = make([]int64, len(user.UserOrg))
	for i := range user.UserOrg {
		orgIds[i] = user.UserOrg[i].OrgId
	}
	return orgIds
}

func (user *User) UserRoleIds() []int64 {
	var roleIds = make([]int64, len(user.UserRole))
	for i := range user.UserRole {
		roleIds[i] = user.UserRole[i].RoleId
	}
	return roleIds
}

// ExistsUserRole  用户是否已经拥有角色
//
// roleId 角色ID
func (user *User) ExistsUserRole(roleId int64) bool {
	for i := range user.UserRole {
		if user.UserRole[i].RoleId == roleId {
			return true
		}
	}
	return false
}

// RemoveUserRole  移除用户拥有的角色
//
// roleId 角色ID
func (user *User) RemoveUserRole(roleId int64) bool {
	var res bool = false
	if user.ExistsUserRole(roleId) {

		var roles = make([]*Role, 0)
		for i := range user.UserRole {
			if user.UserRole[i].RoleId != roleId {
				roles = append(roles, user.UserRole[i])
			} else {
				res = true
			}
		}
		user.UserRole = roles
		return res
	}
	return res
}

// AddFavoriteMenu  菜单收藏
//
// codes 菜单列表
func (user *User) AddFavoriteMenu(codes ...string) error {
	for i := 0; i < len(codes); i++ {
		var menuExisted = false
		for j := 0; j < len(user.FavoriteMenus); j++ {
			if user.FavoriteMenus[j] == codes[i] {
				menuExisted = true
			}
		}
		if !menuExisted {
			user.FavoriteMenus = append(user.FavoriteMenus, codes[i])
		}
	}
	return nil
}

// AddFavoriteMenu  菜单收藏移除
//
// codes 菜单列表
func (user *User) RemoveFavoriteMenu(codes ...string) error {
	for i := 0; i < len(codes); i++ {
		var menuExisted = false
		var newMenus = make([]string, 0)
		for j := 0; j < len(user.FavoriteMenus); j++ {
			if user.FavoriteMenus[j] == codes[i] {
				menuExisted = true
			} else {
				newMenus = append(newMenus, user.FavoriteMenus[j])
			}
		}
		if menuExisted {
			user.FavoriteMenus = newMenus
		}
	}
	return nil
}

/*****   2.缓存模块  *****/

func (user *User) CacheKeyFunc() string {
	if constant.DISABLE_REPOSITORY_CACHE {
		return ""
	}
	if user.UserId == 0 {
		return ""
	}
	return fmt.Sprintf("%v:cache:users:id:%v", constant.CACHE_PREFIX, user.UserId)
}

/*****   3.实现接口 AuthedData  *****/
func (user *User) BelongOrg() int64 {
	return user.OrganizationId
}

/*****   4.批量添加组织项  *****/

type BatchAddUserItem struct {
	// 企业id
	CompanyId int64 `json:"companyId,omitempty"`
	// 用户类型  1:企业内部用户(内部添加) 2:共创用户   1024:企业注册用户(注册添加)
	UserType int `json:"userType,omitempty"`
	// 用户姓名
	UserName string `json:"userName"`
	// 手机号码
	Phone string `json:"phone"`
	// 邮箱
	Email string `json:"email"`
	// 用户编号 企业内标识
	UserCode string `json:"userCode"`
	// 组织编码
	Org string `json:"org"`
	// 部门编码
	Department string `json:"department"`
	// 状态(1:启用  2:禁用  3:注销)
	EnableStatus string `json:"enableStatus,omitempty"`
	// 共创公司 cooperationCompany
	CooperationCompany string `json:"cooperationCompany"`
	// 共创到期时间 (yyyy-MM-dd) cooperationDeadline
	CooperationDeadline string `json:"cooperationDeadline"`
	// 员工类型  1:固定 2:派遣 3.临时
	EmployeeType string `json:"employeeType,omitempty"`
	// IC卡号
	IcCardNumber string `json:"icCardNumber,omitempty"`

	// 失败理由
	FailReason string `json:"failReason"`
}

func (item *BatchAddUserItem) Status() int {
	if item.EnableStatus == "启用" {
		return 1
	}
	if item.EnableStatus == "禁用" {
		return 2
	}
	return 1
}

func (item *BatchAddUserItem) GetEmployeeType() int {
	if item.EmployeeType == "固定" {
		return 1
	}
	if item.EmployeeType == "派遣" {
		return 2
	}
	if item.EmployeeType == "临时" {
		return 3
	}
	return 1
}