package controllers

import (
	"XT_New/enums"
	"XT_New/models"
	"XT_New/service"
	"XT_New/utils"
	"fmt"
	"github.com/astaxie/beego"
	"net/url"
	"regexp"
	"strconv"
	"strings"
)

func VerifyUserLoginControllerRegistRouters() {
	beego.Router("/login", &VerifyUserLoginController{}, "get:Login")
	beego.Router("/logout", &VerifyUserLoginController{}, "get,post:Logout")
	beego.Router("/handle_error", &VerifyUserLoginController{}, "get:HandleError")

	beego.Router("/api/token/verify", &VerifyUserLoginAPIController{}, "post:VerifyToken")
	beego.Router("/api/admin/edit_info", &VerifyUserLoginAPIController{}, "post:EditAdminUserInfo")

	beego.Router("/api/password/code", &PersonAPIController{}, "post:CodeOfModifyPwd")
	beego.Router("/api/password/modify", &PersonAPIController{}, "post:ModifyPwd")
}

type VerifyUserLoginController struct {
	BaseViewController
}

// /login [get]
// @param token?:string
// @param relogin?:bool
func (this *VerifyUserLoginController) Login() {
	token := this.Ctx.Input.Query("token")
	if len(token) > 0 { // 带 token 参数的一般是从 SSO 回调回来的
		utils.TraceLog("SSO Login 回调: token=%v", token)
		xtFrontEndDomain := beego.AppConfig.String("front_end_domain") + "?lt=" + token
		this.Redirect302(xtFrontEndDomain)

	} else {
		relogin, _ := this.GetBool("relogin", false)
		returnURL := url.QueryEscape(fmt.Sprintf("%v%v", beego.AppConfig.String("httpdomain"), this.Ctx.Request.RequestURI))
		ssoDomain := beego.AppConfig.String("sso_domain")
		ssoLoginURL := fmt.Sprintf("%v/login?returnurl=%v&app_type=3&relogin=%v", ssoDomain, returnURL, relogin)
		this.Redirect302(ssoLoginURL)
	}
}

// /logout [get/post]
func (this *VerifyUserLoginController) Logout() {
	if this.Ctx.Request.Method == "GET" {
		this.DelSession("admin_user_info")
		this.Redirect302(fmt.Sprintf("%v/logout", beego.AppConfig.String("sso_domain")))
	} else if this.Ctx.Request.Method == "POST" {
		this.DelSession("admin_user_info")
	}
}

// /handle_error [get]
// @param code:int
func (this *VerifyUserLoginController) HandleError() {
	code, _ := this.GetInt("code")
	if code == enums.ErrorCodeNeverCreateTypeApp {
		ssoDomain := beego.AppConfig.String("sso_domain")
		createAppURL := fmt.Sprintf("%v/org/app/create", ssoDomain)
		this.Redirect302(createAppURL)

	} else if code == enums.ErrorCodeContactSuperAdminCreateTypeApp {
		ssoDomain := beego.AppConfig.String("sso_domain")
		hitURL := fmt.Sprintf("%v/create_app_hint", ssoDomain)
		this.Redirect302(hitURL)

	} else {
		this.Abort404()
	}
}

type VerifyUserLoginAPIController struct {
	BaseAPIController
}

// /api/token/verify [post]
// @param token:string
func (this *VerifyUserLoginAPIController) VerifyToken() {
	if this.Ctx.Request.Method == "OPTIONS" {
		this.Abort("200")

	} else {
		token := this.GetString("token")
		utils.TraceLog("token: %v", token)
		if len(token) == 0 {
			this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
			return
		}

		ip := utils.GetIP(this.Ctx.Request)
		fmt.Println("ip是什么", ip)
		sessionID := this.Ctx.GetCookie("s")
		fmt.Println("sessionID", sessionID)
		utils.TraceLog("Request: %v", this.Ctx.Request)
		utils.TraceLog("cookie session id: %v", sessionID)
		adminUserInfo, err, errCode := service.VerifyToken(token, ip, sessionID)
		fmt.Println("错误是什么", err)
		fmt.Println("errCode是什么", errCode)
		if err != nil {
			if errCode == 903 { // 未创建应用
				this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeNeverCreateTypeApp)

			} else if errCode == 904 { // 联系超管来开通
				this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeContactSuperAdminCreateTypeApp)

			} else {
				utils.ErrorLog("令牌验证失败：%v", err)
				this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeInvalidToken)
			}
			return

		} else {
			adminUser := adminUserInfo.AdminUser
			appRole := adminUserInfo.AppRoles[adminUserInfo.CurrentAppId]
			userInfo := map[string]interface{}{
				"id":         adminUser.Id,
				"mobile":     adminUser.Mobile,
				"user_name":  appRole.UserName,
				"avatar":     appRole.Avatar,
				"intro":      appRole.Intro,
				"user_type":  appRole.UserType,
				"user_title": appRole.UserTitle,
			}
			curOrg := adminUserInfo.Orgs[adminUserInfo.CurrentOrgId]
			org := map[string]interface{}{
				"id":             curOrg.Id,
				"org_name":       curOrg.OrgName,
				"org_short_name": curOrg.OrgShortName,
				"org_intro":      curOrg.OrgIntroduction,
				"org_logo":       curOrg.OrgLogo,
				"province":       curOrg.Province,
				"city":           curOrg.City,
				"district":       curOrg.District,
				"address":        curOrg.Address,
			}

			var didRegistedForSCRM bool = false
			var didRegistedForCDM bool = false
			var didRegistedForMall bool = false

			tempInfo, _ := service.GetOrgInfoTemplate(curOrg.Id)
			fmt.Println("teimpInfo", tempInfo)
			template_info := map[string]interface{}{
				"id":          tempInfo.ID,
				"org_id":      tempInfo.OrgId,
				"template_id": tempInfo.TemplateId,
			}
			var FiledList []*models.FiledConfig

			FiledList, _ = service.FindFiledByOrgId(curOrg.Id)
			if len(FiledList) == 0 {
				err := service.BatchInsertFiledConfig(curOrg.Id)
				if err == nil {
					FiledList, _ = service.FindFiledByOrgId(curOrg.Id)

				} else {
					utils.ErrorLog("字段批量插入失败：%v", err)
				}
			}

			var pruviews []*models.Purview
			var curAppUrlfors []string
			if len(curAppUrlfors) == 0 {
				if adminUser.Id == curOrg.Creator { //超级管理员
					urlfors, _, _ := service.GetSuperAdminUsersPurviewTreeAndUrlfors(3)
					didRegistedForSCRM = true
					didRegistedForCDM = true
					didRegistedForMall = true

					//urlfors, _, _ := service.GetSuperAdminUsersPurviewTreeAndUrlfors(4)
					//urlfors, _, _ := service.GetSuperAdminUsersPurviewTreeAndUrlfors(5)
					//urlfors, _, _ := service.GetSuperAdminUsersPurviewTreeAndUrlfors(6)

					curAppUrlfors = urlfors
				} else {
					appRole, _ := service.FindAdminUserIDA(appRole.Id)
					if appRole.Id > 0 && len(appRole.RoleIds) > 0 {
						role_arr := strings.Split(appRole.RoleIds, ",")
						var ids string
						for _, role_id := range role_arr {
							id, _ := strconv.ParseInt(role_id, 10, 64)
							role, _ := service.GetRoleByRoleID(id)
							var system_ids = ""
							if role.RoleName == "子管理员" && role.IsSystem > 0 {
								purviews, _ := service.GetSystemPurview()
								for _, purview := range purviews {
									if len(system_ids) == 0 {
										system_ids = strconv.FormatInt(purview.Id, 10)
									} else {
										system_ids = system_ids + "," + strconv.FormatInt(purview.Id, 10)
									}
								}
							}
							purview_ids, _ := service.GetRolePurviewIds(id)
							if len(ids) == 0 {
								ids = purview_ids
							} else {
								ids = ids + "," + purview_ids
							}

							if len(system_ids) > 0 {
								ids = ids + "," + system_ids
							}
						}
						if len(ids) != 0 {
							pruviews, _ = service.GetPurviewById(CompressStr(ids))
							for _, item := range pruviews {
								if item.Module == 3 && item.Parentid > 0 {
									fmt.Println(item.Urlfor)
									curAppUrlfors = append(curAppUrlfors, item.Urlfor)
								}
							}
						} else {

							curAppUrlfors = append(curAppUrlfors, "")
						}
					} else {
						curAppUrlfors = append(curAppUrlfors, "")

					}
				}
			}

			for _, item := range pruviews {
				if item.Module == 6 {
					didRegistedForSCRM = true
				}
				if item.Module == 4 {
					didRegistedForCDM = true
				}
				if item.Module == 7 {
					didRegistedForMall = true
				}
			}

			if adminUser.Id == curOrg.Creator { //超级管理员
				didRegistedForSCRM = true
				didRegistedForCDM = true
				didRegistedForMall = true

			}

			subscibe, _ := service.GetOrgSubscibe(adminUserInfo.CurrentOrgId)

			this.SetSession("admin_user_info", adminUserInfo)

			this.ServeSuccessJSON(map[string]interface{}{
				"user":            userInfo,
				"org":             org,
				"urlfors":         curAppUrlfors,
				"current_org_id":  adminUserInfo.CurrentOrgId,
				"current_app_id":  adminUserInfo.CurrentAppId,
				"subscibe":        subscibe,
				"scrm_role_exist": didRegistedForSCRM,
				"cdm_role_exist":  didRegistedForCDM,
				"mall_role_exist": didRegistedForMall,
				"template_info":   template_info,
				"fileds":          FiledList,
			})
			return
		}
	}
}

// /api/admin/edit_info [post]
// @param avatar:string
// @param name:string
// @param opwd?:string 没有原始密码的时候，认为不修改密码
// @param npwd?:string
func (this *VerifyUserLoginAPIController) EditAdminUserInfo() {
	adminUserInfo := this.GetAdminUserInfo()

	avatar := this.GetString("avatar")
	name := this.GetString("name")
	if len(name) == 0 {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeMissingUserName)
		return
	}
	// oldPwd := this.GetString("opwd")
	// newPwd := this.GetString("npwd")
	// modifyPwd := len(oldPwd) != 0
	// if modifyPwd {
	// 	if len(newPwd) == 0 {
	// 		this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodePasswordEmpty)
	// 		this.ServeJSON()
	// 		return
	// 	}
	// 	pwdRight, err := service.IsPasswordRight(adminUserInfo.AdminUser.Id, oldPwd)
	// 	if err != nil {
	// 		utils.ErrorLog("判断旧密码是否错误失败：%v", err)
	// 		this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeDataException)
	// 		this.ServeJSON()
	// 		return
	// 	}
	// 	if !pwdRight {
	// 		this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeOldPasswordWrong)
	// 		this.ServeJSON()
	// 		return
	// 	}
	// } else {
	// 	newPwd = ""
	// }
	modifyErr := service.ModifyAdminUserInfo(adminUserInfo.AdminUser.Id, adminUserInfo.CurrentOrgId, adminUserInfo.CurrentAppId, name, avatar, "")
	if modifyErr != nil {
		this.ErrorLog("修改个人信息失败：%v", modifyErr)
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDBUpdate)

	} else {
		appRole := adminUserInfo.AppRoles[adminUserInfo.CurrentAppId]
		appRole.UserName = name
		appRole.Avatar = avatar
		this.ServeSuccessJSON(nil)
	}
}

type PersonAPIController struct {
	BaseAuthAPIController
}

// /api/password/code [post]
func (this *PersonAPIController) CodeOfModifyPwd() {
	adminUserInfo := this.GetAdminUserInfo()
	mobile := adminUserInfo.AdminUser.Mobile
	if err := service.SMSSendVerificationCode(mobile); err != nil {
		utils.ErrorLog("修改密码发送验证码失败:%v", err)
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
		return
	} else {
		this.ServeSuccessJSON(map[string]interface{}{
			"msg": "短信发送成功,有效期为10分钟",
		})
	}
}

// /api/password/modify [post]
// @param password:string
// @param code:string
func (this *PersonAPIController) ModifyPwd() {
	new_pwd := this.GetString("password")
	code := this.GetString("code")
	if len(new_pwd) == 0 || len(code) == 0 {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
		return
	}

	adminUserInfo := this.GetAdminUserInfo()
	mobile := adminUserInfo.AdminUser.Mobile

	redisClient := service.RedisClient()
	defer redisClient.Close()
	cachedCode, err := redisClient.Get("xt_modify_pwd_" + mobile).Result()
	if err != nil {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeAccountOrVerCodeWrong)
		return
	}
	if code != cachedCode {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeAccountOrVerCodeWrong)
		return
	}

	if modifyErr := service.ModifyPassword(adminUserInfo.AdminUser.Id, new_pwd); modifyErr != nil {
		this.ErrorLog("修改密码失败:%v", modifyErr)
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
		return
	}

	// 清除验证码
	redisClient.Del("xt_modify_pwd_" + mobile)
	this.ServeSuccessJSON(map[string]interface{}{
		"msg": "密码已修改",
	})
}

func CompressStr(str string) string {
	if str == "" {
		return ""
	}
	//匹配一个或多个空白符的正则表达式
	reg := regexp.MustCompile("\\s+")
	return reg.ReplaceAllString(str, "")
}
