package elastic

import (
	"context"
	"encoding/json"
	"errors"
	"eta/eta_mini_crm_ht/models"
	"eta/eta_mini_crm_ht/utils"
	"fmt"
	"strconv"
	"strings"

	"github.com/olivere/elastic/v7"
)

// indexName:索引名称
// mappingJson:表结构
func EsCreateIndex(indexName, mappingJson string) (err error) {
	client := utils.EsClient

	//定义表结构
	exists, err := client.IndexExists(indexName).Do(context.Background()) //<5>
	if err != nil {
		return
	}
	if !exists {
		resp, err := client.CreateIndex(indexName).BodyJson(mappingJson).Do(context.Background())
		//BodyJson(bodyJson).Do(context.Background())
		if err != nil {
			fmt.Println("CreateIndex Err:" + err.Error())
			return err
		}
		fmt.Println(resp.Index, resp.ShardsAcknowledged, resp.Acknowledged)
	} else {
		fmt.Println(indexName + " 已存在")
	}
	return
}

// EsDeleteData 删除es中的指标数据
func EsDeleteData(indexName, docId string) (err error) {
	defer func() {
		if err != nil {
			fmt.Println("EsDeleteEdbInfoData Err:", err.Error())
		}
	}()
	client := utils.EsClient

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

// EsAddOrEditReport 新增编辑es报告
func EsAddOrEditReportPdf(indexName, docId string, item *models.ReportPdfView) (err error) {
	defer func() {
		if err != nil {
			fmt.Println("EsAddOrEditReport Err:", err.Error())
		}
	}()
	client := utils.EsClient

	// docId为报告ID+章节ID
	searchById, err := client.Get().Index(indexName).Id(docId).Do(context.Background())
	if err != nil && !strings.Contains(err.Error(), "404") {
		fmt.Println("Get Err" + err.Error())
		return
	}
	if searchById != nil && searchById.Found {
		resp, err := client.Update().Index(indexName).Id(docId).Doc(map[string]interface{}{
			"ReportPdfId":        item.ReportPdfId,
			"PdfUrl":             item.PdfUrl,
			"PdfName":            item.PdfName,
			"Title":              item.Title,
			"Abstract":           item.Abstract,
			"PublishTime":        item.PublishTime,
			"ModifyTime":         item.ModifyTime,
			"SysUserId":          item.SysUserId,
			"SysRealName":        item.SysRealName,
			"Author":             item.Author,
			"State":              item.State,
			"ClassifyIdFirst":    item.ClassifyIdFirst,
			"ClassifyNameFirst":  item.ClassifyNameFirst,
			"ClassifyIdSecond":   item.ClassifyIdSecond,
			"ClassifyNameSecond": item.ClassifyNameSecond,
			"ClassifyIdThird":    item.ClassifyIdThird,
			"ClassifyNameThird":  item.ClassifyNameThird,
			"Stage":              item.Stage,
		}).Do(context.Background())
		if err != nil {
			return err
		}
		//fmt.Println(resp.Status, resp.Result)
		if resp.Status == 0 {
			fmt.Println("修改成功" + docId)
			err = nil
		} else {
			fmt.Println("EditData", resp.Status, resp.Result)
		}
	} else {
		resp, err := client.Index().Index(indexName).Id(docId).BodyJson(item).Do(context.Background())
		if err != nil {
			fmt.Println("新增失败:", err.Error())
			return err
		}
		if resp.Status == 0 && resp.Result == "created" {
			fmt.Println("新增成功" + docId)
			return nil
		} else {
			fmt.Println("AddData", resp.Status, resp.Result)
		}
	}
	return
}

// EsAddOrEditReport 新增编辑es报告
func EsAddOrEditMedia(indexName, docId string, item *models.ESMedia) (err error) {
	defer func() {
		if err != nil {
			fmt.Println("EsAddOrEditReport Err:", err.Error())
		}
	}()
	client := utils.EsClient
	// docId为报告ID+章节ID
	searchById, err := client.Get().Index(indexName).Id(docId).Do(context.Background())
	if err != nil && !strings.Contains(err.Error(), "404") {
		fmt.Println("Get Err" + err.Error())
		return
	}
	if searchById != nil && searchById.Found {
		resp, err := client.Update().Index(indexName).Id(docId).Doc(map[string]interface{}{
			"authorId":              item.AuthorId,
			"authorName":            item.AuthorName,
			"src":                   item.Src,
			"mediaName":             item.MediaName,
			"mediaPlayMilliseconds": item.MediaPlayMilliseconds,
			"permissionIDs":         item.PermissionIds,
			"publishedTime":         item.PublishedTime,
		}).Do(context.Background())
		if err != nil {
			return err
		}
		//fmt.Println(resp.Status, resp.Result)
		if resp.Status == 0 {
			fmt.Println("修改成功" + docId)
			err = nil
		} else {
			fmt.Println("EditData", resp.Status, resp.Result)
		}
	} else {
		resp, err := client.Index().Index(indexName).Id(docId).BodyJson(item).Do(context.Background())
		if err != nil {
			fmt.Println("新增失败:", err.Error())
			return err
		}
		if resp.Status == 0 && resp.Result == "created" {
			fmt.Println("新增成功" + docId)
			return nil
		} else {
			fmt.Println("AddData", resp.Status, resp.Result)
		}
	}
	return
}

// AnalyzeResp 分词接口返回结构体
type AnalyzeResp struct {
	Tokens []struct {
		EndOffset   int64  `json:"end_offset"`
		Position    int64  `json:"position"`
		StartOffset int64  `json:"start_offset"`
		Token       string `json:"token"`
		Type        string `json:"type"`
	} `json:"tokens"`
}

// Analyze 根据输入的文字获取分词后的文字
func Analyze(content string) (contentList []string, err error) {
	defer func() {
		if err != nil {
			fmt.Println("Analyze Err:", err.Error())
		}
	}()
	client := utils.EsClient

	queryMap := map[string]string{
		"text":     content,
		"analyzer": "ik_max_word",
	}
	res, err := client.PerformRequest(
		context.Background(),
		elastic.PerformRequestOptions{
			Method: "GET",
			Path:   "/_analyze",
			Body:   queryMap,
			Stream: false,
		},
	)
	if res.StatusCode == 200 {
		var analyzeResp AnalyzeResp
		tmpErr := json.Unmarshal(res.Body, &analyzeResp)
		if tmpErr != nil {
			err = errors.New("返回数据转结构体失败：" + tmpErr.Error())
			return
		}
		for _, v := range analyzeResp.Tokens {
			contentList = append(contentList, v.Token)
		}
	} else {
		err = errors.New("分词失败,返回code异常：" + strconv.Itoa(res.StatusCode))
	}
	return
}
