package domain

import "time"

//Users.Status用户是否可用状态:【1:正常】【 2:禁用】
const (
	userStatusUsable   int8 = 1
	userStatusUnusable int8 = 2
)

//Users.ChargeStatus用户是否是主管 :【1:是主管】【 2:不是主管】
const (
	UserIsCompanyCharge    int8 = 1
	UserIsNotCompanyCharge int8 = 2
)

//Users.AdminType 用户类型 1普通用户 2主管理员
const (
	UserIsNotAdmin int8 = 1
	UserIsAdmin    int8 = 2
)

//Users.IsSenior  用户是否是公司高管【1:是】【2:否】
const (
	UserIsSeniorYes int8 = 1
	UserIsSeniorNo  int8 = 2
)

//Users 企业平台的用户
type Users struct {
	Id             int64                 //用户id
	CompanyId      int64                 //公司id
	OpenId         int64                 //统一用户中心
	Name           string                //用户名称
	Sex            int8                  //性别:【0:未知】【1:男】【2:女】
	JobNum         string                //工号
	Phone          string                //手机号,同账号
	PrivatePhone   string                //私人手机号
	Email          string                //邮件
	ExtensionNum   string                //分机号
	EntryTime      time.Time             //入职时间
	Workspace      string                //工作地
	Status         int8                  //状态:【1:正常】【 2:禁用】
	Avatar         string                ///头像
	Remarks        string                //备注
	ChargeStatus   int8                  //是否为当前公司主管 【1:是】【2:否】
	CreateAt       time.Time             //
	UpdateAt       time.Time             //
	Permission     []AdminPermissionBase //权限
	AccessPartners []Partner             //
	AdminType      int8                  //是否是公司负责人,即超级管理员 1普通用户 2主管理员
	IsSenior       int8                  //是否是公司高管【1:是】【2:否】;用于确定是否可以拥有“可查看的合伙人”
}

//IsUsable 用户是否可用
func (u Users) IsUsable() bool {
	return u.Status == userStatusUsable
}

//IsSuperAdmin 用户是否是负责人
func (u Users) IsSuperAdmin() bool {
	return u.AdminType == UserIsAdmin
}

func (u Users) InCompany(companyid int64) bool {
	return u.CompanyId == companyid
}

func (u Users) HasPermissionByCode(code string) bool {
	if u.IsSuperAdmin() {
		return true
	}
	for _, v := range u.Permission {
		if v.Code == code {
			return true
		}
	}
	return false
}

func (u *Users) SetIsSenior(senior int8) {
	switch senior {
	case UserIsSeniorYes:
		u.IsSenior = senior
	case UserIsSeniorNo:
		u.IsSenior = senior
		u.AccessPartners = make([]Partner, 0)
	default:
	}
}

func (u *Users) Update(m map[string]interface{}) error {
	if v, ok := m["CompanyId"]; ok {
		u.CompanyId = v.(int64)
	}
	if v, ok := m["OpenId"]; ok {
		u.OpenId = v.(int64)
	}
	if v, ok := m["Name"]; ok {
		u.Name = v.(string)
	}
	if v, ok := m["Sex"]; ok {
		u.Sex = v.(int8)
	}
	if v, ok := m["JobNum"]; ok {
		u.JobNum = v.(string)
	}
	if v, ok := m["Phone"]; ok {
		u.Phone = v.(string)
	}
	if v, ok := m["PrivatePhone"]; ok {
		u.PrivatePhone = v.(string)
	}
	if v, ok := m["Email"]; ok {
		u.Email = v.(string)
	}
	if v, ok := m["ExtensionNum"]; ok {
		u.ExtensionNum = v.(string)
	}
	if v, ok := m["EntryTime"]; ok {
		u.EntryTime = v.(time.Time)
	}
	if v, ok := m["Workspace"]; ok {
		u.Workspace = v.(string)
	}
	if v, ok := m["Status"]; ok {
		u.Status = v.(int8)
	}
	if v, ok := m["Avatar"]; ok {
		u.Avatar = v.(string)
	}
	if v, ok := m["Remarks"]; ok {
		u.Remarks = v.(string)
	}
	if v, ok := m["ChargeStatus"]; ok {
		u.ChargeStatus = v.(int8)
	}
	if v, ok := m["Permission"]; ok {
		u.Permission = v.([]AdminPermissionBase)
	}
	if v, ok := m["AccessPartners"]; ok {
		u.AccessPartners = v.([]Partner)
	}
	if v, ok := m["AdminType"]; ok {
		u.AdminType = v.(int8)
	}
	if v, ok := m["IsSenior"]; ok {
		senior := v.(int8)
		u.SetIsSenior(senior)
	}
	return nil
}

type UsersFindOneQuery struct {
	Id        int64
	Phone     string
	CompanyId int64
	OpenId    int64
}

type UsersFindQuery struct {
	AdminType     int8
	ChargeStatus  int8
	CompanyId     int64
	Ids           []int64
	Offset        int
	Limit         int
	UserNameMatch string
}
type UsersRepository interface {
	Add(*Users) error
	Edit(*Users) error
	Remove([]int64) error
	FindOne(queryOptions UsersFindOneQuery) (Users, error)
	//FindOneWithExist 查询一个用户,
	//当数据不存在时不返回错误,替代的是返回bool,true表示数据存在,false表示数据不存在
	FindOneWithExist(queryOptions UsersFindOneQuery) (*Users, bool, error)
	Find(queryOptions UsersFindQuery) (int, []Users, error)
}