using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Elasticsearch.Net;
using GxPress.Common.Page;
using Nest;

namespace GxPress.Common.Tools
{
    public class ElasticSearchHelper
    {

        private static ElasticSearchHelper _elasticSearchHelper;

        // 默认索引
        public static string DefaultIndex = "tededata";

        private ElasticClient Client()
        {
            var nodes = new Uri[]
            {
                new Uri("http://127.0.0.1:9200")
            };
            var pool = new StaticConnectionPool(nodes);
            var settings = new ConnectionSettings(pool)
                .DefaultIndex(DefaultIndex)
                .PrettyJson();

            return new ElasticClient(settings);
        }

        public static ElasticClient GetInstance()
        {
            if (_elasticSearchHelper == null)
            {
                _elasticSearchHelper = new ElasticSearchHelper();
            }

            return _elasticSearchHelper.Client();
        }

        /// <summary>
        /// 根据关键字查询
        /// </summary>
        /// <param name="key"></param>
        /// <param name="userId"></param>
        ///  <param name="typeId">文件夹类型 1 通知 2话题 3 收藏 4笔记 5 普通站内信 6匿名站内信 7小组 10聊天 100 通讯录 0全部</param>
        /// <returns></returns>
        public async Task<PagedList<TedeData>> SearchAsync(string key, int typeId, int userId, int page, int perPage)
        {

            var result = new PagedList<TedeData>();
            var client = GetInstance();
            var query = new Nest.SearchDescriptor<TedeData>();
            var listTedeData = new List<TedeData>();
            var total = 0;
            var queryResult = query;
            //全部
            if (typeId == 0)
            {
                query.Query(q =>
                     q.Bool(b =>
                         b.Must(m =>
                             m.MultiMatch(t => t.Fields(f => f.Field(obj => obj.Title).Field(obj => obj.Content).Field(obj => obj.Name)).Query(key))
                         )
                     )).PostFilter(n => n.Term(n => n.Field(f => f.UserId).Value(userId)));

            }
            else
            {
                //通讯录
                if (typeId == 100)
                {
                    query.Query(q =>
                                       q.Bool(b =>
                                           b.Must(m =>
                                               m.MultiMatch(t => t.Fields(f => f.Field(obj => obj.Title).Field(obj => obj.Content).Field(obj => obj.Name)).Query(key))
                                           )
                                       )).PostFilter(n => n.Term(n => n.Field(f => f.SearchType).Value(typeId)));
                }
                else
                {
                    query.Query(q =>
                    q.Bool(b =>
                        b.Must(m =>
                            m.MultiMatch(t => t.Fields(f => f.Field(obj => obj.Title).Field(obj => obj.Content).Field(obj => obj.Name)).Query(key))
                        )
                    )).PostFilter(n => n.Term(z => z.Field(f => f.UserId).Value(userId)) && n.Term(k => k.Field(m => m.SearchType).Value(typeId)));

                }
            }

            //排序
            Func<SortDescriptor<TedeData>, IPromise<IList<ISort>>> sortDesc = sd =>
            {
                    //根据分值排序
                    sd.Descending(n => n.CreatedDate);
                return sd;
            };
            var resultData = client.Search<TedeData>(x => queryResult.From((page - 1) * perPage).Size(perPage).Sort(sortDesc));
            var list = resultData.Documents.ToList();
            total += Convert.ToInt32(resultData.Total);
            listTedeData.AddRange(list);
            foreach (var item in listTedeData)
            {
                item.AvatarUrl = StringUtils.AddDomainMin(item.AvatarUrl);
            }
            result.Items = listTedeData;
            result.Total = total;

            return result;

        }

        /// <summary>
        /// 根据ID查询
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<TedeData> Get(string id)
        {
            var client = GetInstance();
            var response = await client.GetAsync<TedeData>(id, idx => idx.Index(DefaultIndex));
            return response.Source;
        }



        /// <summary>
        /// 按 id 删除单条数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<Result> Delete(string id)
        {
            var client = GetInstance();
            var response = await client.DeleteAsync<TedeData>(id, idx => idx.Index(DefaultIndex));
            return response.Result;
        }

        /// <summary>
        /// 插入数据
        /// </summary>
        /// <returns></returns>
        public async Task<bool> InsetData(TedeData data)
        {
            var client = GetInstance();
            //成功
            var result = await client.IndexAsync(data, idx => idx.Index(DefaultIndex));
            if (result.ApiCall.Success)
                return true;
            return false;
        }
    }

    [ElasticsearchType(RelationName = "TedeData", IdProperty = "GuId")]
    public class TedeData
    {
        /// <summary>
        /// 存放guid
        /// </summary>
        [Keyword]
        public string GuId { get; set; }
        /// <summary>
        /// 存放guid
        /// </summary>
        [Keyword]
        public string Id { get; set; }
        /// <summary>
        /// 姓名 群名称 聊天对应用户名称
        /// </summary>
        [Keyword]
        public string Name { get; set; }
        /// <summary>
        /// 头像地址
        /// </summary>
        [Text]
        public string AvatarUrl { get; set; }
        /// <summary>
        /// 文件夹类型 1 通知 2话题  5 站内信  7小组 10 聊天 100通讯录
        /// </summary>
        [Text]
        public int SearchType { get; set; }
        /// <summary>
        /// 环信ID
        /// </summary>
        [Text]
        public string ImId { get; set; }
        /// <summary>
        /// 群聊用到对应哪个用户
        /// </summary>
        [Text]
        public int ToUserId { get; set; }
        /// <summary>
        /// 用户ID
        /// </summary>
        [Text]
        public int UserId { get; set; }
        /// <summary>
        /// 标题  
        /// </summary>
        [Keyword]
        public string Title { get; set; }
        /// <summary>
        /// 内容
        /// </summary>
        [Text]
        public string Content { get; set; }
        /// <summary>
        /// 日期
        /// </summary>
        [Text]
        public DateTime? CreatedDate { get; set; }
        /// <summary>
        /// 1 单聊 2 群聊
        /// </summary>
        [Text]
        public int ChatType { get; set; }
    }

}
