package elastic

import (
	"context"
	"encoding/json"
	"eta/eta_api/models/rag"
	"eta/eta_api/utils"
	"fmt"
	"github.com/olivere/elastic/v7"
	"time"
)

// 摘要索引
var EsWechatArticleAbstractName = utils.EsWechatArticleAbstractName

type WechatArticleAbstractItem struct {
	WechatArticleAbstractId int       `gorm:"column:wechat_article_abstract_id;type:int(9) UNSIGNED;primaryKey;not null;" description:"wechat_article_abstract_id"`
	WechatArticleId         int       `gorm:"column:wechat_article_id;type:int(9) UNSIGNED;comment:关联的微信报告id;default:0;" description:"关联的微信报告id"`
	WechatPlatformId        int       `gorm:"column:wechat_platform_id;type:int(9) UNSIGNED;comment:微信公众号id;default:0;" description:"微信公众号id"`
	Abstract                string    `gorm:"column:abstract;type:longtext;comment:摘要内容;" description:"摘要内容"` //
	Version                 int       `gorm:"column:version;type:int(10) UNSIGNED;comment:版本号;default:1;" description:"版本号"`
	VectorKey               string    `gorm:"column:vector_key;type:varchar(255);comment:向量key标识;" description:"向量key标识"`
	ModifyTime              time.Time `gorm:"column:modify_time;type:datetime;default:NULL;" description:"modify_time"`
	CreateTime              time.Time `gorm:"column:create_time;type:datetime;default:NULL;" description:"create_time"`
	Title                   string    `gorm:"column:title;type:varchar(255);comment:标题;" description:"标题"`
	Link                    string    `gorm:"column:link;type:varchar(255);comment:链接;" description:"链接"`
	TagIdList               []int     `description:"品种id列表"`
}

func (m *WechatArticleAbstractItem) ToView() rag.WechatArticleAbstractView {
	var modifyTime, createTime string

	if !m.CreateTime.IsZero() {
		createTime = m.CreateTime.Format(utils.FormatDateTime)
	}
	if !m.ModifyTime.IsZero() {
		modifyTime = m.ModifyTime.Format(utils.FormatDateTime)
	}

	tagId := 0
	if len(m.TagIdList) > 0 {
		tagId = m.TagIdList[0]
	}
	return rag.WechatArticleAbstractView{
		WechatArticleAbstractId: m.WechatArticleAbstractId,
		WechatArticleId:         m.WechatArticleId,
		WechatPlatformId:        m.WechatPlatformId,
		Abstract:                m.Abstract,
		Version:                 m.Version,
		VectorKey:               m.VectorKey,
		ModifyTime:              modifyTime,
		CreateTime:              createTime,
		Title:                   m.Title,
		Link:                    m.Link,
		TagId:                   tagId,
	}
}

func (m *WechatArticleAbstractItem) ToViewList(list []*WechatArticleAbstractItem) (wechatArticleViewList []rag.WechatArticleAbstractView) {
	wechatArticleViewList = make([]rag.WechatArticleAbstractView, 0)

	for _, v := range list {
		wechatArticleViewList = append(wechatArticleViewList, v.ToView())
	}
	return
}

// WechatArticleEsAddOrEdit
// @Description: 新增/编辑微信文章
// @author: Roc
// @datetime 2025-03-13 10:24:05
// @param docId string
// @param item WechatArticleAndPlatform
// @return err error
func WechatArticleAbstractEsAddOrEdit(docId string, item WechatArticleAbstractItem) (err error) {
	if docId == "" {
		return
	}
	if EsWechatArticleAbstractName == `` {
		return
	}
	defer func() {
		if err != nil {
			fmt.Println("WechatArticleEsAddOrEdit Err:", err.Error())
		}
	}()
	client := utils.EsClient

	resp, err := client.Index().Index(EsWechatArticleAbstractName).Id(docId).BodyJson(item).Refresh("true").Do(context.Background())
	if err != nil {
		fmt.Println("新增失败:", err.Error())
		return err
	}
	if resp.Status == 0 {
		fmt.Println("新增成功", resp.Result)
		err = nil
	} else {
		fmt.Println("WechatArticleEsAddOrEdit", resp.Status, resp.Result)
	}

	return
}

// WechatArticleEsDel
// @Description: 删除微信文章
// @author: Roc
// @datetime 2025-03-13 10:23:55
// @param docId string
// @return err error
func WechatArticleAbstractEsDel(docId string) (err error) {
	if docId == "" {
		return
	}
	if EsWechatArticleAbstractName == `` {
		return
	}
	defer func() {
		if err != nil {
			fmt.Println("EsDeleteEdbInfoData Err:", err.Error())
		}
	}()
	client := utils.EsClient

	resp, err := client.Delete().Index(EsWechatArticleAbstractName).Id(docId).Refresh(`true`).Do(context.Background())
	if err != nil {
		return
	}
	if resp.Status == 0 {
		fmt.Println("删除成功")
	} else {
		fmt.Println("WechatArticleEsDel", resp.Status, resp.Result)
	}

	return
}

// WechatArticleAbstractEsSearch
// @Description: 搜索
// @author: Roc
// @datetime 2025-03-13 19:54:54
// @param keywordStr string
// @param tagIdList []int
// @param platformIdList []int
// @param from int
// @param size int
// @param sortMap map[string]string
// @return total int64
// @return list []*WechatArticleAbstractItem
// @return err error
func WechatArticleAbstractEsSearch(keywordStr string, tagIdList, platformIdList []int, from, size int, sortMap map[string]string) (total int64, list []*WechatArticleAbstractItem, err error) {
	indexName := EsWechatArticleAbstractName
	list = make([]*WechatArticleAbstractItem, 0)
	defer func() {
		if err != nil {
			fmt.Println("SearchEdbInfoData Err:", err.Error())
		}
	}()

	query := elastic.NewBoolQuery()

	if len(tagIdList) > 0 {
		termsList := make([]interface{}, 0)
		for _, v := range tagIdList {
			termsList = append(termsList, v)
		}
		query = query.Must(elastic.NewTermsQuery("TagIdList", termsList...))
	}
	if len(platformIdList) <= 0 {
		return
	}

	{
		termsList := make([]interface{}, 0)
		for _, v := range platformIdList {
			termsList = append(termsList, v)
		}
		query = query.Must(elastic.NewTermsQuery("WechatPlatformId", termsList...))
	}

	// 名字匹配
	if keywordStr != `` {
		query = query.Must(elastic.NewMultiMatchQuery(keywordStr, "Abstract"))
	}

	// 排序
	sortList := make([]*elastic.FieldSort, 0)
	// 如果没有关键字,那么就走指标id倒序

	for orderKey, orderType := range sortMap {
		switch orderType {
		case "asc":
			sortList = append(sortList, elastic.NewFieldSort(orderKey).Asc())
		case "desc":
			sortList = append(sortList, elastic.NewFieldSort(orderKey).Desc())

		}

	}

	return searchWechatArticleAbstract(indexName, query, sortList, from, size)
}

// searchEdbInfoDataV2 查询es中的数据
func searchWechatArticleAbstract(indexName string, query elastic.Query, sortList []*elastic.FieldSort, from, size int) (total int64, list []*WechatArticleAbstractItem, err error) {
	total, err = searchWechatArticleAbstractTotal(indexName, query)
	if err != nil {
		return
	}

	// 获取列表数据
	list, err = searchWechatArticleAbstractList(indexName, query, sortList, from, size)
	if err != nil {
		return
	}

	return
}

// searchEdbInfoDataTotal
// @Description: 查询es中的数量
// @author: Roc
// @datetime 2024-12-23 11:19:04
// @param indexName string
// @param query elastic.Query
// @return total int64
// @return err error
func searchWechatArticleAbstractTotal(indexName string, query elastic.Query) (total int64, err error) {
	defer func() {
		if err != nil {
			fmt.Println("searchEdbInfoDataTotal Err:", err.Error())
		}
	}()
	client := utils.EsClient

	//根据条件数量统计
	requestTotalHits := client.Count(indexName).Query(query)
	total, err = requestTotalHits.Do(context.Background())
	if err != nil {
		return
	}

	return
}

// searchEdbInfoDataList
// @Description: 查询es中的明细数据
// @author: Roc
// @datetime 2024-12-23 11:18:48
// @param indexName string
// @param query elastic.Query
// @param sortList []*elastic.FieldSort
// @param from int
// @param size int
// @return list []*data_manage.EdbInfoList
// @return err error
func searchWechatArticleAbstractList(indexName string, query elastic.Query, sortList []*elastic.FieldSort, from, size int) (list []*WechatArticleAbstractItem, err error) {
	list = make([]*WechatArticleAbstractItem, 0)
	defer func() {
		if err != nil {
			fmt.Println("searchEdbInfoDataList Err:", err.Error())
		}
	}()
	client := utils.EsClient
	// 高亮
	highlight := elastic.NewHighlight()
	highlight = highlight.Fields(elastic.NewHighlighterField("Content"))
	highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")

	//request := client.Search(indexName).Highlight(highlight).From(from).Size(size) // sets the JSON request
	request := client.Search(indexName).From(from).Size(size) // sets the JSON request

	// 如果有指定排序,那么就按照排序来
	if len(sortList) > 0 {
		for _, v := range sortList {
			request = request.SortBy(v)
		}
	}

	searchMap := make(map[string]string)

	searchResp, err := request.Query(query).Do(context.Background())
	if err != nil {
		return
	}
	//fmt.Println(searchResp)
	//fmt.Println(searchResp.Status)
	if searchResp.Status != 0 {
		return
	}
	//total = searchResp.TotalHits()
	if searchResp.Hits != nil {
		for _, v := range searchResp.Hits.Hits {
			if _, ok := searchMap[v.Id]; !ok {
				itemJson, tmpErr := v.Source.MarshalJSON()
				if tmpErr != nil {
					err = tmpErr
					fmt.Println("movieJson err:", err)
					return
				}
				item := new(WechatArticleAbstractItem)
				tmpErr = json.Unmarshal(itemJson, &item)
				if tmpErr != nil {
					fmt.Println("json.Unmarshal movieJson err:", tmpErr)
					err = tmpErr
					return
				}
				if len(v.Highlight["Content"]) > 0 {
					item.Abstract = v.Highlight["Content"][0]
				}
				list = append(list, item)
				searchMap[v.Id] = v.Id
			}
		}
	}

	return
}