package services

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/beego/beego/v2/client/orm"
	"hongze/hz_crm_api/models"
	"hongze/hz_crm_api/models/company"
	"hongze/hz_crm_api/models/company_user"
	"hongze/hz_crm_api/models/system"
	"hongze/hz_crm_api/models/yb"
	"hongze/hz_crm_api/services/alarm_msg"
	"hongze/hz_crm_api/utils"
	"strconv"
	"strings"
	"time"
)

// 移动潜在客户名下的联系人
func MovePotentialUser(userId, companyId int, realName, mobile, email, remark string, companyProductList []*company.CompanyProduct, wxUser *models.WxUser, updateWxCol []string) (err error) {
	wxUser.CompanyId = companyId
	wxUser.Remark = remark
	wxUser.LastUpdatedTime = time.Now()
	updateWxCol = append(updateWxCol, "CompanyId", "Remark", "LastUpdatedTime")
	err = wxUser.Update(updateWxCol)

	if err != nil {
		return
	}

	//删除原有的销售关系
	_ = models.DeleteUserSellerRelationByUserId(userId)

	//添加新的联系人与销售员的关系
	if companyProductList != nil && len(companyProductList) > 0 {
		for _, companyProduct := range companyProductList {
			_, tmpErr := models.AddUserSellerRelation(int64(userId), companyProduct.CompanyId, companyProduct.SellerId, companyProduct.ProductId, companyProduct.SellerName, mobile, email)
			if tmpErr != nil {
				utils.FileLog.Info("添加销售与联系人的关系失败,错误原因:,其他信息:user_id:%s;seller_id:%s;product_id:%s", tmpErr.Error(), userId, companyProduct.SellerId, companyProduct.ProductId)
			}
		}
	}

	// 若联系人有图表权限则清除
	_ = company_user.ClearUserChartPermission(userId)

	return
}

// 移动销售名下的联系人
func MoveUser(userId, companyId, sellerId int, wxUser *models.WxUser, adminId int) (err error) {
	productId := 1
	var toSellerInfo *system.Admin
	//有选择销售的情况下(正常来说就是不是移动到潜在客户中去的情况下)
	if sellerId > 0 {
		//获取新的销售信息
		tmpSellerInfo, queryErr := system.GetSysAdminById(sellerId)
		if queryErr != nil {
			err = errors.New("获取即将移动的销售信息失败,Err:" + queryErr.Error())
			return
		}

		companyProduct, tmpErr := company.GetCompanyProductByCompanyIdAndSellerId(companyId, sellerId)
		if tmpErr != nil {
			err = errors.New("获取即将移动的销售与客户信息失败,err:" + tmpErr.Error())
			return
		}
		productId = companyProduct.ProductId
		//productId = GetProductId(tmpSellerInfo.RoleTypeCode)
		//if productId == 0 {
		//	err = errors.New("销售信息异常")
		//	return
		//}
		toSellerInfo = tmpSellerInfo
	}
	//将联系人挪移到 对应的 企业客户 下面
	err = models.MoveUser(userId, companyId)
	if err != nil {
		return
	}

	//删除联系人与原有的销售关系
	_ = models.DeleteUserSellerRelationByUserId(userId)

	//不是挪到潜在客户的话,那么就不需要重新 添加新的联系人与销售员的关系(正常来说就是不是移动到潜在客户中去的情况下)
	if toSellerInfo != nil {
		//添加新的联系人与销售员的关系
		_, tmpErr := models.AddUserSellerRelation(int64(userId), companyId, sellerId, productId, toSellerInfo.AdminName, wxUser.Mobile, wxUser.Email)
		if tmpErr != nil {
			utils.FileLog.Info("添加销售与联系人的关系失败,错误原因:,其他信息:user_id:%s;seller_id:%s;product_id:%s", tmpErr.Error(), userId, sellerId, productId)
		}
	}

	// 若联系人有图表权限则清除
	_ = company_user.ClearUserChartPermission(userId)

	// 若联系人发起过ficc申请则标记为已处理,已移动
	_ = DealFiccApply(userId, adminId)
	return
}

// 删除微信用户
func DeleteWxUser(userId int) (err error) {
	//删除用户与第三方(微信用户)的关系
	err = models.DelUserRecordByUserId(userId)
	if err != nil {
		return
	}

	//删除用户
	err = company.DeleteCompanyUser(userId)

	// 若联系人有图表权限则清除
	_ = company_user.ClearUserChartPermission(userId)
	return
}

// 删除微信用户
func DeleteCompanyWxUserByProductId(companyId, productId int) (list []*models.UserSellerRelation, userRecordList []*models.UserRecord, wxUserList []*models.WxUser, chartClassifyPermission []*company_user.ChartClassifyPermission, err error) {
	//productId = 1
	//获取当前产品 的 所有联系人
	list, err = models.GetCompanyUserSellerRelationByProductId(companyId, productId)
	//只删除自己的联系人(如果该联系人是共享,那么也不删除)
	//fmt.Println(list)

	//获取不是当前产品的所有联系人
	notList, err := models.GetNotCompanyUserSellerRelationByProductId(companyId, productId)
	//fmt.Println(notList)

	//不是当前产品的所有联系人map,真正删除的时候,用来做判断是否存在该联系人
	wxUserMap := make(map[int]int)
	for _, wxUser := range notList {
		wxUserMap[wxUser.UserId] = 1
	}
	//fmt.Println(wxUserMap)

	userIdSlice := make([]string, 0)
	for _, wxUser := range list {
		//_, ok := wxUserMap[wxUser.UserId]
		//fmt.Println(wxUser.UserId, "===:", ok)
		if _, ok := wxUserMap[wxUser.UserId]; ok == false {
			userIdSlice = append(userIdSlice, strconv.Itoa(wxUser.UserId))
		}
	}
	//fmt.Println(userIdSlice)

	//删除用户与销售员的关系
	err = models.DelCompanyUserSellerRelationByProductId(companyId, productId)
	if err != nil {
		return
	}
	if len(userIdSlice) > 0 {
		userIdStr := strings.Join(userIdSlice, ",")

		//根据用户id字符串获取用户与第三方(微信用户)的关系列表
		userRecordList, err = models.GetUserRecordListByUserIds(userIdStr)
		if err != nil {
			return
		}
		//删除用户与第三方(微信用户)的关系
		err = models.DelUserRecordByUserIds(userIdStr)
		if err != nil {
			return
		}

		//删除用户
		wxUserList, err = models.GetWxUserListByUserIds(userIdStr)
		if err != nil {
			return
		}
		//删除用户
		err = models.DeleteWxUserByUserIds(userIdStr)

		// 清除客户联系人图表权限设置
		chartClassifyPermission, err = company_user.GetCompanyChartPermissionByCompanyId(companyId)
		if err != nil {
			return
		}
		_ = company_user.ClearCompanyChartPermission(companyId)
	}
	return
}

// 根绝客户id获取客户下面的联系人数量
func GetUserCountByCompanyId(companyId, productId int) (total int, err error) {
	var condition string
	var pars []interface{}

	if productId > 0 {
		condition += ` AND a.company_id = ? AND b.company_id = ?   AND b.product_id = ? `
		pars = append(pars, companyId, companyId, productId)
		tmpTotal, tmpErr := company.GetCompanyUserListCountV2(condition, pars, companyId)
		total = tmpTotal
		err = tmpErr
	} else {
		tmpTotal, tmpErr := company.GetCompanyUserCount(companyId)
		total = tmpTotal
		err = tmpErr
	}
	return
}

// DealPotentialUser 标记潜在用户
func DealPotentialUser(userId, sysUserId int) (err error) {
	o := orm.NewOrm()
	to, err := o.Begin()
	if err != nil {
		return
	}
	defer func() {
		if err != nil {
			_ = to.Rollback()
		} else {
			_ = to.Commit()
		}
	}()

	// 1.标记用户表
	wxUser, err := models.GetWxUserByUserId(userId)
	if err != nil {
		if err.Error() == utils.ErrNoRow() {
			err = errors.New(fmt.Sprint("用户不存在", err))
			return
		}
		return
	}
	if wxUser.IsDeal != 0 {
		err = errors.New(fmt.Sprint("用户标记状态有误", err))
		return
	}
	nowTime := time.Now()
	wxUser.IsDeal = 1
	wxUser.LastUpdatedTime = nowTime
	userUpdateCols := make([]string, 0)
	userUpdateCols = append(userUpdateCols, "IsDeal", "LastUpdatedTime")
	err = wxUser.Update(userUpdateCols)

	// 2.标记申请记录表中所有该用户的申请
	err = yb.DealUserApplyRecords(userId, sysUserId, nowTime)
	return
}

// MovePotentialUserByApplyRecord 通过FICC申请单移动客户
func MovePotentialUserByApplyRecord(adminId, userId, companyId, applyRecordId int, realName, mobile, email, remark string, companyProductList []*company.CompanyProduct, wxUser *models.WxUser, updateWxCol []string) (err error) {
	o := orm.NewOrm()
	to, err := o.Begin()
	if err != nil {
		return
	}
	defer func() {
		if err != nil {
			_ = to.Rollback()
		} else {
			_ = to.Commit()
		}
	}()

	// 移动潜在客户
	err = MovePotentialUser(userId, companyId, realName, mobile, email, remark, companyProductList, wxUser, updateWxCol)
	if err != nil {
		return
	}

	// 标记FICC申请单为已移动
	if applyRecordId > 0 {
		applyRecord, tErr := yb.GetApplyRecordById(applyRecordId)
		if tErr != nil {
			if tErr.Error() == utils.ErrNoRow() {
				err = errors.New(fmt.Sprint("申请记录不存在:", err))
			}
			err = tErr
			return
		}
		updateCols := make([]string, 0)
		applyRecord.IsMove = 1
		updateCols = append(updateCols, "IsMove")
		if applyRecord.OpStatus == 0 {
			applyRecord.OpStatus = 1
			applyRecord.DealTime = time.Now()
			applyRecord.SysUserId = adminId
			updateCols = append(updateCols, "OpStatus", "DealTime", "SysUserId")
		}
		err = applyRecord.Update(updateCols)
		if err != nil {
			err = errors.New(fmt.Sprint("标记申请单失败", err))
			return
		}
	}

	return
}

// SwitchHzUserEnabledByMobile 根据手机号启用/禁用弘则研究下的联系人
func SwitchHzUserEnabledByMobile(opEnabled int, mobile string) (err error) {
	if mobile == "" {
		return
	}
	userInfo, err := models.GetWxUserByMobile(mobile)
	if err != nil && err.Error() != utils.ErrNoRow() {
		return
	}
	// 存在相应联系人
	if userInfo != nil {
		// 禁用-联系人为弘则研究下的则设置为潜在用户
		updateCols := make([]string, 0)
		if opEnabled == 0 && userInfo.CompanyId == 16 {
			userInfo.CompanyId = 1
			userInfo.LastUpdatedTime = time.Now()
			updateCols = append(updateCols, "CompanyId", "LastUpdatedTime")
			_ = userInfo.Update(updateCols)
		}
		// 启用-联系人为潜在用户则设置为弘则研究下
		if opEnabled == 1 && userInfo.CompanyId == 1 {
			userInfo.CompanyId = 16
			userInfo.LastUpdatedTime = time.Now()
			updateCols = append(updateCols, "CompanyId", "LastUpdatedTime")
			_ = userInfo.Update(updateCols)
		}
	}

	return nil
}

// DeleteHzUserByMobile 根据手机号删除弘则研究下的联系人
func DeleteHzUserByMobile(mobile string) (err error) {
	if mobile == "" {
		return
	}
	companyId := 16
	userInfo, err := models.GetWxUserByCompanyIdAndMobile(companyId, mobile)
	if err != nil && err.Error() != utils.ErrNoRow() {
		return
	}
	if userInfo != nil {
		userId := int(userInfo.UserId)
		if err = models.DeleteWxUserAndRecordByUserId(userId); err != nil {
			return
		}
		// 删除所有的标识,并真正删除数据
		_ = models.DeleteUserSellerRelationByProductId(userId, 1)
		_ = models.DeleteUserSellerRelationByProductId(userId, 2)

		// 更新客户最近阅读次数以及最近阅读时间
		go ModifyCompanyProductLastViewData([]int{userInfo.CompanyId})
	}

	return nil
}

// ForbiddenSysUserByMobile 根据手机号禁用联系人关联的系统管理员
func ForbiddenSysUserByMobile(mobile string) (err error) {
	if mobile == "" {
		return
	}
	adminInfo, _ := system.GetSysUserByMobile(mobile)
	if adminInfo == nil {
		return
	}
	// 禁用管理员
	if err = system.DisableAdmin(adminInfo.AdminId); err != nil {
		return
	}

	return
}

// DealFiccApply 用户一旦被移动将未被标记处理的用户都标记成已处理
func DealFiccApply(userId, sysUserId int) (err error) {
	//更新申请为标记处理
	nowTime := time.Now()
	err = yb.DealUnDealFiccApplyByIds(userId, sysUserId, nowTime)
	return
}

// AddHzCompanyUser 新增弘则联系人
func AddHzCompanyUser(mobile, realName string, adminId int, adminName string) {
	var err error
	defer func() {
		if err != nil {
			go alarm_msg.SendAlarmMsg("自动添加弘则联系人失败, Err: "+err.Error(), 3)
		}
	}()
	mobile = utils.TrimStr(mobile)
	realName = utils.TrimStr(realName)
	if mobile == "" || realName == "" {
		return
	}

	// 设置3分钟缓存, 不允许重复添加, 添加完成删除对应的缓存
	cacheKey := "wx_user:mobile:" + mobile
	isHas := utils.Rc.IsExist(cacheKey)
	if isHas == true {
		return
	}
	utils.Rc.SetNX(cacheKey, 1, time.Second*300)
	defer func() {
		_ = utils.Rc.Delete(cacheKey)
	}()

	// 此处简化操作, 但凡能查出手机号对应的联系人, 不管是否为弘则研究均直接返回, 手动加联系人
	userItem, e := company.GetUserCountByMobile(mobile)
	if e != nil && e.Error() != utils.ErrNoRow() {
		err = errors.New("获取手机号对应联系人失败, Err: " + e.Error())
		return
	}
	if userItem != nil {
		return
	}

	// 新增用户
	companyId := utils.HZ_COMPANY_ID
	newUser := &models.WxUser{
		RealName:            realName,
		Sex:                 1, // 默认1-男
		CountryCode:         utils.DEFAULT_COUNTRY_CODE,
		Mobile:              mobile,
		OutboundCountryCode: utils.DEFAULT_COUNTRY_CODE,
		IsMaker:             0,
		CompanyId:           companyId,
		CreatedTime:         time.Now().Local(),
		RegisterPlatform:    utils.WX_USER_REGISTER_PLATFORM_ADMIN,
	}
	userId, e := models.AddWxUser(newUser)
	if e != nil {
		err = errors.New("新增弘则联系人失败, Err: " + e.Error())
		return
	}
	newUser.UserId = userId

	// 弘则联系人两种产品都有
	productList := make([]*company.CompanyProduct, 0)
	ficcProduct, e := company.GetCompanyProductByCompanyIdAndProductId(companyId, 1)
	if e != nil && e.Error() != utils.ErrNoRow() {
		err = errors.New("获取弘则FICC产品失败, Err: " + e.Error())
		return
	}
	if ficcProduct != nil {
		productList = append(productList, ficcProduct)
	}
	equityProduct, e := company.GetCompanyProductByCompanyIdAndProductId(companyId, 2)
	if e != nil && e.Error() != utils.ErrNoRow() {
		err = errors.New("获取弘则权益产品失败, Err: " + e.Error())
		return
	}
	if equityProduct != nil {
		productList = append(productList, equityProduct)
	}

	// 将联系人与销售员绑定
	for _, p := range productList {
		if _, e = models.AddUserSellerRelation(userId, p.CompanyId, p.SellerId, p.ProductId, p.SellerName, mobile, ""); e != nil {
			err = errors.New(fmt.Sprintf("新增弘则联系人与销售关系失败, ProductId: %d, Err: %s", p.ProductId, e.Error()))
			return
		}
	}

	// 记录新增用户日志
	userJson, _ := json.Marshal(newUser)
	go AddWxUserOpLog(company.WxUserOpLog{
		LogType:                "add",
		UserId:                 int(newUser.UserId),
		CompanyId:              newUser.CompanyId,
		Mobile:                 newUser.Mobile,
		Email:                  newUser.Email,
		OriginalUserInfo:       "",
		UserInfo:               string(userJson),
		OriginalUserSellerInfo: "",
		UserSellerInfo:         "",
		OpUserId:               adminId,
		OpUserName:             adminName,
		CreateTime:             time.Now(),
	})
	return
}