package models

import (
	"errors"
	"oppmg/common/log"
	"time"

	"github.com/astaxie/beego/orm"
)

type Role struct {
	Id        int64     `orm:"column(id);auto"`
	Name      string    `orm:"column(name);size(30)"`
	Pid       int64     `orm:"column(pid)"`
	Types     int8      `orm:"column(types)"`
	CompanyId int64     `orm:"column(company_id)"`
	Descript  string    `orm:"column(descript)"`
	CreateAt  time.Time `orm:"column(create_at);type(timestamp)"`
	UpdateAt  time.Time `orm:"column(update_at);type(timestamp)"`
	DeleteAt  time.Time `orm:"column(delete_at);type(timestamp)"`
	IsDefault int8      `orm:"column(is_default)"`
}

func (t *Role) TableName() string {
	return "role"
}

func init() {
	orm.RegisterModel(new(Role))
}

//角色类型
const (
	ROLETYPES_ROLE  int8 = 1 //角色
	ROLETYPES_GROUP int8 = 2 //角色组

)

//默认角色
const (
	ROLE_DEFAULR     int8 = 1 //默认
	ROLE_DEFAULR_NOT int8 = 0 // 非默认
)

func (t *Role) ValidateTypes() bool {
	switch t.Types {
	case ROLETYPES_GROUP:
		return true
	case ROLETYPES_ROLE:
		return true
	}
	return false
}

func (t *Role) IsDefaultRole() bool {
	return t.IsDefault == ROLE_DEFAULR
}

func (t *Role) ValidatePid() (*Role, error) {
	if t.Pid == 0 {
		return nil, nil
	}
	roledata, err := GetRoleById(t.Pid)
	if err != nil {
		return nil, err
	}
	if roledata.DeleteAt.Unix() > 0 {
		return nil, errors.New("roledata Delete")
	}
	if roledata.Types != ROLETYPES_GROUP {
		return nil, errors.New("roledata.Types != ROLETYPES_GROUP")
	}
	if roledata.CompanyId != t.CompanyId {
		return nil, errors.New("validate  companyId err")
	}
	return roledata, nil
}

// AddRole insert a new Role into database and returns
// last inserted Id on success.
func AddRole(m *Role, om ...orm.Ormer) (id int64, err error) {
	var o orm.Ormer
	if len(om) > 0 {
		o = om[0]
	} else {
		o = orm.NewOrm()
	}
	m.CreateAt = time.Now()
	m.DeleteAt = time.Unix(0, 0)
	m.UpdateAt = time.Now()
	id, err = o.Insert(m)
	return
}

// GetRoleById retrieves Role by Id. Returns error if
// Id doesn't exist
func GetRoleById(id int64) (v *Role, err error) {
	o := orm.NewOrm()
	v = &Role{Id: id}
	if err = o.Read(v); err == nil {
		return v, nil
	}
	return nil, err
}

// UpdateRole updates Role by Id and returns error if
// the record to be updated doesn't exist
func UpdateRoleById(m *Role, col []string) (err error) {
	o := orm.NewOrm()
	v := Role{Id: m.Id}
	// ascertain id exists in the database
	if err = o.Read(&v); err == nil {
		var num int64
		if num, err = o.Update(m, col...); err == nil {
			log.Debug("Number of records updated in database:%d", num)
		}
	}
	return
}

// DeleteRole deletes Role by Id and returns error if
// the record to be deleted doesn't exist
func DeleteRoleByID(id int64) (err error) {
	o := orm.NewOrm()
	v := Role{Id: id}
	// ascertain id exists in the database
	if err = o.Read(&v); err == nil {
		var num int64
		v.DeleteAt = time.Now()
		if num, err = o.Update(&v); err == nil {
			log.Debug("Number of records updated in database:%d", num)
		}
	}
	return
}

func DeleteRoleByPid(pid int64) (err error) {
	o := orm.NewOrm()
	var num int64
	deleteAt := time.Now()
	num, err = o.QueryTable(&Role{}).Filter("pid", pid).Update(orm.Params{
		"delete_at": deleteAt,
	})
	log.Debug("Number of records updated in database:%d", num)
	return
}

func CountRoleByPid(pid int64) (int64, error) {
	o := orm.NewOrm()
	var (
		cnt int64
		err error
	)
	cnt, err = o.QueryTable(&Role{}).
		Filter("delete_at", 0).
		Filter("pid", pid).Count()
	return cnt, err
}

func GetRoleGroupsByCompany(companyid int64) ([]Role, error) {
	var (
		err   error
		roles []Role
	)
	o := orm.NewOrm()
	_, err = o.QueryTable(&Role{}).
		Filter("company_id", companyid).
		Filter("types", ROLETYPES_GROUP).
		Filter("delete_at", 0).
		All(&roles)
	if err == orm.ErrNoRows {
		return roles, nil
	}
	return roles, err
}

func GetRoleByPid(pid int64) ([]Role, error) {
	var (
		err   error
		roles []Role
	)
	o := orm.NewOrm()
	_, err = o.QueryTable(&Role{}).
		Filter("pid", pid).
		Filter("delete_at", 0).
		All(&roles)
	if err == orm.ErrNoRows {
		return roles, nil
	}
	return roles, err
}

func ExistRoleName(companyid int64, rname string, types int8) bool {
	var (
		ok bool
	)
	o := orm.NewOrm()
	ok = o.QueryTable(&Role{}).
		Filter("name", rname).
		Filter("types", types).
		Filter("company_id", companyid).
		Filter("delete_at", 0).
		Exist()
	return ok
}

func GetCompanyDefaultRole(companyid int64) (*Role, error) {
	r := &Role{}
	o := orm.NewOrm()
	err := o.QueryTable(&Role{}).
		Filter("company_id", companyid).
		Filter("types", ROLETYPES_ROLE).
		Filter("is_default", ROLE_DEFAULR).
		One(r)
	return r, err
}

func GetCompanyDefaultRoleGroup(companyid int64) (*Role, error) {
	r := &Role{}
	o := orm.NewOrm()
	err := o.QueryTable(&Role{}).
		Filter("company_id", companyid).
		Filter("types", ROLETYPES_GROUP).
		Filter("is_default", ROLE_DEFAULR).
		One(r)
	return r, err
}

func GetUserRoleByUser(usecompanyid int64) ([]Role, error) {
	sql := `SELECT a.id,a.pid,a.types,a.company_id FROM role AS a
			JOIN user_role AS b ON a.id= b.role_id
			WHERE a.delete_at=0 AND b.user_company_id =? `
	var (
		list []Role
		err  error
	)
	o := orm.NewOrm()
	_, err = o.Raw(sql, usecompanyid).QueryRows(&list)
	if err != nil {
		return list, err
	}
	return list, err
}