package maycur

import (
	"encoding/json"
	"fmt"
	"github.com/tealeg/xlsx"
	"hongze/hz_crm_api/models/system"
	"hongze/hz_crm_api/services/alarm_msg"
	"hongze/hz_crm_api/utils"
	"strings"
)

// EmployeeDetailReq 员工详情请求体
type EmployeeDetailReq struct {
	EmployeeIds []string `description:"员工工号" json:"employeeIds"`
}

// EmployeeDetailResp 员工详情响应体
type EmployeeDetailResp struct {
	Code    string               `description:"状态码"`
	Message string               `description:"返回信息"`
	Data    []EmployeeDetailData `description:"员工详情信息"`
	Success bool                 `description:"是否成功"`
}

// EmployeeDetailData 员工详情
type EmployeeDetailData struct {
	EmployeeId   string `description:"员工工号"`
	EmployeeName string `description:"员工姓名"`
	Email        string `description:"电子邮箱"`
	PhoneNo      string `description:"手机号"`
	Status       string `description:"状态: ENABLE-正常"`
}

// CurlEmployeeDetail 请求员工详情接口
func CurlEmployeeDetail(req EmployeeDetailReq) (employeeList []EmployeeDetailData, err error) {
	defer func() {
		if err != nil {
			utils.FileLog.Error("CurlEmployeeDetail ErrMsg: %s", err.Error())
			go alarm_msg.SendAlarmMsg(fmt.Sprintf("每刻报销-获取员工详情信息失败, ErrMsg: %s", err.Error()), 3)
		}
	}()
	for _, v := range req.EmployeeIds {
		if v == "" {
			err = fmt.Errorf("employeeIds is empty")
			return
		}
	}

	// 请求
	url := fmt.Sprintf("%s%s", utils.MayCurBaseUrl, ApiEmployeeDetailUrl)
	reqByte, e := json.Marshal(req)
	if e != nil {
		err = fmt.Errorf("request json marshal err: %s", e.Error())
		return
	}
	body, e := buildHttpRequest(url, "POST", string(reqByte), true)
	if e != nil {
		err = fmt.Errorf("curl api err: %s", e.Error())
		return
	}

	// 响应
	resp := new(EmployeeDetailResp)
	if e = json.Unmarshal(body, &resp); e != nil {
		err = fmt.Errorf("resp json unmarshal err: %s", e.Error())
		return
	}
	if resp == nil {
		err = fmt.Errorf("resp nil")
		return
	}
	if resp.Code != ApiSuccessCode {
		err = fmt.Errorf("resp err message: %s", resp.Message)
		return
	}
	employeeList = resp.Data
	return
}

// ImportExcelEmployee 导入Excel员工信息
type ImportExcelEmployee struct {
	EmployeeName string `description:"员工姓名"`
	EmployeeId   string `description:"员工工号"`
}

// ImportExcelEmployeeId 导入Excel更新员工工号
func ImportExcelEmployeeId() (err error) {
	defer func() {
		if err != nil {
			fmt.Printf("导入失败, ErrMsg: %s\n", err.Error())
			return
		}
		fmt.Println("导入成功")
	}()

	// 读取文件
	path := `./static/employee_id.xlsx`
	xlFile, e := xlsx.OpenFile(path)
	if e != nil {
		err = fmt.Errorf("打开文件失败, Err: %s", e.Error())
		return
	}

	// 读取数据
	importData := make([]*ImportExcelEmployee, 0)
	for _, sheet := range xlFile.Sheets {
		maxRow := sheet.MaxRow
		for i := 0; i < maxRow; i++ {
			if i == 0 {
				row := sheet.Row(i)
				cells := row.Cells
				for k, cell := range cells {
					text := cell.String()
					if k == 0 {
						if text != "姓名" {
							err = fmt.Errorf("模板格式错误: 姓名-%s", text)
							return
						}
					}
					if k == 1 {
						if text != "工号" {
							err = fmt.Errorf("模板格式错误: 工号-%s", text)
							return
						}
					}
				}
			}
			if i >= 1 {
				row := sheet.Row(i)
				cells := row.Cells
				employee := new(ImportExcelEmployee)
				for k, cell := range cells {
					v := strings.TrimSpace(cell.String())
					if v == "" {
						err = fmt.Errorf("第%d行存在空数据", i)
						return
					}
					if k == 0 {
						employee.EmployeeName = v
					}
					if k == 1 {
						employee.EmployeeId = v
					}
				}
				importData = append(importData, employee)
				fmt.Printf("姓名-%s; 工号-%s\n", employee.EmployeeName, employee.EmployeeId)
			}
		}
	}
	if len(importData) == 0 {
		return
	}
	employeeMap := make(map[string]string)
	for _, d := range importData {
		employeeMap[d.EmployeeName] = d.EmployeeId
	}

	// 更新工号
	adminOB := new(system.Admin)
	adminPars := make([]interface{}, 0)
	admins, e := adminOB.GetItemsByCondition(``, adminPars, []string{}, "")
	if e != nil {
		err = fmt.Errorf("获取员工列表失败, Err: %s", e.Error())
		return
	}
	updateCols := []string{"EmployeeId"}
	for _, a := range admins {
		id := employeeMap[a.RealName]
		if id == "" {
			continue
		}
		a.EmployeeId = id
		if e = a.Update(updateCols); e != nil {
			err = fmt.Errorf("更新员工工号失败, Err: %s", e.Error())
			return
		}
	}
	return
}

// levelMap 销售组别等级
var levelMap = map[string]string{
	utils.ROLE_TYPE_CODE_FICC_SELLER:     utils.ROLE_TYPE_CODE_FICC_TEAM,
	utils.ROLE_TYPE_CODE_FICC_TEAM:       utils.ROLE_TYPE_CODE_FICC_GROUP,
	utils.ROLE_TYPE_CODE_FICC_GROUP:      utils.ROLE_TYPE_CODE_FICC_DEPARTMENT,
	utils.ROLE_TYPE_CODE_FICC_DEPARTMENT: utils.ROLE_TYPE_CODE_FICC_ADMIN,
	utils.ROLE_TYPE_CODE_RAI_SELLER:      utils.ROLE_TYPE_CODE_RAI_GROUP,
	utils.ROLE_TYPE_CODE_RAI_GROUP:       utils.ROLE_TYPE_CODE_RAI_DEPARTMENT,
	utils.ROLE_TYPE_CODE_RAI_DEPARTMENT:  utils.ROLE_TYPE_CODE_RAI_ADMIN,
}

// findSellerLeader 查找销售上级
func findSellerLeader(seller *system.Admin, employeeList []*system.Admin, groupList []*system.Admin, groupParentMap map[int]int, groupParentChildrenMap map[int][]int, existMap map[int]bool) []*system.Admin {
	if groupList == nil {
		groupList = make([]*system.Admin, 0)
	}
	// 最上级, 中止递归
	leaderRole := levelMap[seller.RoleTypeCode]
	if leaderRole == "" {
		return groupList
	}
	// 遍历员工列表
	for _, v := range employeeList {
		isLeader := false

		// 根据当前销售级别查找(没办法...乱七八糟的=_=!)
		parentGroupId := groupParentMap[seller.GroupId]
		parentChildrenGroupIds := groupParentChildrenMap[seller.GroupId]
		switch seller.RoleTypeCode {
		case utils.ROLE_TYPE_CODE_FICC_SELLER:
			// 小组-组长/主管
			if seller.GroupId == v.GroupId && (v.RoleTypeCode == leaderRole || v.RoleTypeCode == levelMap[leaderRole]) {
				isLeader = true
				break
			}
			// 大组-主管/同时归属大组和大组下小组的主管
			if parentGroupId > 0 && v.RoleTypeCode == levelMap[leaderRole] && (v.GroupId == parentGroupId || utils.InArrayByInt(parentChildrenGroupIds, v.GroupId)) {
				isLeader = true
				break
			}
			// FICC部门管理员/FICC管理员
			if v.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_DEPARTMENT || v.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN {
				isLeader = true
				break
			}
		case utils.ROLE_TYPE_CODE_RAI_SELLER:
			// 本组的组长/主管
			if seller.GroupId == v.GroupId && (v.RoleTypeCode == leaderRole || v.RoleTypeCode == levelMap[leaderRole]) {
				isLeader = true
				break
			}
			// 权益销售部门主管
			if parentGroupId > 0 && v.RoleTypeCode == levelMap[leaderRole] && v.GroupId == parentGroupId {
				isLeader = true
				break
			}
			// 权益部门管理员/权益管理员
			if v.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_DEPARTMENT || v.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_ADMIN {
				isLeader = true
				break
			}
		case utils.ROLE_TYPE_CODE_FICC_TEAM:
			// 主管-同组
			if v.RoleTypeCode == leaderRole && seller.GroupId == v.GroupId {
				isLeader = true
				break
			}
			// 主管-父级组
			if v.RoleTypeCode == leaderRole && parentGroupId > 0 && parentGroupId == v.GroupId {
				isLeader = true
				break
			}
			// 主管-同一父级组但同时归属其他小组
			if v.RoleTypeCode == leaderRole && parentGroupId > 0 && utils.InArrayByInt(parentChildrenGroupIds, v.GroupId) {
				isLeader = true
				break
			}
			// FICC部门管理员/FICC管理员
			if v.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_DEPARTMENT || v.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN {
				isLeader = true
				break
			}
		case utils.ROLE_TYPE_CODE_FICC_GROUP, utils.ROLE_TYPE_CODE_RAI_GROUP:
			// 本组/上一组的领导
			if (seller.GroupId == v.GroupId || parentGroupId == v.GroupId) && v.RoleTypeCode == leaderRole {
				isLeader = true
				break
			}
			// FICC管理员
			if seller.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_GROUP && (v.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_DEPARTMENT || v.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN) {
				isLeader = true
				break
			}
			// 权益管理员
			if seller.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_GROUP && (v.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_DEPARTMENT || v.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_ADMIN) {
				isLeader = true
				break
			}
		}

		// 向上递归
		if !isLeader {
			continue
		}
		// 去重
		if !existMap[v.AdminId] {
			existMap[v.AdminId] = true
			groupList = append(groupList, v)
		}
		groupList = findSellerLeader(v, employeeList, groupList, groupParentMap, groupParentChildrenMap, existMap)
	}
	return groupList
}

// getEmployeeGroupMapFromList 获取员工及上级员工组Map
func getEmployeeGroupMapFromList() (employeeGroupMap map[int][]*system.Admin, err error) {
	employeeOB := new(system.Admin)
	employeeCond := ` AND enabled = 1 AND employee_id <> ""`
	employeePars := make([]interface{}, 0)
	employeeList, e := employeeOB.GetItemsByCondition(employeeCond, employeePars, []string{}, "")
	if e != nil {
		err = fmt.Errorf("获取员工列表失败, Err: %s", e.Error())
		return
	}

	// FICC销售多一层组, 所以需要更详细的分组信息
	sysGroupList, e := system.GetFullGroup()
	if e != nil {
		err = fmt.Errorf("获取部门分组列表失败, Err: %s", e.Error())
		return
	}
	groupParentMap := make(map[int]int)     // 组别父级ID
	groupChildrenMap := make(map[int][]int) // 组别子级IDs
	for _, s := range sysGroupList {
		if s.ParentId > 0 {
			groupParentMap[s.GroupId] = s.ParentId
			groupChildrenMap[s.ParentId] = append(groupChildrenMap[s.ParentId], s.GroupId)
		}
	}
	groupParentChildrenMap := make(map[int][]int) // 组别父级下的至直系子组
	for _, s2 := range sysGroupList {
		if s2.ParentId > 0 {
			groupParentChildrenMap[s2.GroupId] = groupChildrenMap[s2.ParentId]
		}
	}
	//fmt.Println("groupParentMap: ", groupParentMap)

	employeeGroupMap = make(map[int][]*system.Admin)
	for _, v := range employeeList {
		// 非销售角色忽略
		//if v.DepartmentId != 2 {
		//employeeGroupMap[v.AdminId] = append(employeeGroupMap[v.AdminId], v)
		//continue
		//}
		if employeeGroupMap[v.AdminId] == nil {
			employeeGroupMap[v.AdminId] = make([]*system.Admin, 0)
		}
		// 销售-自下而上找自己组的组长、主管一并加入自己的分组
		existMap := make(map[int]bool)
		leaders := findSellerLeader(v, employeeList, nil, groupParentMap, groupParentChildrenMap, existMap)
		employeeGroupMap[v.AdminId] = append(employeeGroupMap[v.AdminId], v)
		if len(leaders) > 0 {
			employeeGroupMap[v.AdminId] = append(employeeGroupMap[v.AdminId], leaders...)
		}
	}
	return
}
