package gn

import (
	"eta_gn/eta_bridge/controller/resp"
	gnLogic "eta_gn/eta_bridge/logic/gn"
	"eta_gn/eta_bridge/models/gn"
	gnRequest "eta_gn/eta_bridge/models/request/gn"
	"eta_gn/eta_bridge/utils"
	"fmt"
	"github.com/gin-gonic/gin"
	"strings"
	"time"
)

// 同步用户锁,防止重复同步,不管是全量还是增量,都是同一时间只能一个同步
//var lockSyncUser sync.Mutex

// SyncUser 临时-全量同步用户
//func (gc *GuoNengController) SyncUser(c *gin.Context) {
//	lockSyncUser.Lock()
//	defer func() {
//		lockSyncUser.Unlock()
//	}()
//	err := gnLogic.SyncUser()
//	if err != nil {
//		resp.FailData("同步失败", err.Error(), c)
//		return
//	}
//	resp.Ok("同步成功", c)
//}

// AddAccount 创建新账号
func (gc *GuoNengController) AddAccount(c *gin.Context) {
	var req gnRequest.AddAccountReq
	if e := c.Bind(&req); e != nil {
		resp.Gn4AResultData(resp.FAIL_CODE, "参数有误", fmt.Sprintf("参数解析失败, %v", e), c)
		return
	}
	if req.UserId == nil || (req.UserId != nil && *req.UserId == "") {
		resp.Gn4AResultData(resp.FAIL_CODE, "登录账号标识不可为空", "登录账号标识不可为空", c)
		return
	}
	if req.FirstName == nil || (req.FirstName != nil && *req.FirstName == "") {
		resp.Gn4AResultData(resp.FAIL_CODE, "姓名不可为空", "姓名不可为空", c)
		return
	}
	if req.LastName == nil || (req.LastName != nil && *req.LastName == "") {
		resp.Gn4AResultData(resp.FAIL_CODE, "姓名不可为空", "姓名不可为空", c)
		return
	}
	if req.UserStatus == nil || (req.UserStatus != nil && *req.UserStatus == "") {
		resp.Gn4AResultData(resp.FAIL_CODE, "账号状态不可为空", "账号状态不可为空", c)
		return
	}
	if req.Password == nil || (req.Password != nil && *req.Password == "") {
		resp.Gn4AResultData(resp.FAIL_CODE, "密码不可为空", "密码不可为空", c)
		return
	}
	if req.UserStatus != nil {
		statsMap := map[string]int{gn.UserStatusActive: 1, gn.UserStatusDisable: 0}
		if _, ok := statsMap[*req.UserStatus]; !ok {
			resp.Gn4AResultData(resp.FAIL_CODE, "枚举值异常: UserStatus", fmt.Sprintf("枚举值异常, UserStatus: %s", *req.UserStatus), c)
			return
		}
	}
	if req.EmpNumber == nil || (req.EmpNumber != nil && *req.EmpNumber == "") {
		resp.Gn4AResultData(resp.FAIL_CODE, "员工编号不可为空", "员工编号不可为空", c)
		return
	}

	// 新增账号
	errMsg, e := gnLogic.AddAccount(req.UserEntity)
	if e != nil {
		resp.Gn4AResultData(resp.FAIL_CODE, errMsg, fmt.Sprintf("AddAccount: %v", e), c)
		return
	}
	resp.Gn4AResultData(resp.GN_OK_CODE, "成功", "", c)
}

// ModifyAccount 修改账号信息
func (gc *GuoNengController) ModifyAccount(c *gin.Context) {
	var req gnRequest.ModifyAccountReq
	if e := c.Bind(&req); e != nil {
		resp.Gn4AResultData(resp.FAIL_CODE, "参数有误", fmt.Sprintf("参数解析失败, %v", e), c)
		return
	}
	if req.UserId == nil || (req.UserId != nil && *req.UserId == "") {
		resp.Gn4AResultData(resp.FAIL_CODE, "登录账号标识不可为空", "登录账号标识不可为空", c)
		return
	}
	//if req.FirstName == nil || (req.FirstName != nil && *req.FirstName == "") {
	//	resp.Gn4AResultData(resp.FAIL_CODE, "姓名不可为空", "姓名不可为空", c)
	//	return
	//}
	//if req.LastName == nil || (req.LastName != nil && *req.LastName == "") {
	//	resp.Gn4AResultData(resp.FAIL_CODE, "姓名不可为空", "姓名不可为空", c)
	//	return
	//}
	//if req.UserStatus == nil || (req.UserStatus != nil && *req.UserStatus == "") {
	//	resp.Gn4AResultData(resp.FAIL_CODE, "账号状态不可为空", "账号状态不可为空", c)
	//	return
	//}
	//if req.Password == nil || (req.Password != nil && *req.Password == "") {
	//	resp.Gn4AResultData(resp.FAIL_CODE, "密码不可为空", "密码不可为空", c)
	//	return
	//}
	if req.UserStatus != nil {
		statsMap := map[string]int{gn.UserStatusActive: 1, gn.UserStatusDisable: 0}
		if _, ok := statsMap[*req.UserStatus]; !ok {
			resp.Gn4AResultData(resp.FAIL_CODE, "枚举值异常: UserStatus", fmt.Sprintf("枚举值异常, UserStatus: %s", *req.UserStatus), c)
			return
		}
	}
	//if req.EmpNumber == nil || (req.EmpNumber != nil && *req.EmpNumber == "") {
	//	resp.Gn4AResultData(resp.FAIL_CODE, "员工编号不可为空", "员工编号不可为空", c)
	//	return
	//}

	// 更新账号
	errMsg, e := gnLogic.ModifyAccount(req.UserEntity)
	if e != nil {
		resp.Gn4AResultData(resp.FAIL_CODE, errMsg, fmt.Sprintf("ModifyAccount: %v", e), c)
		return
	}
	resp.Gn4AResultData(resp.GN_OK_CODE, "成功", "", c)
}

// DeleteAccount 删除账号
func (gc *GuoNengController) DeleteAccount(c *gin.Context) {
	var req gnRequest.DeleteAccountReq
	if e := c.Bind(&req); e != nil {
		resp.Gn4AResultData(resp.FAIL_CODE, "参数有误", fmt.Sprintf("参数解析失败, %v", e), c)
		return
	}
	if req.UserId == "" {
		resp.Gn4AResultData(resp.FAIL_CODE, "登录账号标识不可为空", "登录账号标识不可为空", c)
		return
	}

	//errMsg, e := gnLogic.DeleteAccount(req.UserId)
	errMsg, e := gnLogic.SuspendAccount(req.UserId)
	if e != nil {
		resp.Gn4AResultData(resp.FAIL_CODE, errMsg, fmt.Sprintf("DeleteAccount: %v", e), c)
		return
	}
	resp.Gn4AResultData(resp.GN_OK_CODE, "成功", "", c)
}

// SuspendAccount 禁用账号
func (gc *GuoNengController) SuspendAccount(c *gin.Context) {
	var req gnRequest.SuspendAccountReq
	if e := c.Bind(&req); e != nil {
		resp.Gn4AResultData(resp.FAIL_CODE, "参数有误", fmt.Sprintf("参数解析失败, %v", e), c)
		return
	}
	if req.UserId == "" {
		resp.Gn4AResultData(resp.FAIL_CODE, "登录账号标识不可为空", "登录账号标识不可为空", c)
		return
	}

	errMsg, e := gnLogic.SuspendAccount(req.UserId)
	if e != nil {
		resp.Gn4AResultData(resp.FAIL_CODE, errMsg, fmt.Sprintf("SuspendAccount: %v", e), c)
		return
	}
	resp.Gn4AResultData(resp.GN_OK_CODE, "成功", "", c)
}

// RestoreAccount 禁用账号
func (gc *GuoNengController) RestoreAccount(c *gin.Context) {
	var req gnRequest.RestoreAccountReq
	if e := c.Bind(&req); e != nil {
		resp.Gn4AResultData(resp.FAIL_CODE, "参数有误", fmt.Sprintf("参数解析失败, %v", e), c)
		return
	}
	if req.UserId == "" {
		resp.Gn4AResultData(resp.FAIL_CODE, "登录账号标识不可为空", "登录账号标识不可为空", c)
		return
	}

	errMsg, e := gnLogic.RestoreAccount(req.UserId)
	if e != nil {
		resp.Gn4AResultData(resp.FAIL_CODE, errMsg, fmt.Sprintf("RestoreAccount: %v", e), c)
		return
	}
	resp.Gn4AResultData(resp.GN_OK_CODE, "成功", "", c)
}

// ChangePassword 修改密码
func (gc *GuoNengController) ChangePassword(c *gin.Context) {
	var req gnRequest.ChangePasswordReq
	if e := c.Bind(&req); e != nil {
		resp.Gn4AResultData(resp.FAIL_CODE, "参数有误", fmt.Sprintf("参数解析失败, %v", e), c)
		return
	}
	if req.UserId == "" {
		resp.Gn4AResultData(resp.FAIL_CODE, "登录账号标识不可为空", "登录账号标识不可为空", c)
		return
	}
	req.NewPassword = strings.TrimSpace(req.NewPassword)
	if req.NewPassword == "" {
		resp.Gn4AResultData(resp.FAIL_CODE, "新密码不可为空", "新密码不可为空", c)
		return
	}

	errMsg, e := gnLogic.ChangePassword(req.UserId, req.NewPassword)
	if e != nil {
		resp.Gn4AResultData(resp.FAIL_CODE, errMsg, fmt.Sprintf("ChangePassword: %v", e), c)
		return
	}
	resp.Gn4AResultData(resp.GN_OK_CODE, "成功", "", c)
}

// SyncMdmOrganization 同步mdm组织部门
func (gc *GuoNengController) SyncMdmOrganization(c *gin.Context) {
	var req gnRequest.SyncMdmOrganizationReq
	if e := c.Bind(&req); e != nil {
		resp.Gn4AResultData(resp.FAIL_CODE, "参数有误", "参数解析失败", c)
		return
	}
	req.MainFieldComstruCode = strings.TrimSpace(req.MainFieldComstruCode)
	if req.MainFieldComstruCode == "" {
		resp.Gn4AResultData(resp.FAIL_CODE, "组织机构编码不可为空", "组织机构编码不可为空", c)
		return
	}

	// 根据主编码判断是否已同步过, 同步过则更新
	ob := new(gn.MDM_COMSTRU)
	cond := ` AND Main_Field_Comstru_Code = ?`
	pars := make([]interface{}, 0)
	pars = append(pars, req.MainFieldComstruCode)
	item, e := ob.GetItemByCondition(cond, pars)
	if e != nil && !utils.IsErrNoRow(e) {
		resp.Gn4AResultData(resp.FAIL_CODE, "组织信息异常", fmt.Sprintf("获取MDM组织信息失败, %v", e), c)
		return
	}

	// 更新
	if item != nil && item.Id > 0 {
		updateCols := []string{"Main_Field_Comstru_Code_HR", "Main_Field_Comstru_Type_HR", "ZDWLX", "Main_Field_Comstru_Name_HR", "Main_Field_Comstru_Short_Name_HR", "Main_Field_ParentAdmin_Comstru_Code_HR", "Main_Field_ParentAdmin_Comstru_Code", "Main_Field_ParentAdmin_Comstru_Name", "Main_Field_Company_Level", "Main_Field_Secondcomstrucodehr", "Main_Field_Sh_Business_Type", "Main_Field_YZGDWZCNDGX", "Main_Field_Order_HR", "Main_Field_Company_Code", "Main_Field_Company_Chain", "Main_Field_PARENTCOMPANYVIRTUAL", "ZQYZT", "ModifyTime"}
		item.MainFieldComstruCodeHR = req.MainFieldComstruCodeHR
		item.MainFieldComstruTypeHR = req.MainFieldComstruTypeHR
		item.ZDWLX = req.ZDWLX
		item.MainFieldComstruNameHR = req.MainFieldComstruNameHR
		item.MainFieldComstruShortNameHR = req.MainFieldComstruShortNameHR
		item.MainFieldParentAdminComstruCodeHR = req.MainFieldParentAdminComstruCodeHR
		item.MainFieldParentAdminComstruCode = req.MainFieldParentAdminComstruCode
		item.MainFieldParentAdminComstruName = req.MainFieldParentAdminComstruName
		item.MainFieldCompanyLevel = req.MainFieldCompanyLevel
		item.MainFieldSecondcomstrucodehr = req.MainFieldSecondcomstrucodehr
		item.MainFieldShBusinessType = req.MainFieldShBusinessType
		item.MainFieldYZGDWZCNDGX = req.MainFieldYZGDWZCNDGX
		item.MainFieldOrderHR = req.MainFieldOrderHR
		item.MainFieldCompanyCode = req.MainFieldCompanyCode
		item.MainFieldCompanyChain = req.MainFieldCompanyChain
		item.MainFieldPARENTCOMPANYVIRTUAL = req.MainFieldPARENTCOMPANYVIRTUAL
		item.ZQYZT = req.ZQYZT
		item.ModifyTime = time.Now()
		if e = item.Update(updateCols); e != nil {
			resp.Gn4AResultData(resp.FAIL_CODE, "同步失败", fmt.Sprintf("更新MDM组织信息失败, %v", e), c)
			return
		}
		resp.Gn4AResultData(resp.GN_OK_CODE, "成功", "", c)
		return
	}

	// 新增
	newOrganizer := gn.MDM_COMSTRU{
		MainFieldComstruCode:              req.MainFieldComstruCode,
		MainFieldComstruCodeHR:            req.MainFieldComstruCodeHR,
		MainFieldComstruTypeHR:            req.MainFieldComstruTypeHR,
		ZDWLX:                             req.ZDWLX,
		MainFieldComstruNameHR:            req.MainFieldComstruNameHR,
		MainFieldComstruShortNameHR:       req.MainFieldComstruShortNameHR,
		MainFieldParentAdminComstruCodeHR: req.MainFieldParentAdminComstruCodeHR,
		MainFieldParentAdminComstruCode:   req.MainFieldParentAdminComstruCode,
		MainFieldParentAdminComstruName:   req.MainFieldParentAdminComstruName,
		MainFieldCompanyLevel:             req.MainFieldCompanyLevel,
		MainFieldSecondcomstrucodehr:      req.MainFieldSecondcomstrucodehr,
		MainFieldShBusinessType:           req.MainFieldShBusinessType,
		MainFieldYZGDWZCNDGX:              req.MainFieldYZGDWZCNDGX,
		MainFieldOrderHR:                  req.MainFieldOrderHR,
		MainFieldCompanyCode:              req.MainFieldCompanyCode,
		MainFieldCompanyChain:             req.MainFieldCompanyChain,
		MainFieldPARENTCOMPANYVIRTUAL:     req.MainFieldPARENTCOMPANYVIRTUAL,
		ZQYZT:                             req.ZQYZT,
		CreateTime:                        time.Now(),
		ModifyTime:                        time.Now(),
	}
	if e = newOrganizer.Create(); e != nil {
		resp.Gn4AResultData(resp.FAIL_CODE, "同步失败", fmt.Sprintf("新增MDM组织信息失败, %v", e), c)
		return
	}

	// 同步ETA部门
	go func() {
		_ = gnLogic.SyncSysDepartment(&newOrganizer)
	}()

	resp.Gn4AResultData(resp.GN_OK_CODE, "成功", "", c)
}

// SyncMdmEmployee 同步mdm员工
func (gc *GuoNengController) SyncMdmEmployee(c *gin.Context) {
	var req gnRequest.SyncMdmEmployeeReq
	if e := c.Bind(&req); e != nil {
		resp.Gn4AResultData(resp.FAIL_CODE, "参数有误", "参数解析失败", c)
		return
	}
	req.MainFieldEmployeeCode = strings.TrimSpace(req.MainFieldEmployeeCode)
	if req.MainFieldEmployeeCode == "" {
		resp.Gn4AResultData(resp.FAIL_CODE, "员工编码不可为空", "员工编码不可为空", c)
		return
	}

	// 根据主编码判断是否已同步过, 同步过则更新
	ob := new(gn.MDM_EMPLOYEE)
	cond := ` AND Main_Field_Employee_Code = ?`
	pars := make([]interface{}, 0)
	pars = append(pars, req.MainFieldEmployeeCode)
	item, e := ob.GetItemByCondition(cond, pars)
	if e != nil && !utils.IsErrNoRow(e) {
		resp.Gn4AResultData(resp.FAIL_CODE, "员工信息异常", fmt.Sprintf("获取MDM员工信息失败, %v", e), c)
		return
	}

	// 员工组织关系
	relations := make([]*gn.MDM_RELA_COMSTRU_EMPLOYEE, 0)
	if len(req.MDM_MATERIAL_PROPS) > 0 {
		for _, v := range req.MDM_MATERIAL_PROPS {
			relations = append(relations, &gn.MDM_RELA_COMSTRU_EMPLOYEE{
				Main_Field_Employee_Code:  req.MainFieldEmployeeCode,
				TuplesFieldCompanyCode:    v.TuplesFieldCompanyCode,
				TuplesFieldCompanyName:    v.TuplesFieldCompanyName,
				TuplesFieldDepartmentCode: v.TuplesFieldDepartmentCode,
				TuplesFieldDepartmentName: v.TuplesFieldDepartmentName,
				CreateTime:                time.Now(),
				ModifyTime:                time.Now(),
			})
		}
	}

	// 更新
	var isUpdate bool
	employeeOb := new(gn.MDM_EMPLOYEE)
	if item != nil && item.Id > 0 {
		isUpdate = true
		updateCols := []string{"Main_Field_Employee_FirstName", "Main_Field_Employee_LastName", "Main_Field_Gender", "Main_Field_Empolyee_Group", "Main_Field_Office_Telephone", "Main_Field_Date_Type", "Main_Field_Employee_Status", "Main_Field_Delete_Flag", "Main_Field_Email", "Main_Field_Company_code", "Main_Field_Secondcomstrucodehr", "Main_Field_Company_Chain", "ModifyTime"}
		item.MainFieldEmployeeFirstName = req.MainFieldEmployeeFirstName
		item.MainFieldEmployeeLastName = req.MainFieldEmployeeLastName
		item.MainFieldGender = req.MainFieldGender
		item.MainFieldEmpolyeeGroup = req.MainFieldEmpolyeeGroup
		item.MainFieldOfficeTelephone = req.MainFieldOfficeTelephone
		item.MainFieldDateType = req.MainFieldDateType
		item.MainFieldEmployeeStatus = req.MainFieldEmployeeStatus
		item.MainFieldDeleteFlag = req.MainFieldDeleteFlag
		item.MainFieldEmail = req.MainFieldEmail
		item.MainFieldCompanyCode = req.MainFieldCompanyCode
		item.MainFieldSecondcomstrucodehr = req.MainFieldSecondcomstrucodehr
		item.MainFieldCompanyChain = req.MainFieldCompanyChain
		item.ModifyTime = time.Now()
		if e = employeeOb.UpdateEmployee(item, updateCols, relations); e != nil {
			resp.Gn4AResultData(resp.FAIL_CODE, "同步失败", fmt.Sprintf("更新MDM组织信息失败, %v", e), c)
			return
		}
	}

	// 新增
	if !isUpdate {
		newEmployee := &gn.MDM_EMPLOYEE{
			MainFieldEmployeeCode:        req.MainFieldEmployeeCode,
			MainFieldEmployeeFirstName:   req.MainFieldEmployeeFirstName,
			MainFieldEmployeeLastName:    req.MainFieldEmployeeLastName,
			MainFieldGender:              req.MainFieldGender,
			MainFieldEmpolyeeGroup:       req.MainFieldEmpolyeeGroup,
			MainFieldOfficeTelephone:     req.MainFieldOfficeTelephone,
			MainFieldDateType:            req.MainFieldDateType,
			MainFieldEmployeeStatus:      req.MainFieldEmployeeStatus,
			MainFieldDeleteFlag:          req.MainFieldDeleteFlag,
			MainFieldEmail:               req.MainFieldEmail,
			MainFieldCompanyCode:         req.MainFieldCompanyCode,
			MainFieldSecondcomstrucodehr: req.MainFieldSecondcomstrucodehr,
			MainFieldCompanyChain:        req.MainFieldCompanyChain,
			CreateTime:                   time.Now(),
			ModifyTime:                   time.Now(),
		}
		if e = employeeOb.CreateEmployee(newEmployee, relations); e != nil {
			resp.Gn4AResultData(resp.FAIL_CODE, "同步失败", fmt.Sprintf("新增MDM员工信息失败, %v", e), c)
			return
		}
	}
	resp.Gn4AResultData(resp.GN_OK_CODE, "成功", "", c)
}