package service

import (
	"app.yhyue.com/moapp/jybase/common"
	"app.yhyue.com/moapp/jybase/encrypt"
	"encoding/json"
	"fmt"
	"jyBXCore/rpc/bxcore"
	IC "jyBXCore/rpc/init"
	"strings"
	"time"
)

const (
	//角色
	Role_admin_system     = 1 //系统管理员
	Role_admin_department = 2 //部门管理员
)

type ParticipateStatistics struct {
	PositionId int64
	EntId      int64
	DeptId     int64
	EntUserId  int64
}

func (in *ParticipateStatistics) PushStatistics(entUserIdArr []string, startTime, endTime int64) (result []*bxcore.PushStatisticsData) {
	//判断是企业、部门还是个人
	isAdmin, personArrStr, users := in.PersonHandle(entUserIdArr)
	//时间处理
	query := QueryHandle(isAdmin, startTime, endTime, personArrStr)
	//推送数据查询
	dataList := IC.BaseMysql.SelectBySql(fmt.Sprintf("select  * from  participate_push_statistics where %s order  by ymd", strings.Join(query, " and ")))
	if users != nil && len(*users) > 0 {
		result = PushHandle(dataList, users, isAdmin)
	}
	return
}

func (in *ParticipateStatistics) ProjectStatistics(entUserIdArr []string, startTime, endTime int64) (result []*bxcore.ProjectStatisticsData) {
	//判断是企业、部门还是个人
	isAdmin, personArrStr, users := in.PersonHandle(entUserIdArr)
	query := QueryHandle(isAdmin, startTime, endTime, personArrStr)
	//订阅推送数处理
	//推送数据查询
	dataList := IC.BaseMysql.SelectBySql(fmt.Sprintf("select  * from  participate_project_statistics where %s order  by ymd", strings.Join(query, "and ")))
	if users != nil && len(*users) > 0 {
		result = ProjectHandle(dataList, users, isAdmin)
	}
	return
}

func (in *ParticipateStatistics) PersonHandle(entUserIdArr []string) (isAdmin bool, idStr string, users *[]map[string]interface{}) {
	userEnt := EntInfo(common.IntAll(in.EntId), common.IntAll(in.EntUserId))
	if len(entUserIdArr) > 0 {
		//查询所选人的部门以及人员信息
		users = GetUser(entUserIdArr)
		//返回所选人的信息
		isAdmin = true
		idStr = strings.Join(entUserIdArr, ",")
	} else {
		if userEnt.Role_admin_department || userEnt.Role_admin_system { //
			// 部门管理员 获取所有部门和子部门员工
			users = GetDisUsers(common.IntAll(in.EntId), userEnt.Dept.Id)
			var staffs []string
			if users != nil && len(*users) > 0 {
				for _, v := range *users {
					staffs = append(staffs, common.InterfaceToStr(v["id"]))
				}
			}
			isAdmin = true
			idStr = strings.Join(staffs, ",")
		} else {
			if userEnt.Dept.Id != 0 {
				entUserIdArr = append(entUserIdArr, common.InterfaceToStr(in.EntUserId))
				users = GetUser(entUserIdArr)
				//返回所选人的信息
				isAdmin = true
				idStr = strings.Join(entUserIdArr, ",")
			} else {
				isAdmin = false
				idStr = common.InterfaceToStr(in.PositionId)
				users = &[]map[string]interface{}{
					map[string]interface{}{
						"id":   in.PositionId,
						"name": "个人",
					},
				}
			}

		}
	}
	return
}

type PushData struct {
	PersonName      string
	entUserId       string
	DepartmentName  string
	PushNumb        map[string]interface{}
	ParticipateNumb map[string]interface{}
	BidNumb         map[string]interface{}
	WinNumb         map[string]interface{}
	BrowseNumb      map[string]interface{}
}
type ProjectData struct {
	PersonName     string
	DepartmentName string
	entUserId      string
	BidNumb        map[string]interface{} //投标数量
	DirectBidNumb  map[string]interface{} //直接投标数
	ChannelBidNumb map[string]interface{} //渠道投标数
	WinNumb        map[string]interface{}
	DirectWinNumb  map[string]interface{} //直接中标数
	ChannelWinNumb map[string]interface{} //渠道中标数
	NotBidNumber   map[string]interface{} //未中标数量
	EndNumb        map[string]interface{} //终止数量
}

func PushHandle(data *[]map[string]interface{}, users *[]map[string]interface{}, isAdmin bool) []*bxcore.PushStatisticsData {
	result := &map[int64]*PushData{}
	for k, v := range *users {
		(*result)[common.Int64All(v["id"])] = &PushData{
			PersonName:     fmt.Sprintf("%s_%d", common.InterfaceToStr(v["name"]), k),
			DepartmentName: common.InterfaceToStr(v["dept_name"]),
			entUserId:      common.InterfaceToStr(v["id"]),
		}
	}
	if data != nil && len(*data) > 0 {
		for _, v := range *data {
			userId := int64(0)
			if isAdmin {
				userId = common.Int64All(v["ent_user_id"])
			} else {
				userId = common.Int64All(v["position_id"])
			}
			if (*result)[userId] != nil {
				//浏览总数处理处理
				project_id := common.InterfaceToStr(common.InterfaceToStr(v["project_id"]))
				if common.Int64All(v["isvisit"]) > 0 {
					(*result)[userId].BrowseNumb = DataHanle((*result)[userId].BrowseNumb, project_id)
				}
				//推送总数处理
				(*result)[userId].PushNumb = DataHanle((*result)[userId].PushNumb, project_id)
				//参标总数处理
				if common.Int64All(v["isparticipate"]) > 0 {
					(*result)[userId].ParticipateNumb = DataHanle((*result)[userId].ParticipateNumb, project_id)
				}
				//投标总数处理
				if common.Int64All(v["isbid"]) > 0 {
					(*result)[userId].BidNumb = DataHanle((*result)[userId].BidNumb, project_id)
				}
				//中标总数处理
				if common.Int64All(v["win_status"]) != 0 {
					win_status := common.Int64All(v["win_status"])
					if win_status == 1 {
						(*result)[userId].WinNumb = DataHanle((*result)[userId].WinNumb, project_id)
					} else {
						delete((*result)[userId].WinNumb, project_id)
					}
				}
			}
		}
	}
	pushStatisticsList := make([]*bxcore.PushStatisticsData, len(*result))
	for _, v := range *result {
		personName := strings.Split(v.PersonName, "_")[0]
		k := common.Int64All(strings.Split(v.PersonName, "_")[1])
		pushStatisticsList[k] = &bxcore.PushStatisticsData{
			PersonName:      personName,
			DepartmentName:  v.DepartmentName,
			EntUserId:       encrypt.SE.Encode2Hex(v.entUserId),
			PushNumb:        common.Int64All(len(v.PushNumb)),
			ParticipateNumb: common.Int64All(len(v.ParticipateNumb)),
			BidNumb:         common.Int64All(len(v.BidNumb)),
			WinNumb:         common.Int64All(len(v.WinNumb)),
			BrowseNumb:      common.Int64All(len(v.BrowseNumb)),
		}
	}
	return pushStatisticsList
}
func ProjectHandle(data *[]map[string]interface{}, users *[]map[string]interface{}, isAdmin bool) []*bxcore.ProjectStatisticsData {
	result := &map[int64]*ProjectData{}
	for k, v := range *users {
		(*result)[common.Int64All(v["id"])] = &ProjectData{
			PersonName:     fmt.Sprintf("%s_%d", common.InterfaceToStr(v["name"]), k),
			DepartmentName: common.InterfaceToStr(v["dept_name"]),
			entUserId:      common.InterfaceToStr(v["id"]),
		}
	}
	if data != nil && len(*data) > 0 {
		for _, v := range *data {
			userId := int64(0)
			if isAdmin {
				userId = common.Int64All(v["ent_user_id"])
			} else {
				userId = common.Int64All(v["position_id"])
			}
			project_id := common.InterfaceToStr(common.InterfaceToStr(v["project_id"]))
			if (*result)[userId] != nil {
				//投标数量
				if common.Int64All(v["isbid"]) > 0 {
					(*result)[userId].BidNumb = DataHanle((*result)[userId].BidNumb, project_id)
				}
				//直接投标数
				if common.Int64All(v["bid_way"]) > 0 {
					if common.Int64All(v["bid_way"]) == 2 {
						(*result)[userId].ChannelBidNumb = DataHanle((*result)[userId].ChannelBidNumb, project_id)
						delete((*result)[userId].DirectBidNumb, project_id)
					} else {
						(*result)[userId].DirectBidNumb = DataHanle((*result)[userId].DirectBidNumb, project_id)
						delete((*result)[userId].ChannelBidNumb, project_id)
					}
				}
				//中标总数处理
				if common.Int64All(v["win_status"]) != 0 {
					if common.Int64All(v["win_status"]) > 0 {
						//中标数量
						(*result)[userId].WinNumb = DataHanle((*result)[userId].WinNumb, project_id)
						delete((*result)[userId].NotBidNumber, project_id)
					} else {
						//未中标数量
						(*result)[userId].NotBidNumber = DataHanle((*result)[userId].NotBidNumber, project_id)
						delete((*result)[userId].WinNumb, project_id)
					}
				}
				//中标方式处理
				if common.Int64All(v["win_bidway"]) != 0 {
					if common.Int64All(v["win_bidway"]) == 1 {
						//直接投标数量
						(*result)[userId].DirectWinNumb = DataHanle((*result)[userId].DirectWinNumb, project_id)
						delete((*result)[userId].ChannelWinNumb, project_id)
					} else {
						//渠道投标数量
						(*result)[userId].ChannelWinNumb = DataHanle((*result)[userId].ChannelWinNumb, project_id)
						delete((*result)[userId].DirectWinNumb, project_id)
					}
				}
				//终止参保统计
				if common.Int64All(v["isend"]) != 0 {
					(*result)[userId].EndNumb = DataHanle((*result)[userId].EndNumb, project_id)
				}
			}
		}
	}
	projectStatisticsList := make([]*bxcore.ProjectStatisticsData, len(*result))
	for _, v := range *result {
		personName := strings.Split(v.PersonName, "_")[0]
		k := common.Int64All(strings.Split(v.PersonName, "_")[1])
		projectStatisticsList[k] = &bxcore.ProjectStatisticsData{
			PersonName:     personName,
			DepartmentName: v.DepartmentName,
			EntUserId:      encrypt.SE.Encode2Hex(v.entUserId),
			BidNumb:        common.Int64All(len(v.BidNumb)),
			DirectBidNumb:  common.Int64All(len(v.DirectBidNumb)),
			ChannelBidNumb: common.Int64All(len(v.ChannelBidNumb)),
			WinNumb:        common.Int64All(len(v.WinNumb)),
			DirectWinNumb:  common.Int64All(len(v.DirectWinNumb)),
			ChannelWinNumb: common.Int64All(len(v.ChannelWinNumb)),
			NotBidNumber:   common.Int64All(len(v.NotBidNumber)),
			EndNumb:        common.Int64All(len(v.EndNumb)),
		}
	}
	return projectStatisticsList
}
func EntInfo(entId, entUserId int) *CurrentUser {
	currentUser := &CurrentUser{
		Dept: &Department{},
	}
	user := IC.MainMysql.SelectBySql(`SELECT a.name as user_name from entniche_user a INNER JOIN entniche_user_role b on (a.id=b.user_id) where a.id=? and b.role_id=? limit 1`, entUserId, Role_admin_system)
	if user != nil && len(*user) > 0 {
		currentUser.Role_admin_system = true
		currentUser.User_name, _ = (*user)[0]["user_name"].(string)
		currentUser.User_power = 1
		r := IC.MainMysql.SelectBySql(`SELECT id,name,subdis,nodiff from entniche_department where ent_id=? and pid=0 limit 1`, entId)
		if r != nil && len(*r) == 1 {
			department := JsonUnmarshal((*r)[0], &Department{}).(*Department)
			if department != nil {
				department.Pid = department.Id
				currentUser.Dept = department
			}
		}
	} else {
		//角色、权限
		r := IC.MainMysql.SelectBySql(`SELECT a.name as user_name,a.power as user_power,b.role_id,d.id as dept_id,d.name as dept_name,d.subdis as dept_subdis,d.nodiff as dept_nodiff,e.id as dept_pid from entniche_user a 
			LEFT JOIN entniche_user_role b on (b.user_id=?) 
			INNER JOIN entniche_department_user c on (a.id=? and a.id=c.user_id) 
			INNER JOIN entniche_department d on (c.dept_id=d.id) 
			INNER JOIN entniche_department e on (e.ent_id=? and e.pid=0) 
			order by a.id desc limit 1`, entUserId, entUserId, entId)
		if r != nil && len(*r) == 1 {
			currentUser.User_name, _ = (*r)[0]["user_name"].(string)
			currentUser.User_power = common.IntAll((*r)[0]["user_power"])
			if common.IntAll((*r)[0]["role_id"]) == Role_admin_department {
				currentUser.Role_admin_department = true
			}
			currentUser.Dept.Id = common.IntAll((*r)[0]["dept_id"])
			currentUser.Dept.Pid = common.IntAll((*r)[0]["dept_pid"])
			currentUser.Dept.Name = common.ObjToString((*r)[0]["dept_name"])
			currentUser.Dept.Subdis = common.IntAll((*r)[0]["dept_subdis"])
			currentUser.Dept.Nodiff = common.IntAll((*r)[0]["dept_nodiff"])
		}
	}
	return currentUser
}

// map转结构体
func JsonUnmarshal(m interface{}, s interface{}) interface{} {
	var b []byte
	if v, ok := m.(string); ok {
		b = []byte(v)
	} else if v, ok := m.([]byte); ok {
		b = v
	} else {
		b, _ = json.Marshal(m)
	}
	json.Unmarshal(b, &s)
	return s
}

// 获取部门下可以进行分发的人员(不包含部门名称和部门id)
func GetDisUsers(entId, deptId int) *[]map[string]interface{} {
	r := IC.MainMysql.SelectBySql(`select DISTINCT c.id,c.name,c.phone,c.power,b.dept_id,d.name as dept_name
		from entniche_department_parent a 
		INNER JOIN entniche_department_user b on (b.dept_id=? or (a.pid=? and a.id=b.dept_id)) 
		INNER JOIN entniche_user c on (c.ent_id=? and b.user_id=c.id) 
		INNER JOIN entniche_department d  on  d.id=b.dept_id
		order by b.dept_id , convert(c.name using gbk) COLLATE gbk_chinese_ci asc`, deptId, deptId, entId)
	return r
}
func GetUser(entUserIdArr []string) *[]map[string]interface{} {
	r := IC.MainMysql.SelectBySql("SELECT DISTINCT  a.id,  a.name,  a.phone,  d.id AS dept_id,  d.NAME AS dept_name  " +
		"FROM  entniche_user a " +
		" INNER JOIN entniche_department_user b ON  FIND_IN_SET(a.id,'" + strings.Join(entUserIdArr, ",") +
		"') and  b.user_id = a.id  " +
		" INNER JOIN entniche_department d ON d.id = b.dept_id " +
		" ORDER BY  d.id,  CONVERT ( a.NAME USING gbk ) COLLATE gbk_chinese_ci ASC",
	)
	return r
}

type User struct {
	Id        int
	Name      string //员工姓名
	Mail      string //邮箱
	Phone     string //手机号
	Dept_id   int    //部门id
	Dept_name string //部门名称
	//Role      string //角色
	Power int //权限
}

type CurrentUser struct {
	Role_admin_department bool        //是否是部门管理员
	Role_admin_system     bool        //是否是系统管理员
	Dept                  *Department //部门信息
	BondPhone             string      //手机号
	NickName              string      //昵称
	HeadImageUrl          string      //头像
	PersonalAuth          int         //个人认证
	PersonalAuthReason    string      //个人认证不通过原因
	User_power            int         //是否分配权限
	User_name             string      //用户姓名
}
type Department struct {
	Id         int
	Name       string //部门名
	Pid        int    //上级部门id
	Pname      string //上级部门名称
	Nodiff     int    //全员无差别接收 0：关闭 1：打开
	Subdis     int    //订阅分发 0：关闭 1：打开
	Aid        int    //管理员id
	Aname      string //管理员姓名
	Rname      string //角色名
	User_count int    //该部门下员工的总数
	Dept_count int    //该部门下子部门总数
	Ent_id     int    //公司id
}

func DataHanle(data map[string]interface{}, project_id string) map[string]interface{} {
	if data == nil {
		data = map[string]interface{}{project_id: 1}
	} else {
		data[project_id] = 1
	}
	return data
}
func QueryHandle(isAdmin bool, startTime, endTime int64, personArrStr string) []string {
	//时间处理
	query := []string{}
	if isAdmin {
		//是管理员
		query = append(query, fmt.Sprintf(" ent_user_id in (%s) ", personArrStr))
	} else {
		//不是管理员
		query = append(query, fmt.Sprintf(" position_id = %s ", personArrStr))
	}
	if startTime == 0 && endTime == 0 {
		//没有传时间，默认时间处理
		var start = time.Now().AddDate(0, 0, -30)
		query = append(query, fmt.Sprintf(" ymd >= %s ", start.Format("20060102")))
	}
	if startTime != 0 {
		query = append(query, fmt.Sprintf(" ymd >= %d ", startTime))
	}
	if endTime != 0 {
		query = append(query, fmt.Sprintf(" ymd <= %d ", endTime))
	}
	return query
}
