package user

import (
	"context"
	"errors"
	"hongze/hongze_yb/global"
	userReq "hongze/hongze_yb/models/request/user"
	admin2 "hongze/hongze_yb/models/tables/admin"
	"hongze/hongze_yb/models/tables/company"
	"hongze/hongze_yb/models/tables/company_product"
	"hongze/hongze_yb/models/tables/rddp/chart_permission"
	"hongze/hongze_yb/models/tables/rddp/msg_code"
	"hongze/hongze_yb/models/tables/research_variety_tag_relation"
	"hongze/hongze_yb/models/tables/sys_role_admin"
	"hongze/hongze_yb/models/tables/wx_user"
	"hongze/hongze_yb/models/tables/yb_apply_record"
	"hongze/hongze_yb/models/tables/yb_index_tab"
	"hongze/hongze_yb/models/tables/yb_message"
	"hongze/hongze_yb/services"
	companyService "hongze/hongze_yb/services/company"
	"hongze/hongze_yb/services/user"
	"hongze/hongze_yb/utils"
	"strings"
	"time"
)

// SendSmsCode 发送手机短信
func SendSmsCode(openid, mobile, areaNum string) (err error, errMsg string) {
	if mobile == "" {
		err = errors.New("请输入手机号")
		return
	}
	msgCode := utils.GetRandDigit(4)
	var result bool
	if areaNum == "86" || areaNum == "" || areaNum == "0" {
		//国内的短信
		result = services.SendSmsCode(mobile, msgCode)
	} else {
		//国际短信
		result = services.SendSmsCodeGj(mobile, msgCode, areaNum)
	}
	//发送成功
	if result {
		item := &msg_code.MsgCode{
			OpenID:          openid,
			Mobile:          mobile,
			Code:            msgCode,
			ExpiredIn:       time.Now().Add(15 * time.Minute).Unix(),
			Enabled:         1,
			CreatedTime:     time.Time{},
			LastUpdatedTime: time.Time{},
		}
		err = item.Create()
	} else {
		err = errors.New("短信发送失败")
	}
	return
}

// SendEmailCode 发送邮件
func SendEmailCode(openid, email string) (err error, errMsg string) {
	if email == "" {
		err = errors.New("请输入邮箱地址")
		return
	}
	if !utils.ValidateEmailFormatat(email) {
		err = errors.New("邮箱格式错误，请重新输入")
		return
	}
	msgCode := utils.GetRandDigit(4)
	content := "尊敬的用户：</br>您好，感谢您使用弘则研究，您正在进行邮箱验证，本次请求的验证码为：" + msgCode + "（为了保障您账号的安全性，请在15分钟内完成验证。）</br>弘则研究团队 </br>" + time.Now().Format(utils.FormatDateCN)
	title := "弘则研究登陆验证"
	//发送邮件
	result, err := services.SendEmailByHz(title, content, email)

	if result {
		item := &msg_code.MsgCode{
			OpenID:          openid,
			Mobile:          email,
			Code:            msgCode,
			ExpiredIn:       time.Now().Add(15 * time.Minute).Unix(),
			Enabled:         1,
			CreatedTime:     time.Time{},
			LastUpdatedTime: time.Time{},
		}
		err = item.Create()
	} else {
		err = errors.New("发送失败，Err:" + err.Error())
	}

	return
}

type CompanyPermission struct {
	Name           string           `json:"name" description:"分类名称"`
	PermissionList []PermissionList `json:"permission_list" description:"权限列表"`
}

type PermissionList struct {
	Name      string    `json:"name" description:"权限名称"`
	StartDate time.Time `json:"start_date" description:"开始日期"`
	EndDate   time.Time `json:"end_date" description:"结束日期"`
	Status    string    `json:"status" description:"状态"`
}

type Detail struct {
	CompanyName    string              `json:"company_name" description:"客户名称（公司名称）"`
	Status         string              `json:"status" description:"客户状态"`
	IsSuspend      int8                `json:"is_suspend" description:"启用与否字段：1:暂停,0:启用"`
	RealName       string              `json:"real_name" description:"用户名称"`
	Mobile         string              `json:"mobile" description:"手机号"`
	Email          string              `json:"email" description:"邮箱"`
	SellerName     string              `json:"seal_name" description:"所属销售名称"`
	SellerMobile   string              `json:"seal_mobile" description:"所属销售手机号"`
	PermissionList []CompanyPermission `json:"permission_list" description:"权限列表"`
	IsInner        int                 `json:"is_inner" description:"是否为内部员工"`
	IsResearcher   int                 `json:"is_researcher" description:"是否为研究员"`
	IsVoiceAdmin   int                 `json:"is_voice_admin" description:"是否为语音管理员"`
	AdminInfo      *admin2.Admin       `json:"admin_info" description:"系统管理员信息"`
	UnRead         int64               `json:"un_read" description:"消息未读数"`
	NickName       string              `json:"nick_name" description:"用户昵称"`
	HeadImgUrl     string              `json:"head_img_url" description:"用户头像，最后一个数值代表正方形头像大小（有0、46、64、96、132数值可选，0代表640*640正方形头像），用户没有头像时该项为空"`
	UserId         uint64              `json:"user_id" description:"用户ID"`
	IsBind         int                 `json:"is_bind" description:"是否绑定了微信"`
}

// GetUserInfo 获取用户我的页面详情数据
func GetUserInfo(userInfo user.UserInfo) (userDetail Detail, err error, errMsg string) {
	list := make([]CompanyPermission, 0)
	companyName := userInfo.Note
	status := ``
	var isSuspend int8
	sellerName := ``
	sellerMobile := ``
	if userInfo.CompanyID > 1 {
		companyInfo, tmpErr := company.GetByCompanyId(userInfo.CompanyID)
		if tmpErr != nil {
			err = tmpErr
			if tmpErr == utils.ErrNoRow {
				err = errors.New("找不到该客户")
				errMsg = "找不到该客户"
				return
			}
			errMsg = "系统异常4001"
			return
		}
		companyName = companyInfo.CompanyName

		companyProduct, tmpErr := company_product.GetByCompany2ProductId(userInfo.CompanyID, 1)

		//如果有ficc权限，那么就去查询相关权限
		if tmpErr == nil {
			status = companyProduct.Status //产品状态
			isSuspend = companyProduct.IsSuspend

			//销售信息
			adminInfo, tmpErr := admin2.GetByAdminId(companyProduct.SellerID)
			if tmpErr == nil {
				sellerName = adminInfo.RealName
				sellerMobile = adminInfo.Mobile
			}
			//获取所有的权限分类列表
			allPermissionList, tmpErr := companyService.GetPermissionListByProductId(1)
			if tmpErr != nil {
				err = tmpErr
				return
			}
			permissionClassMap := make(map[int]*chart_permission.ChartPermission)

			for _, chartPermission := range allPermissionList {
				permissionClassMap[int(chartPermission.ChartPermissionID)] = chartPermission
			}

			// 获取权限列表
			permissionList, tmpErr := companyService.GetValidPermissionByCompany2ProductId(userInfo.CompanyID, 1)
			if tmpErr != nil {
				err = tmpErr
				return
			}

			permissionMap := make(map[string][]PermissionList)
			for _, permission := range permissionList {
				chartPermission, ok := permissionClassMap[permission.ChartPermissionID]
				if ok {
					tmpPermission := PermissionList{
						Name:      chartPermission.PermissionName,
						StartDate: permission.StartDate,
						EndDate:   permission.EndDate,
						Status:    permission.Status,
					}
					if tmpPermissionList, ok2 := permissionMap[chartPermission.ClassifyName]; ok2 {
						permissionMap[chartPermission.ClassifyName] = append(tmpPermissionList, tmpPermission)
					} else {
						tmpPermissionList := make([]PermissionList, 0)
						permissionMap[chartPermission.ClassifyName] = append(tmpPermissionList, tmpPermission)
					}
				}
			}

			for name, tmpPermissionList := range permissionMap {
				list = append(list, CompanyPermission{
					Name:           name,
					PermissionList: tmpPermissionList,
				})
			}
		}

	}

	// 查询消息未读数
	unRead, err := yb_message.GetUnreadByUserId(userInfo.UserID)
	if err != nil {
		errMsg = "查询消息未读数失败"
		return
	}

	// 用户头像
	headimgurl := userInfo.Headimgurl
	if headimgurl == "" {
		// 未绑定-灰色头像
		headimgurl = utils.DEFAULT_HONGZE_USER_LOGO_GRAY
		if userInfo.UserID > 0 {
			headimgurl = utils.DEFAULT_HONGZE_USER_LOGO
		}
	}

	// 查询是否为内部员工、研究员、语音管理员
	isInner, isResearcher, isVoiceAdmin, adminInfo, e := GetUserIdentity(int(userInfo.CompanyID), userInfo.Mobile, userInfo.Email)
	if e != nil {
		return
	}

	isBind := 0
	if userInfo.UserID > 0 {
		isBind = 1
	}

	userDetail = Detail{
		CompanyName:    companyName, //客户名称（公司名称）
		Status:         status,      //产品状态
		IsSuspend:      isSuspend,   //是否启用
		RealName:       userInfo.RealName,
		Mobile:         userInfo.Mobile,
		Email:          userInfo.Email,
		SellerName:     sellerName,
		SellerMobile:   sellerMobile,
		PermissionList: list,         //权限列表
		IsInner:        isInner,      // 是否为内部员工
		IsResearcher:   isResearcher, // 是否为研究员
		IsVoiceAdmin:   isVoiceAdmin, // 语音管理员
		AdminInfo:      adminInfo,    // 系统管理员信息
		UnRead:         unRead,
		NickName:       userInfo.NickName,
		HeadImgUrl:     headimgurl,
		UserId:         userInfo.UserID,
		IsBind:         isBind,
	}

	return
}

// SetUserInfo 设置用户的个人信息，头像和昵称
func SetUserInfo(userInfo user.UserInfo, req userReq.SetUserInfoReq) (err error) {
	// todo 用户如果没有设置头像，用默认头像也允许上传
	// 校验昵称长度
	// 校验头像地址是否正确
	if !strings.Contains(req.HeadImgUrl, "http://") && !strings.Contains(req.HeadImgUrl, "https://") {
		err = errors.New("上传头像出错")
		return
	}
	wxUser := userInfo.WxUser
	wxUser.NickName = req.NickName
	wxUser.Headimgurl = req.HeadImgUrl
	err = wxUser.Update([]string{"nick_name", "headimgurl"})
	if err != nil {
		err = errors.New("更新用户信息操作失败")
		return
	}
	return
}

type Record struct {
	BusinessCardURL string `json:"business_card_url" description:"名片"`
	RealName        string `json:"real_name" description:"姓名"`
	CompanyName     string `json:"company_name" description:"客户备注的公司名称"`
	Mobile          string `json:"mobile" description:"手机号"`
}

// GetLastApplyInfo 获取最近的一套申请记录
func GetLastApplyInfo(userId int) (record Record, err error) {
	recordInfo, err := yb_apply_record.GetLastNotOpRecordByUserId(userId)
	if err != nil {
		if err == utils.ErrNoRow {
			err = nil
		}
		return
	}
	record = Record{
		BusinessCardURL: recordInfo.BusinessCardURL,
		RealName:        recordInfo.RealName,
		CompanyName:     recordInfo.CompanyName,
		Mobile:          recordInfo.Mobile,
	}
	return
}

// Apply 客户申请
func Apply(userId int, companyId int64, mobile, email string, applyInfo userReq.ApplyReq) (ybApplyRecord *yb_apply_record.YbApplyRecord, err error) {
	sellerName := ``
	status := `潜在用户`
	companyName := applyInfo.CompanyName

	tmpmYbApplyRecord, err := yb_apply_record.GetLastNotOpRecordByUserId(userId)
	if err == nil {
		ybApplyRecord = tmpmYbApplyRecord // 申请来源每一种只存在一条数据
		return
	} else {
		if err != utils.ErrNoRow {
			return
		}
	}

	// 联系人信息
	wxUserInfo, err := wx_user.GetByUserId(userId)
	if err != nil {
		return
	}

	if companyId > 1 {
		//客户信息
		companyInfo, tmpErr := company.GetByCompanyId(companyId)
		if tmpErr != nil {
			err = tmpErr
			return
		}
		companyName = companyInfo.CompanyName

		//客户产品权限
		companyProductList, tmpErr := company_product.GetListByCompanyId(companyId)
		if tmpErr != nil {
			err = tmpErr
			return
		}
		sellerNameList := make([]string, 0)
		statusList := make([]string, 0)
		for _, companyProductInfo := range companyProductList {
			if companyProductInfo.ProductID == 2 && status == "潜在用户" {
				status = "权益用户"
			}
			if companyProductInfo.ProductID == 1 {
				sellerName = companyProductInfo.SellerName
				status = companyProductInfo.Status
				if companyProductInfo.IsSuspend == 1 {
					status = `试用暂停`
				}
			}
		}
		if len(sellerNameList) > 0 && len(statusList) > 0 {
			sellerName = strings.Join(sellerNameList, ",")
			status = strings.Join(statusList, ",")
		}
	}
	ybApplyRecord = &yb_apply_record.YbApplyRecord{
		UserID:          userId,
		BusinessCardURL: applyInfo.BusinessCardUrl,
		RealName:        applyInfo.RealName,
		CompanyName:     applyInfo.CompanyName,
		Mobile:          mobile,
		Email:           email,
		Permission:      applyInfo.Permission,
		SellerName:      sellerName,
		Status:          status,
		CompanyIDPay:    int(companyId),
		CompanyNamePay:  companyName,
		CreateTime:      time.Now(),
		Source:          applyInfo.Source,
		SourceAgent:     applyInfo.SourceAgent,
		FromPage:        applyInfo.FromPage,
	}
	err = ybApplyRecord.Create()
	if err != nil {
		return
	}

	// 修改客户信息
	wxUserInfo.RealName = applyInfo.RealName
	wxUserInfo.Note = applyInfo.CompanyName
	wxUserInfo.IsNote = 1

	applyMethod := wxUserInfo.ApplyMethod //0:未申请，1:已付费客户申请试用，2:非客户申请试用
	applyMethod = 2
	if sellerName != "" {
		applyMethod = 1
	}
	wxUserInfo.ApplyMethod = applyMethod

	_ = wxUserInfo.Update([]string{"RealName", "Note", "IsNote", "ApplyMethod"})
	return
}

// GetUserTabBar 获取用户小程序TabBar
func GetUserTabBar(userInfo user.UserInfo, version string) (list []string, err error) {
	where := make(map[string]interface{})
	where["version"] = version
	where["position"] = 2
	where["is_show"] = 1
	tabs, e := yb_index_tab.GetListByCondition(where)
	if e != nil {
		err = errors.New("获取TabBar失败, Err: " + e.Error())
		return
	}
	if len(tabs) == 0 {
		return
	}
	authOk := false
	companyProduct, e := company_product.GetByCompany2ProductId(userInfo.CompanyID, 1)
	if e != nil && e != utils.ErrNoRow {
		err = errors.New("获取客户信息失败, Err: " + e.Error())
		return
	}
	if companyProduct != nil && companyProduct.Status != "" {
		if strings.Contains("永续,正式", companyProduct.Status) {
			authOk = true
		}
	}
	for _, v := range tabs {
		if v.AuthCheck == 1 && !authOk {
			continue
		}
		list = append(list, v.Mark)
	}
	return
}

// PcSendSmsCode 发送手机短信
func PcSendSmsCode(mobile, areaNum string) (err error, errMsg string) {
	cacheKey := utils.HONGZEYB_ + "REPORT_SMS_CODE_PC:GetSmsCode:" + areaNum + ":" + mobile
	smsCodeStr, _ := global.Redis.Get(context.TODO(), cacheKey).Result()
	if smsCodeStr != "" {
		err = errors.New("请勿频繁发送验证码")
		return
	}

	if mobile == "" {
		err = errors.New("请输入手机号")
		return
	}
	msgCode := utils.GetRandDigit(4)
	var result bool
	if areaNum == "86" || areaNum == "" || areaNum == "0" {
		//国内的短信
		result = services.SendSmsCode(mobile, msgCode)
	} else {
		//国际短信
		result = services.SendSmsCodeGj(mobile, msgCode, areaNum)
	}
	//发送成功
	if result {
		// 验证码存库
		item := &msg_code.MsgCode{
			Mobile:          mobile,
			Code:            msgCode,
			ExpiredIn:       time.Now().Add(15 * time.Minute).Unix(),
			Enabled:         1,
			CreatedTime:     time.Time{},
			LastUpdatedTime: time.Time{},
		}
		err = item.Create()
		global.Redis.Set(context.TODO(), cacheKey, msgCode, 60*time.Second)
	} else {
		err = errors.New("短信发送失败")
	}
	return
}

// PcSendEmailCode 发送邮件
func PcSendEmailCode(email string) (err error, errMsg string) {
	if email == "" {
		err = errors.New("请输入邮箱地址")
		return
	}
	if !utils.ValidateEmailFormatat(email) {
		err = errors.New("邮箱格式错误，请重新输入")
		return
	}
	cacheKey := utils.HONGZEYB_ + "REPORT_SMS_CODE_PC:PcSendEmailCode:" + email
	smsCodeStr, _ := global.Redis.Get(context.TODO(), cacheKey).Result()
	if smsCodeStr != "" {
		err = errors.New("请勿频繁发送验证码")
		return
	}

	msgCode := utils.GetRandDigit(4)
	content := "尊敬的用户：</br>您好，感谢您使用弘则研究，您正在进行邮箱验证，本次请求的验证码为：" + msgCode + "（为了保障您账号的安全性，请在15分钟内完成验证。）</br>弘则研究团队 </br>" + time.Now().Format(utils.FormatDateCN)
	title := "弘则研究登陆验证"
	//发送邮件
	result, err := services.SendEmailByHz(title, content, email)

	if result {
		item := &msg_code.MsgCode{
			Mobile:          email,
			Code:            msgCode,
			ExpiredIn:       time.Now().Add(15 * time.Minute).Unix(),
			Enabled:         1,
			CreatedTime:     time.Time{},
			LastUpdatedTime: time.Time{},
		}
		err = item.Create()
		global.Redis.Set(context.TODO(), cacheKey, msgCode, 60*time.Second)
	} else {
		err = errors.New("发送失败")
	}

	return
}

// TopTab
type TopTab struct {
	Tab  string `json:"tab" description:"选项卡名称"`
	Mark string `json:"mark" description:"选项卡标识"`
	Icon string `json:"icon" description:"icon图标"`
	Sort int    `json:"sort" description:"排序"`
}

// GetTopTab 获取小程序首页顶部选项卡
func GetTopTab(userInfo user.UserInfo, version string) (list []*TopTab, err error) {
	where := make(map[string]interface{})
	where["version"] = version
	where["position"] = 1
	where["is_show"] = 1
	tabs, e := yb_index_tab.GetListByCondition(where)
	if e != nil {
		err = errors.New("获取TabBar失败, Err: " + e.Error())
		return
	}
	if len(tabs) == 0 {
		return
	}
	authOk := false
	companyProduct, e := company_product.GetByCompany2ProductId(userInfo.CompanyID, 1)
	if e != nil && e != utils.ErrNoRow {
		err = errors.New("获取客户信息失败, Err: " + e.Error())
		return
	}
	if companyProduct != nil && companyProduct.Status != "" {
		if strings.Contains("永续,正式", companyProduct.Status) {
			authOk = true
		}
	}
	list = make([]*TopTab, 0)
	for _, v := range tabs {
		if v.AuthCheck == 1 && !authOk {
			continue
		}
		list = append(list, &TopTab{
			Tab:  v.Tab,
			Mark: v.Mark,
			Icon: v.DefaultIcon,
			Sort: v.Sort,
		})
	}
	return
}

// GetUserIdentity 获取用户身份（内部员工、研究员、语音管理员）
func GetUserIdentity(companyId int, mobile, email string) (isInner, isResearcher, isVoiceAdmin int, adminInfo *admin2.Admin, err error) {
	if companyId != utils.HzCompanyId {
		return
	}
	if mobile == "" && email == "" {
		return
	}
	var e error
	// 通过手机号/邮箱获取管理员信息
	if mobile != "" {
		adminInfo, e = admin2.GetAdminByMobile(mobile)
		if e != nil && e != utils.ErrNoRow {
			return
		}
	} else {
		adminInfo, e = admin2.GetAdminByEmail(email)
		if e != nil && e != utils.ErrNoRow {
			return
		}
	}
	// 仅内部员工才判断研究员、语音管理员身份
	if adminInfo != nil && adminInfo.AdminID > 0 && adminInfo.Enabled == 1 {
		isInner = 1
		// 研究员
		researchGroupList, e := research_variety_tag_relation.GetResearchVarietyTagRelationByAdminId(int(adminInfo.AdminID))
		if e != nil {
			err = errors.New("用户研究员信息有误")
			return
		}
		if len(researchGroupList) > 0 {
			isResearcher = 1
		}
		// 语音管理员
		voiceAdmin, e := sys_role_admin.GetVoiceAdmin(int(adminInfo.AdminID))
		if e != nil && e != utils.ErrNoRow {
			err = errors.New("用户语音管理员信息有误")
			return
		}
		if voiceAdmin != nil && voiceAdmin.Id > 0 {
			isVoiceAdmin = 1
		}
	}
	return
}
