package services

import (
	"encoding/json"
	"fmt"
	"hongze/hz_crm_api/models"
	"hongze/hz_crm_api/utils"
	"io/ioutil"
	"net/http"
	"sort"
	"strings"
)

type GetClassifyListReq struct {
	Keyword     string
	CompanyType string
	HideDayWeek int
}

type ClassifySetEnabledReq struct {
	ClassifyId int `description:"分类ID"`
	Enabled    int `description:"是否可用，1可用，0禁用"`
}

type EditClassifyReq struct {
	ClassifyId int `description:"分类ID"`
	/*Abstract          string                 `description:"栏目简介"`
	Descript          string                 `description:"分享描述"`
	ReportAuthor      string                 `description:"栏目作者"`
	AuthorDescript    string                 `description:"作者简介"`
	ColumnImgUrl      string                 `description:"栏目配图"`
	ReportImgUrl      string                 `description:"报告配图"`
	HeadImgUrl        string                 `description:"头部banner"`
	AvatarImgUrl      string                 `description:"头像"`
	HomeImgUrl        string                 `description:"首页配图"`*/
	ClassifyLabel string `description:"分类标签"`
	ShowType      int    `description:"展示类型：1-列表 2-专栏"`
	/*HasTeleconference int                    `description:"是否有电话会：0-否 1-是"`
	VipTitle          string                 `description:"研究员头衔"`*/
	//Sort              int                    `description:"后台排序"`
	IsShow               int                    `description:"是否在小程序显示：1-显示 0-隐藏"`
	YbFiccSort           int                    `description:"小程序FICC页排序"`
	YbFiccIcon           string                 `description:"小程序FICC页icon"`
	YbFiccPcIcon         string                 `description:"小程序PC端FICC页背景图"`
	YbIconUrl            string                 `description:"小程序已购页icon"`
	YbBgUrl              string                 `description:"小程序已购详情背景图"`
	YbListImg            string                 `description:"小程序研报列表封面图"`
	YbShareBgImg         string                 `description:"小程序研报详情分享背景图"`
	YbRightBanner        string                 `description:"Pc端详情页，右侧，报告合集背景图"`
	MenuList             []*ClassifyMenuSaveReq `description:"子目录列表"`
	ClassifyMenuId       int                    `description:"二级分类-子目录ID"`
	RelateTel            int                    `description:"是否在电话会中可选: 0-否; 1-是"`
	RelateVideo          int                    `description:"是否在路演视频中可选: 0-否; 1-是"`
	ReportDetailShowType int                    `description:"报告详情的展示类型：1-拼接；2:目录"`
}

// ClassifyMenuSaveReq 保存分类子目录请求体
type ClassifyMenuSaveReq struct {
	MenuId   int    `description:"子目录ID, 0为新增, 大于0为编辑"`
	MenuName string `description:"子目录名称"`
}

type CrmEtaBaseResp struct {
	Code   int    `json:"code" description:"状态码"`
	Msg    string `json:"msg" description:"提示信息"`
	ErrMsg string `json:"-" description:"错误信息，不用返回给前端，只是做日志记录"`
}

func crmEtaPost(url string, param interface{}) (respBody []byte, err error) {
	data, e := json.Marshal(param)
	if e != nil {
		err = fmt.Errorf("data json marshal err: %s", e.Error())
		return
	}

	body := ioutil.NopCloser(strings.NewReader(string(data)))
	client := &http.Client{}
	req, e := http.NewRequest("POST", url, body)
	if e != nil {
		err = fmt.Errorf("http create request err: %s", e.Error())
		return
	}

	contentType := "application/json;charset=utf-8"
	req.Header.Set("Content-Type", contentType)
	req.Header.Set("Authorization", utils.CrmEtaAuthorization)
	resp, e := client.Do(req)
	if e != nil {
		err = fmt.Errorf("http client do err: %s", e.Error())
		return
	}
	defer func() {
		_ = resp.Body.Close()
	}()
	b, e := ioutil.ReadAll(resp.Body)
	if e != nil {
		err = fmt.Errorf("resp body read err: %s", e.Error())
		return
	}
	if len(b) == 0 {
		err = fmt.Errorf("resp body is empty")
		return
	}
	// 生产环境解密, 注意有个坑前后的双引号
	if utils.RunMode == "release" {
		str := string(b)
		str = strings.Trim(str, `"`)
		b = utils.DesBase64Decrypt([]byte(str))
	}

	respBody = b
	return
}

func EditReportClassify(pars *EditClassifyReq) (err error, errMsg string) {
	if utils.CrmEtaServerUrl == "" {
		return
	}
	url := fmt.Sprint(utils.CrmEtaServerUrl, "/api/eta/classify/edit")
	b, err := crmEtaPost(url, pars)
	if err != nil {
		errMsg = "更新品种失败"
		err = fmt.Errorf("url:%s err: %s", url, err.Error())
		return
	}
	result := new(CrmEtaBaseResp)
	if e := json.Unmarshal(b, &result); e != nil {
		errMsg = "更新分类失败"
		err = fmt.Errorf("result unmarshal err: %s\nresult: %s", e.Error(), string(b))
		return
	}
	utils.FileLog.Info("%s", string(b))
	if result.Code != 200 {
		err = fmt.Errorf("result: %s, err: %s", string(b), result.ErrMsg)
		errMsg = result.Msg
		return
	}
	return
}

type EditClassifyPermissionReq struct {
	Keyword               string
	ChartPermissionIdList []int `description:"权限id数组"`
	NewKeyword            string
}

// GetClassifyList 获取报告分类已绑定的权限
func GetClassifyList(req *GetClassifyListReq) (list models.ClassifyListResp, err error) {
	if utils.CrmEtaServerUrl == "" {
		return
	}
	url := fmt.Sprint(utils.CrmEtaServerUrl, "/api/eta/classify/list")
	b, err := crmEtaPost(url, req)
	if err != nil {
		err = fmt.Errorf("url:%s err: %s", url, err.Error())
		return
	}
	//result := new(models.ResultData)
	result := new(GetClassifyListResp)
	if e := json.Unmarshal(b, &result); e != nil {
		err = fmt.Errorf("result unmarshal err: %s\nresult: %s", e.Error(), string(b))
		return
	}
	utils.FileLog.Info("%s", string(b))
	if result.Code != 200 {
		err = fmt.Errorf("result: %s", string(b))
		return
	}
	list = result.Data
	return
}

type ClassifyPermissionReq struct {
	Keyword string
}

type ClassifyPermissionList struct {
	List []*models.ChartPermissionSearchKeyWordMapping
}

type GetClassifyListResp struct {
	Code   int                     `json:"code" description:"状态码"`
	Msg    string                  `json:"msg" description:"提示信息"`
	Data   models.ClassifyListResp `json:"data" description:"返回数据"`
	ErrMsg string                  `json:"-" description:"错误信息，不用返回给前端，只是做日志记录"`
}

// GetParentClassifyListByParentIdList
// @Description: 递归获取父级分类信息，正常来讲只有三次
// @author: Roc
// @datetime 2024-06-19 13:23:33
// @param parentClassifyIdList []int
// @return list []*models.ClassifyList
// @return err error
func GetParentClassifyListByParentIdList(parentClassifyIdList []int) (list []*models.Classify, err error) {
	num := len(parentClassifyIdList)
	if num <= 0 {
		return
	}
	list, err = models.GetClassifyListByParentIdList(parentClassifyIdList)
	if err != nil {
		return
	}

	// 是否还有上级
	{
		currParentClassifyIdList := make([]int, 0)
		for _, v := range list {
			if v.ParentId > 0 {
				currParentClassifyIdList = append(currParentClassifyIdList, v.ParentId)
			}
		}

		if len(currParentClassifyIdList) > 0 {
			tmpList, tmpErr := GetParentClassifyListByParentIdList(currParentClassifyIdList)
			if tmpErr != nil {
				err = tmpErr
				return
			}
			list = append(tmpList, list...)
		}
	}

	return
}

// GetClassifyListTreeRecursive
// @Description: 递归获取分类树形结构
// @author: Roc
// @datetime 2024-06-19 13:23:28
// @param list []*models.ClassifyList
// @param parentId int
// @return []*models.ClassifyList
func GetClassifyListTreeRecursive(list []*models.SimpleClassifyList, parentId int) []*models.SimpleClassifyList {
	res := make([]*models.SimpleClassifyList, 0)
	for _, v := range list {
		if v.ParentId == parentId {
			v.Child = GetClassifyListTreeRecursive(list, v.Id)
			res = append(res, v)
		}
	}

	// 前端的JP需要我这么返回
	if len(res) <= 0 {
		res = nil
	}

	return res
}

// BySortAndCreateTime 用来排序，先按Sort字段升序排序，若Sort相同，则按照CreateTime字段升序排序。
type BySortAndCreateTime []*models.SimpleClassifyList

func (a BySortAndCreateTime) Len() int {
	return len(a)
}

func (a BySortAndCreateTime) Swap(i, j int) {
	a[i], a[j] = a[j], a[i]
}

func (a BySortAndCreateTime) Less(i, j int) bool {
	if a[i].Sort == a[j].Sort {
		return a[i].CreateTime.Before(a[j].CreateTime)
	}
	return a[i].Sort < a[j].Sort
}

// SortClassifyListBySortAndCreateTime sorts the ClassifyList slice by Sort and then CreateTime in ascending order.
func SortClassifyListBySortAndCreateTime(classifyList []*models.SimpleClassifyList) {
	sort.Sort(BySortAndCreateTime(classifyList))
}
