package roadshow

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/rdlucklib/rdluck_tools/http"
	"hongze/hz_crm_api/models/roadshow"
	"hongze/hz_crm_api/models/system"
	"hongze/hz_crm_api/services/alarm_msg"
	"hongze/hz_crm_api/utils"
	"io/ioutil"
	netHttp "net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
)

type SyncCalendarFromShanghaiRecord struct {
	UserPhone string `description:"手机号"`
	StartDate string `description:"开始时间"`
	EndDate   string `description:"结束时间"`
}

// 上海路演数据同步到自系统 从Redis获取
func InsertSyncCalendarFromShanghai() {
	var err error
	defer func() {
		if err != nil {
			go alarm_msg.SendAlarmMsg("上海路演数据同步到自系统 失败；InsertSyncCalendarFromShanghai ERR："+err.Error(), 3)
		}
	}()
	for {
		utils.Rc.Brpop(utils.CACHE_KEY_SHANG_HAI_RS_CALENDAR_API, func(b []byte) {
			record := new(SyncCalendarFromShanghaiRecord)
			if err := json.Unmarshal(b, &record); err != nil {
				fmt.Println("json unmarshal wrong!")
			}
			//fmt.Println(record.UserPhone)
			_ = SyncCalendarFromShanghai(record.UserPhone, record.StartDate, record.EndDate)
		})
	}
}

// 上海路演数据同步到自系统请求放到Redis
func InsertSyncCalendarFromShanghaiLPush(userPhone, startDate, endDate string) bool {
	log := &SyncCalendarFromShanghaiRecord{UserPhone: userPhone, StartDate: startDate, EndDate: endDate}
	if utils.Re == nil {
		err := utils.Rc.LPush(utils.CACHE_KEY_SHANG_HAI_RS_CALENDAR_API, log)
		if err != nil {
			fmt.Println(err)
			go alarm_msg.SendAlarmMsg("上海路演数据同步到自系统 失败；InsertSyncCalendarFromShanghaiLPush ERR："+err.Error(), 3)
		}
		return true
	}
	return false
}

// getAccessToken token内部请求接口
func getAccessToken() (tokenData roadshow.TokenData, err error) {
	defer func() {
		if err != nil {
			go alarm_msg.SendAlarmMsg("更新上海的token失败；ERR："+err.Error(), 3)
			//go utils.SendEmail(utils.APPNAME+"更新上海的token失败："+time.Now().Format("2006-01-02 15:04:05"), err.Error(), utils.EmailSendToUsers)
		}
	}()
	getUrl := fmt.Sprintf(utils.CRM_OPEN_API_URL+"/v1/auth/getAccessToken?app_key=%s&app_secret=%s", utils.CRM_OPEN_API_APP_KEY, utils.CRM_OPEN_API_APP_SECRET)
	body, err := http.Get(getUrl)
	if err != nil {
		err = errors.New("NewRequest Err:" + err.Error())
		return
	}

	var tokenResp roadshow.GetTokenResp
	err = json.Unmarshal(body, &tokenResp)
	if err != nil {
		err = errors.New("Unmarshal Err:" + err.Error())
		return
	}
	if tokenResp.Code != 1 {
		err = errors.New("getAccessToken err:" + tokenResp.Msg)
		return
	}
	tokenData = tokenResp.TokenData
	return
}

// refreshAccessToken 强制刷新获取accessToken
func refreshAccessToken() (token string, err error) {
	defer func() {
		if err != nil {
			go alarm_msg.SendAlarmMsg("刷新上海的token失败；ERR："+err.Error(), 3)
			//go utils.SendEmail(utils.APPNAME+"刷新上海的token失败："+time.Now().Format("2006-01-02 15:04:05"), err.Error(), utils.EmailSendToUsers)
		}
	}()
	tokenInfo, tmpErr := getAccessToken()
	if tmpErr != nil {
		err = tmpErr
		return
	}
	token = tokenInfo.AccessToken

	//token存入redis
	err = utils.Rc.Put("SH_ACCESS_TOKEN", token, time.Duration(tokenInfo.ExpireIn-600)*time.Second)
	if err != nil {
		go alarm_msg.SendAlarmMsg("获取上海的token失败；上海token存入redis失败，ERR："+err.Error(), 3)
		//go utils.SendEmail(utils.APPNAME+"获取上海的token失败："+time.Now().Format("2006-01-02 15:04:05"), "上海token存入redis失败：", utils.EmailSendToUsers)
	}
	return
}

// getCalendarFrom 获取上海方的路演活动列表
func getCalendarFrom(userPhone, startDate, endDate string) (list []roadshow.UserCalendar, err error) {
	exUrl := utils.CRM_OPEN_API_URL + "/v1/calendar/userCalendarList"
	form := url.Values{
		"user_phone": {userPhone},
		"start_time": {startDate},
		"end_time":   {endDate},
	}
	body, err := getCurl(exUrl, form, 0)
	if err != nil {
		err = errors.New("NewRequest Err:" + err.Error())
		return
	}
	var userCalendarList roadshow.UserCalendarList
	err = json.Unmarshal(body, &userCalendarList)
	if err != nil {
		err = errors.New("Unmarshal Err:" + err.Error())
		return
	}
	list = userCalendarList.Data

	//fmt.Println(response)
	//userCalendarList := response.([]interface{})
	//
	//for _, userCalendar := range userCalendarList {
	//	fmt.Println(userCalendar)
	//	fmt.Printf("type :%T;\n", userCalendar)
	//	//list = append(list, userCalendar.(roadshow.UserCalendar))
	//}
	//fmt.Println(userCalendarList)

	//list = userCalendarList
	return
}

// creatSHCalendar 新增上海日历活动
func creatSHCalendar(userPhone, toUserPhone, content, startTime, endTime string, calendarType int8, selfCalendarId int) (err error, errMsg string) {
	logMsg := ``
	defer func() {
		if err != nil {
			if logMsg != `` {
				errMsg = logMsg
			}
		}
	}()
	finalUrl := utils.CRM_OPEN_API_URL + "/v1/Calendar/create"

	form := url.Values{
		"user_phone":    {userPhone},
		"to_user_phone": {toUserPhone},
		"content":       {content},
		"start_time":    {startTime},
		"end_time":      {endTime},
	}
	//发送创建请求
	body, err, logMsg := postCurl(finalUrl, form, 0)
	if err != nil {
		err = errors.New("NewRequest Err:" + err.Error())
		return
	}
	var creatSHCalendarResp roadshow.CreatSHCalendarResp
	err = json.Unmarshal(body, &creatSHCalendarResp)
	if err != nil {
		err = errors.New("Unmarshal Err:" + err.Error())
		return
	}
	calendar := creatSHCalendarResp.Data

	//上海系统id
	sThirdId := calendar.CalendarID
	thirdId, err := strconv.Atoi(sThirdId)
	if err != nil {
		err = errors.New("string to int Err:" + err.Error())
		return
	}
	// 添加自系统与上海系统的路演关系
	relationItem := roadshow.RsCalendarRelation{
		UserPhone:        userPhone,
		CalendarType:     calendarType,
		SelfCalendarId:   selfCalendarId,
		ThirdCalendarId:  thirdId,
		Title:            content,
		ResearcherMobile: toUserPhone,
		ModifyTime:       time.Now(),
		CreateTime:       time.Now(),
	}
	_, err = roadshow.AddRsCalendarRelation(&relationItem)
	if err != nil {
		err = errors.New("AddRsCalendarRelation Err:" + err.Error())
		fmt.Println(err)
		return
	}
	return
}

// updateSHCalendar 内部函数，只用于发送修改上海日历的http请求
func updateSHCalendar(thirdCalendarId, researcherMobile, content, startTime, endTime string) (calendarResp roadshow.CreatSHCalendarResp, err error) {
	finalUrl := utils.CRM_OPEN_API_URL + "/v1/Calendar/update"

	form := url.Values{
		"calendar_id":   {thirdCalendarId},
		"to_user_phone": {researcherMobile},
		"content":       {content},
		"start_time":    {startTime},
		"end_time":      {endTime},
	}
	//发送创建请求
	_, err, _ = postCurl(finalUrl, form, 0)
	if err != nil {
		err = errors.New("NewRequest Err:" + err.Error())
		return
	}
	return
}

// deleteSHCalendar 删除上海方的路演
func deleteSHCalendar(userPhone string, calendarId int) (err error) {
	finalUrl := utils.CRM_OPEN_API_URL + "/v1/Calendar/delete"

	form := url.Values{
		"user_phone":  {userPhone},
		"calendar_id": {fmt.Sprintf("%v", calendarId)},
	}
	//发送创建请求
	_, err, _ = postCurl(finalUrl, form, 0)
	if err != nil {
		err = errors.New("NewRequest Err:" + err.Error())
		return
	}
	return
}

// ShResponse 上海数据返回结构体
type ShResponse struct {
	Code int         `json:"code" description:"1：正常返回；4001：token失效"`
	Msg  string      `json:"msg" description:"文字描述"`
	Time int         `json:"time" description:"时间戳"`
	Data interface{} `json:"data" description:"业务数据"`
}

// getCurl get请求上海接口
func getCurl(urlStr string, params url.Values, num int) (body []byte, err error) {
	if err != nil {
		go alarm_msg.SendAlarmMsg("get请求上海接口失败，ERR："+err.Error(), 3)
		//go utils.SendEmail(utils.APPNAME+"get请求上海接口失败："+time.Now().Format("2006-01-02 15:04:05"), "get请求上海接口失败："+err.Error(), utils.EmailSendToUsers)
	}
	token, err := GetAccessToken(false)
	if err != nil {
		return
	}
	params.Add("access_token", token)
	getUrl := urlStr + "?" + params.Encode()
	body, err = http.Get(getUrl)
	if err != nil {
		utils.FileLog.Info(fmt.Sprint("get Err:", err.Error(), ";url:", getUrl, ";params:", params.Encode(), ";response:", string(body)))
		err = errors.New("NewRequest Err:" + err.Error())
		return
	}

	var response ShResponse
	err = json.Unmarshal(body, &response)
	if err != nil {
		utils.FileLog.Info(fmt.Sprint("get Err:", err.Error(), ";url:", getUrl, ";params:", params.Encode(), ";response:", string(body)))
		err = errors.New("Unmarshal Err:" + err.Error())
		return
	}

	//如果是token失效，同时只是第一次请求（没有尝试强制刷新token，那么重新请求）
	if response.Code == 4001 && num <= 0 {
		utils.FileLog.Info(fmt.Sprint("get data err", ";url:", getUrl, ";params:", params.Encode(), ";response:", string(body)))

		//token失效
		_, tmpErr := refreshAccessToken()
		if tmpErr != nil {
			err = tmpErr
		}
		num++
		params.Del("access_token")
		return getCurl(urlStr, params, num)
	} else if response.Code != 1 {
		utils.FileLog.Info(fmt.Sprint("get data err", ";url:", getUrl, ";params:", params.Encode(), ";response:", string(body)))
		err = errors.New(response.Msg)
		return
	}
	return
}

// postCurl post请求上海接口
func postCurl(urlStr string, form url.Values, num int) (body []byte, err error, errMsg string) {
	logMsg := ``
	defer func() {
		if err != nil {
			if logMsg != `` {
				errMsg = logMsg
				go alarm_msg.SendAlarmMsg("post请求上海接口失败，ERR："+err.Error()+";errMsg:"+errMsg, 3)
				//go utils.SendEmail(utils.APPNAME+"post请求上海接口失败："+time.Now().Format("2006-01-02 15:04:05"), "post请求上海接口失败："+errMsg, utils.EmailSendToUsers)
			}
		}
	}()
	token, err := GetAccessToken(false)
	if err != nil {
		return
	}
	finalUrl := urlStr + "?access_token=" + token

	//发送创建请求
	resp, err := netHttp.PostForm(finalUrl, form)
	if err != nil {
		err = errors.New("NewRequest Err:" + err.Error())
		return
	}

	defer resp.Body.Close()

	//解析resp并且存入关联表
	body, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		logMsg = fmt.Sprint("post err; request:", form.Encode(), "; errMsg:", err.Error())
		utils.FileLog.Info(logMsg)
		return
	}
	logMsg = fmt.Sprint("post request:", form.Encode(), "; response:", string(body))
	utils.FileLog.Info(logMsg)

	var response ShResponse
	err = json.Unmarshal(body, &response)
	if err != nil {
		utils.FileLog.Info("post Err:", err.Error(), ";url:", finalUrl, ";params:", form.Encode(), ";response:", string(body))
		err = errors.New("Unmarshal Err:" + err.Error())
		return
	}
	utils.FileLog.Info(fmt.Sprint("post request url:", finalUrl, ";params:", form.Encode(), ";response:", string(body)))

	//如果是token失效，同时只是第一次请求（没有尝试强制刷新token，那么重新请求）
	if response.Code == 4001 && num <= 0 {
		//token失效
		_, tmpErr := refreshAccessToken()
		if tmpErr != nil {
			err = tmpErr
		}
		num++
		return postCurl(urlStr, form, num)
	} else if response.Code != 1 {
		utils.FileLog.Info(fmt.Sprint("post data err", ";url:", finalUrl, ";params:", form.Encode(), ";response:", string(body)))
		err = errors.New(response.Msg)
		return
	}
	return
}

// GetAccessToken 获取accessToken
func GetAccessToken(isRefresh bool) (token string, err error) {
	defer func() {
		if err != nil {
			go alarm_msg.SendAlarmMsg("获取上海的token失败，ERR："+err.Error(), 3)
			//go utils.SendEmail(utils.APPNAME+"获取上海的token失败："+time.Now().Format("2006-01-02 15:04:05"), err.Error(), utils.EmailSendToUsers)
		}
	}()
	token, redisErr := utils.Rc.RedisString("SH_ACCESS_TOKEN")
	//如果从redis中accessToken 获取失败或者token为空了，再或者需要强制刷新了，那么重新获取accessToken
	if redisErr != nil || token == `` || isRefresh {
		return refreshAccessToken()
	}
	return
}

// CalendarToSH 创建活动时同步上海的前置函数
func CalendarToSH(rsCalendar roadshow.RsCalendar, researcher roadshow.RsCalendarResearcher) {
	var err error
	errMsg := ``
	defer func() {
		if err != nil {
			errMsg = err.Error() + ";" + errMsg
			go alarm_msg.SendAlarmMsg("新建上海研究员日历失败，ERR："+err.Error()+";errMsg:"+errMsg, 3)
			//go utils.SendEmail(utils.APPNAME+"新建上海研究员日历失败："+time.Now().Format("2006-01-02 15:04:05"), err.Error(), utils.EmailSendToUsers)
		}
	}()
	//redis获取创建者及研究员信息
	userInfo, err := getAdminInfoById(rsCalendar.SysUserId)
	if err != nil {
		utils.FileLog.Info("getAdminInfoById err: " + err.Error())
		return
	}
	researcherInfo, err := getAdminInfoById(researcher.ResearcherId)
	if err != nil {
		utils.FileLog.Info("getAdminInfoById err: " + err.Error())
		return
	}

	sTime, _ := time.ParseInLocation(utils.FormatDateTime, researcher.StartDate+" "+researcher.StartTime, time.Now().Location())
	startTime := sTime.Format("2006-01-02 15:04")
	eTime, _ := time.ParseInLocation(utils.FormatDateTime, researcher.EndDate+" "+researcher.EndTime, time.Now().Location())
	endTime := eTime.Format("2006-01-02 15:04")

	// 创建上海路演日程
	err, errMsg = creatSHCalendar(userInfo.Mobile, researcherInfo.Mobile, rsCalendar.Title, startTime, endTime, 1, researcher.RsCalendarResearcherId)
	if err != nil {
		utils.FileLog.Info("CreatSHCalendar err: " + err.Error())
		fmt.Println(err)
		return
	}

	// 更新路演与研究员关系表的同步字段
	whereParams := make(map[string]interface{})
	updateParams := make(map[string]interface{})
	whereParams["rs_calendar_researcher_id"] = researcher.RsCalendarResearcherId
	updateParams["is_synced"] = 1
	updateParams["modify_time"] = time.Now()
	err = roadshow.UpdateCalendarResearcher(whereParams, updateParams)
	if err != nil {
		utils.FileLog.Info("UpdateCalendarResearcher err: " + err.Error())
		fmt.Println("UpdateCalendarResearcher err: " + err.Error())
		return
	}

	// 更新路演的同步字段
	calWhereParams := make(map[string]interface{})
	calWhereParams["rs_calendar_id"] = rsCalendar.RsCalendarId
	err = roadshow.UpdateRsCalendar(calWhereParams, updateParams)
	if err != nil {
		utils.FileLog.Info("UpdateRsCalendar err: " + err.Error())
		fmt.Println("UpdateRsCalendar err: " + err.Error())
		return
	}
}

// MatterToSH 创建事项时同步上海的前置函数
func MatterToSH(matter roadshow.RsMatters) (err error) {
	errMsg := ``
	defer func() {
		if err != nil {
			errMsg = err.Error() + ";" + errMsg
			go alarm_msg.SendAlarmMsg("新建上海研究员事项失败，ERR："+err.Error()+";errMsg:"+errMsg, 3)
			//go utils.SendEmail(utils.APPNAME+"新建上海研究员事项失败："+time.Now().Format("2006-01-02 15:04:05"), err.Error(), utils.EmailSendToUsers)
		}
	}()
	//获取研究员信息
	researcherInfo, err := getAdminInfoById(matter.SysUserId)
	if err != nil {
		//utils.FileLog.Info("getAdminInfoById err: " + err.Error())
		return
	}

	sTime, _ := time.ParseInLocation(utils.FormatDateTime, matter.StartDate+" "+matter.StartTime, time.Now().Location())
	startTime := sTime.Format("2006-01-02 15:04")
	eTime, _ := time.ParseInLocation(utils.FormatDateTime, matter.EndDate+" "+matter.EndTime, time.Now().Location())
	endTime := eTime.Format("2006-01-02 15:04")
	err, errMsg = creatSHCalendar(researcherInfo.Mobile, researcherInfo.Mobile, matter.MatterContent, startTime, endTime, 2, matter.RsMattersId)
	if err != nil {
		return
	}

	// 修改事项的同步字段
	updateParams := make(map[string]interface{})
	whereParams := make(map[string]interface{})
	updateParams["is_synced"] = 1
	whereParams["rs_matters_id"] = matter.RsMattersId
	err = roadshow.UpdateRsMatters(whereParams, updateParams)
	if err != nil {
		err = fmt.Errorf("UpdateRsMatters err: " + err.Error())
	}
	return
}

// UpdateSHCalendar 更新上海日历活动
func UpdateSHCalendar(rsCalendarId, rsCalendarResearcherId int, activityType, roadshowType, activityCategory, roadshowPlatform, province, city string, calendarResearcherList []*roadshow.CalendarResearcher) (err error) {
	errMsg := ``
	defer func() {
		if errMsg != `` {
			if err != nil {
				errMsg = err.Error() + ";" + errMsg
			}
			go alarm_msg.SendAlarmMsg("更新上海日历活动失败，errMsg:"+errMsg, 3)
			//go utils.SendEmail(utils.APPNAME+"更新上海日历活动失败："+time.Now().Format("2006-01-02 15:04:05"), errMsg, utils.EmailSendToUsers)
		}
	}()

	//查询关联表获取信息
	var condition string
	var pars []interface{}
	condition = ` AND self_calendar_id = ?  and calendar_type = 1 `
	pars = append(pars, rsCalendarResearcherId)
	relationItem, err := roadshow.GetRelationByPars(condition, pars)
	if err != nil {
		err = errors.New("GetRelationByPars err:" + err.Error())
		fmt.Println(err)
		return
	}

	//需要同时修改创建人及研究员的日历（目前听说只有1个，先按一个处理吧）
	for _, researcher := range calendarResearcherList {
		sTime, _ := time.ParseInLocation(utils.FormatDateTime, researcher.StartDate+" "+researcher.StartTime, time.Now().Location())
		startTime := sTime.Format("2006-01-02 15:04")
		eTime, _ := time.ParseInLocation(utils.FormatDateTime, researcher.EndDate+" "+researcher.EndTime, time.Now().Location())
		endTime := eTime.Format("2006-01-02 15:04")
		title := getTitle(activityType, roadshowType, activityCategory, roadshowPlatform, province, city)
		//发送更新请求
		_, err = updateSHCalendar(fmt.Sprintf("%v", relationItem.ThirdCalendarId), relationItem.ResearcherMobile, title, startTime, endTime)
		if err != nil {
			errMsg += fmt.Sprint("更新研究员日历信息：", relationItem.ThirdCalendarId, ";err:"+err.Error(), ";")
		}

		//// 更新路演活动的信息
		//calWhereParams := make(map[string]interface{})
		//calWhereParams["rs_calendar_id"] = rsCalendarId
		//err = roadshow.UpdateRsCalendarRelation(calWhereParams, updateParams)
		//if err != nil {
		//	errMsg += fmt.Sprint("UpdateRsCalendar：", relationItem.ThirdCalendarId, ";err:"+err.Error(), ";")
		//	return
		//}
	}

	// 更新路演活动中 研究员的信息
	whereParams := make(map[string]interface{})
	updateParams := make(map[string]interface{})
	whereParams["rs_calendar_researcher_id"] = rsCalendarResearcherId
	updateParams["is_synced"] = 1
	updateParams["modify_time"] = time.Now()
	err = roadshow.UpdateCalendarResearcher(whereParams, updateParams)
	if err != nil {
		errMsg += fmt.Sprint("UpdateCalendarResearcher：", relationItem.ThirdCalendarId, ";err:"+err.Error(), ";")
		return
	}

	// 更新路演活动的信息
	calWhereParams := make(map[string]interface{})
	calWhereParams["rs_calendar_id"] = rsCalendarId
	err = roadshow.UpdateRsCalendar(calWhereParams, updateParams)
	if err != nil {
		errMsg += fmt.Sprint("UpdateRsCalendar：", relationItem.ThirdCalendarId, ";err:"+err.Error(), ";")
		return
	}

	return
}

// UpdateSHCalendarByMatter 更新上海日历活动
func UpdateSHCalendarByMatter(req roadshow.UpdateMattersReq) (err error) {
	defer func() {
		if err != nil {
			go alarm_msg.SendAlarmMsg("更新上海日历活动失败，Err："+err.Error(), 3)
			//go utils.SendEmail(utils.APPNAME+"更新上海日历活动失败："+time.Now().Format("2006-01-02 15:04:05"), err.Error(), utils.EmailSendToUsers)
		}
	}()
	if err != nil {
		return
	}

	//需要同时修改创建人及研究员的日历
	//查询关联表获取信息
	var condition string
	var pars []interface{}
	condition = ` AND self_calendar_id = ? and calendar_type = 2 `
	pars = append(pars, req.RsMattersId)
	relationItem, err := roadshow.GetRelationByPars(condition, pars)
	if err != nil {
		err = errors.New("GetRelationByPars err:" + err.Error())
		fmt.Println(err)
	}

	sTime, _ := time.ParseInLocation(utils.FormatDateTime, req.StartDate+" "+req.StartTime, time.Now().Location())
	startTime := sTime.Format("2006-01-02 15:04")
	eTime, _ := time.ParseInLocation(utils.FormatDateTime, req.EndDate+" "+req.EndTime, time.Now().Location())
	endTime := eTime.Format("2006-01-02 15:04")
	//发送更新请求

	_, err = updateSHCalendar(fmt.Sprintf("%v", relationItem.ThirdCalendarId), relationItem.ResearcherMobile, req.MatterContent, startTime, endTime)
	if err == nil {
		updateParams := make(map[string]interface{})
		whereParams := make(map[string]interface{})
		updateParams["is_synced"] = 1
		whereParams["rs_matters_id"] = req.RsMattersId
		err = roadshow.UpdateRsMatters(whereParams, updateParams)
		if err != nil {
			utils.FileLog.Info("UpdateRsMatters err: " + err.Error())
			fmt.Println("UpdateRsMatters err: " + err.Error())
			return
		}
	}
	return
}

// DeleteSHCalendar 删除上海日历活动
func DeleteSHCalendar(rsCalendarResearcherId int) (err error) {
	defer func() {
		if err != nil {
			go alarm_msg.SendAlarmMsg(fmt.Sprint("删除上海日历活动失败，关系id：", rsCalendarResearcherId, "；err:", err.Error()), 3)
			//go utils.SendEmail(utils.APPNAME+"删除上海日历活动失败："+time.Now().Format("2006-01-02 15:04:05"), fmt.Sprint("关系id：", rsCalendarResearcherId, ";err:", err.Error()), utils.EmailSendToUsers)
		}
	}()

	var condition string
	var pars []interface{}
	condition = ` AND self_calendar_id = ?  and calendar_type = 1 `
	pars = append(pars, rsCalendarResearcherId)
	relationItem, err := roadshow.GetRelationByPars(condition, pars)
	if err != nil {
		logInfo := fmt.Sprint("删除上海日历活动失败;rsCalendarResearcherId:,", rsCalendarResearcherId, " ;GetRelationByPars err"+err.Error())
		err = errors.New(logInfo)
		utils.FileLog.Info(logInfo)

		if err.Error() == utils.ErrNoRow() {
			err = nil
			return
		}
		return
	}

	//删除上海方的路演
	err = deleteSHCalendar(relationItem.UserPhone, relationItem.ThirdCalendarId)
	if err != nil {
		return
	}

	//删除活动表及事项表
	err = roadshow.DeleteRsCalendarRelation(relationItem.RelationId)
	if err != nil {
		err = errors.New("DeleteRsCalendarRelation err:" + err.Error())
		return
	}
	return
}

// DeleteSHMatter 删除上海日历事项
func DeleteSHMatter(matterId int) (err error) {
	defer func() {
		if err != nil {
			go alarm_msg.SendAlarmMsg("删除上海研究员日历失败；ERR:"+err.Error(), 3)
			//go utils.SendEmail(utils.APPNAME+"删除上海日历事项失败:", "删除上海研究员日历失败 "+err.Error(), utils.EmailSendToUsers)
		}
	}()
	var condition string
	var pars []interface{}
	condition = ` AND self_calendar_id = ?  and calendar_type = 2 `
	pars = append(pars, matterId)
	relationItem, err := roadshow.GetRelationByPars(condition, pars)
	if err != nil {
		err = errors.New(fmt.Sprint("删除上海日历事项失败;matterId:,", matterId, " ;GetRelationByPars err"+err.Error()))
		utils.FileLog.Info(err.Error())

		if err.Error() == utils.ErrNoRow() {
			err = nil
			return
		}
		return
	}

	//删除上海方的路演
	err = deleteSHCalendar(relationItem.UserPhone, relationItem.ThirdCalendarId)

	//删除活动表及事项表
	err = roadshow.DeleteRsCalendarRelation(relationItem.RelationId)
	if err != nil {
		err = errors.New("DeleteRsCalendarRelation err:" + err.Error())
		return
	}
	return
}

// SyncCalendarFromShanghai 上海路演数据同步到自系统
func SyncCalendarFromShanghai(userPhone, startDate, endDate string) (err error) {
	errMsgList := make([]string, 0)
	defer func() {
		if len(errMsgList) > 0 {
			//fmt.Println("err:", errMsg)
			if err != nil {
				errMsgList = append(errMsgList, fmt.Sprint("ERR:"+err.Error(), ";"))
			}
			go alarm_msg.SendAlarmMsg("上海路演数据同步到自系统失败；errMsg:"+strings.Join(errMsgList, "\n"), 3)
			//go utils.SendEmail(utils.APPNAME+"上海路演数据同步到自系统失败："+time.Now().Format("2006-01-02 15:04:05"), errMsg, utils.EmailSendToUsers)
		}
	}()
	//fmt.Println(userPhone, startDate, endDate)
	endDateTime, err := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
	if err != nil {
		errMsgList = append(errMsgList, `结束日期转time类型失败，err:`+err.Error())
		return
	}
	//往后延迟一天，避免截止到当天
	endDate = endDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)

	currDay := time.Now().Format(utils.FormatDate)
	nowDateTime, _ := time.ParseInLocation(utils.FormatDate, currDay, time.Local)
	//如果传入的结束日期早于当前日期，那么就不去查询了
	if endDateTime.Before(nowDateTime) {
		return
	}

	//获取当前研究员信息
	userPhoneInfo, err := getAdminInfo(userPhone)
	if err != nil {
		errMsgList = append(errMsgList, fmt.Sprint("获取手机号信息失败：手机号：", userPhone, ";err:"+err.Error(), ";"))
		return
	}

	//根据研究员和开始/结束日期获取上海的活动路演
	rsCalendarResearcherList, err := roadshow.GetRsCalendarResearcherInfoIByResearcherIdAndDate(userPhoneInfo.AdminId, currDay, endDate)
	if err != nil {
		errMsgList = append(errMsgList, fmt.Sprint("获取研究员日程信息失败：手机号：", userPhone, ";err:"+err.Error(), ";"))
		return
	}
	//待删除的活动路演
	deleteRsCalendarResearcherMap := make(map[int][]*roadshow.RsCalendarResearcherRelationInfo)
	for _, v := range rsCalendarResearcherList {
		tmpList, ok := deleteRsCalendarResearcherMap[v.ThirdCalendarId]
		if !ok {
			tmpList = make([]*roadshow.RsCalendarResearcherRelationInfo, 0)
		}
		tmpList = append(tmpList, v)

		deleteRsCalendarResearcherMap[v.ThirdCalendarId] = tmpList
	}

	//以当前日期作为起始日期去同步
	list, err := getCalendarFrom(userPhone, currDay, endDate)
	if err != nil {
		errMsgList = append(errMsgList, fmt.Sprint("获取第三方路演日历数据失败,", "userPhone:", userPhone, "；currDay:", currDay, "；endDate:", endDate, "；err:"+err.Error()))
		return
	}
	thirdIdList := make([]int, 0)
	if len(list) > 0 {
		for _, v := range list {
			thirdIdList = append(thirdIdList, v.ID)
			//移除还存在的活动，保留不存在的活动
			delete(deleteRsCalendarResearcherMap, v.ID)
		}
		rsCalendarRelationList, tmpErr := roadshow.GetRsCalendarRelationListByThirdIds(thirdIdList)
		if tmpErr != nil {
			err = tmpErr
			errMsgList = append(errMsgList, "获取关联列表失败,err:"+tmpErr.Error())
			return
		}

		rsCalendarRelationMap := make(map[int]*roadshow.RsCalendarRelation)
		for _, rsCalendarRelation := range rsCalendarRelationList {
			rsCalendarRelationMap[rsCalendarRelation.ThirdCalendarId] = rsCalendarRelation
		}

		for _, v := range list {
			//展示优先级：1、customer_name 2、project_name 3、title 需求池953
			if v.CustomerName != "" {
				v.Title = v.CustomerName
			} else if v.ProjectName != "" {
				v.Title = v.ProjectName
			}
			if rsCalendarRelation, ok := rsCalendarRelationMap[v.ID]; ok {
				//存在的话，那么就去查找对应的信息
				if rsCalendarRelation.CalendarType == 1 {
					//路演
					rsCalendarResearcherInfo, tmpErr := roadshow.GetRsCalendarResearcherById(rsCalendarRelation.SelfCalendarId)
					if tmpErr != nil {
						errMsgList = append(errMsgList, fmt.Sprint("第三方日历ID：", v.ID, "获取路演研究员信息失败;err:"+tmpErr.Error(), ";"))
						continue
					}
					rsCalendarInfo, tmpErr := roadshow.GetRsCalendarById(rsCalendarResearcherInfo.RsCalendarId)
					if tmpErr != nil {
						errMsgList = append(errMsgList, fmt.Sprint("第三方日历ID：", v.ID, "获取路演信息失败;err:"+tmpErr.Error(), ";"))
						continue
					}
					if rsCalendarInfo.Source == 0 { //自系统创建的路演活动，不需要依靠上海方来修改
						continue
					}

					//是否去同步变更数据库
					isUpdateSync := false

					//是否变更
					isUpdate := false
					if v.StartTime != rsCalendarRelation.StartTime {
						isUpdate = true
					}
					if v.EndTime != rsCalendarRelation.EndTime {
						isUpdate = true
					}
					if v.Title != rsCalendarRelation.Title {
						isUpdate = true
					}
					if rsCalendarResearcherInfo.Status == 4 { // 被删除了，现在是需要更新
						isUpdate = true
					}

					researcherList := make([]system.AdminItem, 0)
					researcherMap := make(map[int]system.AdminItem)

					addResearcherList := make([]system.AdminItem, 0)                  // 需要新增的研究员
					delResearcherIdList := make([]int, 0)                             //需要删除的路演活动与研究员的关系id
					updateResearcherList := make([]*roadshow.RsCalendarResearcher, 0) //待更新的路演活动中研究员信息

					if v.ResearcherMobile != rsCalendarRelation.ResearcherMobile {
						//研究员变更了，需要去改表
						isUpdateSync = true

						researcherMobileList := strings.Split(v.ResearcherMobile, ",")
						if len(researcherMobileList) > 0 {
							for _, mobile := range researcherMobileList {
								researcherInfo, tmpErr := getAdminInfo(mobile)
								if tmpErr != nil {
									errMsgList = append(errMsgList, fmt.Sprint("第三方日历ID：", v.ID, "获取研究员失败,研究员手机号：", mobile, ";err:"+tmpErr.Error(), ";"))
									continue
								}
								if researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_RESEARCHR ||
									researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RESEARCHR ||
									researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_RESEARCHR ||
									researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_DEPARTMENT ||
									researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_DEPARTMENT ||
									researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_SELLER ||
									researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_ADMIN {

									researcherList = append(researcherList, researcherInfo)
									researcherMap[researcherInfo.AdminId] = researcherInfo
								}
							}
						}

						//没有研究员
						if len(researcherList) <= 0 {
							errMsgList = append(errMsgList, fmt.Sprint("第三方日历ID：", v.ID, "；对方研究员信息失败；"))
							continue
						}

						rsCalendarResearcherList, tmpErr := roadshow.GetRsCalendarResearcherListByRsCalendarId(rsCalendarInfo.RsCalendarId)
						if tmpErr != nil {
							errMsgList = append(errMsgList, fmt.Sprint("第三方日历ID：", v.ID, "获取路演活动中的研究员列表失败,路演活动ID：", rsCalendarInfo.RsCalendarId, ";err:"+tmpErr.Error(), ";"))
							continue
						}

						//现有活动中的研究员
						rsCalendarResearcherMap := make(map[int]*roadshow.RsCalendarResearcher)
						for _, rsCalendarResearcher := range rsCalendarResearcherList {
							if _, ok := researcherMap[rsCalendarResearcher.ResearcherId]; ok {
								if isUpdate {
									updateResearcherList = append(updateResearcherList, rsCalendarResearcher)
								}
							} else {
								delResearcherIdList = append(delResearcherIdList, rsCalendarResearcher.RsCalendarResearcherId)
							}

							rsCalendarResearcherMap[rsCalendarResearcher.ResearcherId] = rsCalendarResearcher
						}

						//校验是否需要新增研究员
						for adminId, researcherInfo := range researcherMap {
							//如果
							if _, ok := rsCalendarResearcherMap[adminId]; !ok {
								addResearcherList = append(addResearcherList, researcherInfo)
							}
						}
					} else if isUpdate { //如果有字段更新，那么需要将所有的研究员信息更新
						isUpdateSync = true

						rsCalendarResearcherList, tmpErr := roadshow.GetRsCalendarResearcherListByRsCalendarId(rsCalendarInfo.RsCalendarId)
						if tmpErr != nil {
							errMsgList = append(errMsgList, fmt.Sprint("第三方日历ID：", v.ID, "获取路演活动中的研究员列表失败,路演活动ID：", rsCalendarInfo.RsCalendarId, ";err:"+tmpErr.Error(), ";"))
							continue
						}
						for _, rsCalendarResearcher := range rsCalendarResearcherList {
							updateResearcherList = append(updateResearcherList, rsCalendarResearcher)
						}
					}

					if isUpdateSync {
						tmpErr = roadshow.UpdateSyncRsCalendarRelation(v, rsCalendarInfo, rsCalendarRelation, updateResearcherList, delResearcherIdList, addResearcherList)
						if tmpErr != nil {
							err = tmpErr
							errMsgList = append(errMsgList, fmt.Sprint("第三方日历ID：", v.ID, "修改关联关系失败；err:"+tmpErr.Error(), ";"))
							return
						}
					}
				} else {
					//事项
					//事项都是由自系统创建的，不需要依靠上海方来修改
				}
			} else {
				//数据不存在
				createUser, tmpErr := getAdminInfo(v.UserPhone)
				if tmpErr != nil {
					errMsgList = append(errMsgList, fmt.Sprint("第三方日历ID：", v.ID, "获取创建人失败,创建人手机号：", v.UserPhone, ";err:"+tmpErr.Error(), ";"))
					continue
				}

				//研究员列表
				researcherList := make([]system.AdminItem, 0)
				researcherMobileList := strings.Split(v.ResearcherMobile, ",")
				if len(researcherMobileList) > 0 {
					for _, mobile := range researcherMobileList {
						researcherInfo, tmpErr := getAdminInfo(mobile)
						if tmpErr != nil {
							errMsgList = append(errMsgList, fmt.Sprint("第三方日历ID：", v.ID, "获取研究员失败,研究员手机号：", mobile, ";err:"+tmpErr.Error(), ";"))
							continue
						}
						if researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_RESEARCHR ||
							researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RESEARCHR ||
							researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_RESEARCHR ||
							researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_DEPARTMENT ||
							researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_DEPARTMENT ||
							researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_SELLER ||
							researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_ADMIN ||
							researcherInfo.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN {
							researcherList = append(researcherList, researcherInfo)
						}
					}
				}

				//没有研究员
				if len(researcherList) <= 0 {
					continue
				}
				//数据入库
				tmpErr = roadshow.SyncRsCalendarRelation(v, createUser, researcherList)
				if tmpErr != nil {
					err = tmpErr
					errMsgList = append(errMsgList, fmt.Sprint("第三方日历ID：", v.ID, "绑定关联关系失败；err:"+tmpErr.Error(), ";"))
					continue
				}
				//fmt.Println("createUser:", createUser)
			}

		}
	}

	//上海那边已经删除了路演，这边也要同步删除
	for _, deleteRsCalendarResearcherList := range deleteRsCalendarResearcherMap {
		for _, deleteRsCalendarResearcher := range deleteRsCalendarResearcherList {
			// 更新路演与研究员关系表的状态字段
			whereParams := make(map[string]interface{})
			updateParams := make(map[string]interface{})
			whereParams["rs_calendar_researcher_id"] = deleteRsCalendarResearcher.RsCalendarResearcherId
			updateParams["status"] = 4
			updateParams["modify_time"] = time.Now()
			tmpErr := roadshow.UpdateCalendarResearcher(whereParams, updateParams)
			if tmpErr != nil {
				err = tmpErr
				errMsgList = append(errMsgList, fmt.Sprint("第三方日历ID：", deleteRsCalendarResearcher.ThirdCalendarId, "删除关联关系失败；err:"+tmpErr.Error(), ";"))
				continue
			}

			// 更新路演的同步字段
			//calWhereParams := make(map[string]interface{})
			//calUpdateParams := make(map[string]interface{})
			//calWhereParams["rs_calendar_id"] = deleteRsCalendarResearcher.RsCalendarId
			//updateParams["is_synced"] = 1
			//err = roadshow.UpdateRsCalendar(calWhereParams, calUpdateParams)
		}
	}
	return
}

// CreateOaUser 新增系统用户
func CreateOaUser(mobile, username string, groupId int) (err error) {
	defer func() {
		if err != nil {
			errMsg := fmt.Sprint("手机号：", mobile, ";username:", username, ";分组id：", groupId, ";err:", err.Error())
			go alarm_msg.SendAlarmMsg("系统用户同步到上海失败；ERR:"+err.Error()+";errMsg:"+errMsg, 3)
			//go utils.SendEmail(utils.APPNAME+"系统用户同步到上海失败："+time.Now().Format("2006-01-02 15:04:05"), errMsg, utils.EmailSendToUsers)
		}
	}()
	finalUrl := utils.CRM_OPEN_API_URL + "/v1/OaUser/create"

	//发送创建请求
	form := url.Values{}
	form.Add("mobile", mobile)
	form.Add("username", username)
	form.Add("group_id", fmt.Sprint(groupId))

	//发送创建请求
	_, err, _ = postCurl(finalUrl, form, 0)
	if err != nil {
		err = errors.New("NewRequest Err:" + err.Error())
		return
	}
	return
}

// getAdminInfo 通过手机号获取用户信息
func getAdminInfo(mobile string) (adminInfo system.AdminItem, err error) {
	adminMap := make(map[string]system.AdminItem)
	redisAdminData, redisErr := utils.Rc.RedisString(utils.CACHE_KEY_ADMIN)
	if redisErr != nil {
		list, err := system.GetSysuserList("", []interface{}{}, 0, 1000)
		//	GetSysuserList
		for _, tmpAdminInfo := range list {
			adminMap[tmpAdminInfo.Mobile] = *tmpAdminInfo
		}

		//入缓存
		redisJsonData, err := json.Marshal(adminMap)
		if err == nil {
			_ = utils.Rc.Put(utils.CACHE_KEY_ADMIN, string(redisJsonData), time.Minute*30)
		}
	} else {
		err := json.Unmarshal([]byte(redisAdminData), &adminMap)
		if err != nil {
			fmt.Println("用户数据，json转换失败：", err)
		}
	}
	adminInfo, ok := adminMap[mobile]
	if !ok {
		err = fmt.Errorf("找不到该手机号用户，mobile:" + mobile)
	}

	return
}

// getAdminInfoById 通过用户id获取用户信息
func getAdminInfoById(sysId int) (adminInfo system.AdminItem, err error) {
	adminMap := make(map[int]system.AdminItem)
	redisAdminData, redisErr := utils.Rc.RedisString(utils.CACHE_KEY_ADMIN_ID)
	if redisErr != nil {
		list, err := system.GetSysuserList("", []interface{}{}, 0, 1000)
		//	GetSysuserList
		for _, tmpAdminInfo := range list {
			adminMap[tmpAdminInfo.AdminId] = *tmpAdminInfo
		}

		//入缓存
		redisJsonData, err := json.Marshal(adminMap)
		if err == nil {
			_ = utils.Rc.Put(utils.CACHE_KEY_ADMIN_ID, string(redisJsonData), time.Minute*30)
		}
	} else {
		err := json.Unmarshal([]byte(redisAdminData), &adminMap)
		if err != nil {
			fmt.Println("用户数据，json转换失败：", err)
		}
	}
	adminInfo, ok := adminMap[sysId]
	if !ok {
		err = fmt.Errorf("找不到该用户id，sysId:" + fmt.Sprint(sysId))
	}

	return
}

func getTitle(activityType, roadshowType, activityCategory, roadshowPlatform, province, city string) string {
	var title string
	switch activityType {
	case "内部会议":
		title = "内部会议"
	case "公开会议", "路演":
		if roadshowType == "线上" {
			title = roadshowType + activityType + roadshowPlatform
		} else {
			title = roadshowType + activityType + province + city
		}
	case "报告电话会":
		title = activityCategory + "电话会"
	}
	return title
}

// GetCalendarFrom 获取上海方的路演活动列表
func GetCalendarFrom(userPhone, startDate, endDate string) (list []roadshow.UserCalendar, err error) {
	list, err = getCalendarFrom(userPhone, startDate, endDate)
	return
}
