using System.Collections.Generic;
using System.Threading.Tasks;
using AutoMapper;
using GxPress.Common.AppOptions;
using GxPress.Common.Tools;
using GxPress.Entity;
using Microsoft.Extensions.Options;
using Datory;
using GxPress.Request.Notice;
using SqlKata;
using GxPress.Result.Notice;
using Dapper;
using System;
using GxPress.Repository.Interface;
using GxPress.Result.App.Missive;
using GxPress.Request.App.Missive;

namespace GxPress.Repository.Implement
{
    public class NoticeAddresseeRepository : IAddresseeRepository
    {
        private readonly Repository<Addressee> _repository;
        private readonly IMapper _mapper;
        private readonly string _connectionString;
        private readonly string _databaseTypeStr;
        public NoticeAddresseeRepository(IOptionsMonitor<DatabaseOptions> dbOptionsAccessor, IMapper mapper)
        {
            _databaseTypeStr = dbOptionsAccessor.CurrentValue.DatabaseType;
            _connectionString = dbOptionsAccessor.CurrentValue.ConnectionString;
            var databaseType = StringUtils.ToEnum<DatabaseType>(dbOptionsAccessor.CurrentValue.DatabaseType, DatabaseType.MySql);
            var database = new Database(databaseType, dbOptionsAccessor.CurrentValue.ConnectionString);
            _repository = new Repository<Addressee>(database);
            _mapper = mapper;
        }

        public IDatabase Database => _repository.Database;
        public string TableName => _repository.TableName;
        public List<TableColumn> TableColumns => _repository.TableColumns;
        /// <summary>
        /// 根据通知ID获取收件人
        /// </summary>
        /// <param name="noticeId"></param>
        /// <returns></returns>
        public async Task<IEnumerable<Addressee>> GetNoticeAddresseeByNoticeIdAsync(int noticeId)
        {
            return await _repository.GetAllAsync(Q.Where(nameof(Addressee.SourceId), noticeId));
        }

        public async Task<bool> DeleteAsync(int noticeId, int sourceType, int isAdmin)
        {
            var query = new SqlKata.Query();
            if (isAdmin == 0)
                query.Where(nameof(Addressee.IsAdmin), false);
            if (isAdmin == 1)
                query.Where(nameof(Addressee.IsAdmin), true);
            return await _repository.DeleteAsync(Q.Where(nameof(Addressee.SourceId), noticeId).Where(nameof(Addressee.SourceType), sourceType)) > 0;
        }

        public async Task<int> InsertAsync(Addressee noticeAddressee)
        {
            return await _repository.InsertAsync(noticeAddressee);
        }
        /// <summary>
        /// 插入收件人
        /// </summary>
        /// <param name="noticeAddressees"></param>
        /// <returns></returns>
        public async Task<bool> InsertAsync(List<Addressee> noticeAddressees)
        {
            if (noticeAddressees.Count == 0)
                return false;
            var sql = "INSERT INTO `tede_addressee`(`Guid`,`CreatedDate`,`LastModifiedDate`,`SourceId`,`SourceType`,`UserId`,`UserName`,`IsRead`,`NoticeAddresseeType`,`IsTop`,`IsAdmin`,`IsDelete`)VALUES";
            foreach (var item in noticeAddressees)
            {
                var guId = Guid.NewGuid().ToString();
                var createdDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                var isRead = item.IsRead == true ? 1 : 0;
                var isTop = item.IsTop == true ? 1 : 0;
                var isAdmin = item.IsAdmin == true ? 1 : 0;
                var isDelete = item.IsDelete == true ? 1 : 0;
                sql += $"('{guId}','{createdDate}','{createdDate}',{item.SourceId},{item.SourceType},{item.UserId},'',{isRead},{item.NoticeAddresseeType.GetHashCode()},{isTop},{isAdmin},{isDelete}),";
            }
            sql = sql.Remove(sql.Length - 1, 1);
            var databaseType = StringUtils.ToEnum<DatabaseType>(_databaseTypeStr, DatabaseType.MySql);
            var database = new Database(databaseType, _connectionString);
            var connection = database.GetConnection();
            var items = await connection.ExecuteAsync(sql);
            return items > 0;
        }
        /// <summary>
        /// 查询通知的未读已读
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<IEnumerable<NoticeReadListResult>> GetNoticeAddresseeByUserIdIdAsync(NoticeReadListRequest request)
        {
            var sqlValue = "";
            if (request.ReadType == 1)
                sqlValue += " and a.IsRead=1";
            else if (request.ReadType == 2)
                sqlValue += " and a.IsRead=0";
            if (!string.IsNullOrWhiteSpace(request.Key))
                sqlValue += $" and b.Name like '%{request.Key}%'";
            var sql = $"SELECT a.*,b.Name,b.AvatarUrl,c.Name FROM ccpph.tede_notice_addressee a inner join ccpph.tede_user b on a.UserId=b.Id inner join ccpph.tede_department c on c.Id=b.DepartmentId where a.NoticeId={request.NoticeId} {sqlValue} order by a.LastModifiedDate desc";
            var databaseType = StringUtils.ToEnum<DatabaseType>(_databaseTypeStr, DatabaseType.MySql);
            var database = new Database(databaseType, _connectionString);
            var connection = database.GetConnection();
            var items = await connection
                .QueryAsync<NoticeReadListResult, User, Department, NoticeReadListResult>(sql,
                    (noticeReadListResult, user, department) =>
                    {
                        noticeReadListResult.Name = user != null ? user.Name : "";
                        noticeReadListResult.AvatarUrl = user != null ? StringUtils.AddDomainMin(user.AvatarUrl) : "";
                        noticeReadListResult.DepartmentName = department.Name;
                        noticeReadListResult.LastModifiedDate = Convert.ToDateTime(noticeReadListResult.LastModifiedDate).ToString("yyyy-MM-dd HH:mm:ss");
                        return noticeReadListResult;
                    },
                    splitOn: "Name,Name");
            return items;
        }
        /// <summary>
        /// 获取收件人
        /// </summary>
        /// <param name="noticeId"></param>
        /// <returns></returns>
        public async Task<IEnumerable<User>> GetUserByNoticeIdAsync(int noticeId)
        {

            var sql = $"SELECT  b.* FROM ccpph.tede_notice_addressee a inner join ccpph.tede_user b on a.UserId=b.Id where a.NoticeId={noticeId} and a.IsAdmin=0;";
            var databaseType = StringUtils.ToEnum<DatabaseType>(_databaseTypeStr, DatabaseType.MySql);
            var database = new Database(databaseType, _connectionString);
            var connection = database.GetConnection();
            var items = await connection
                .QueryAsync<User>(sql);
            return items;
        }
        public async Task<int> CountAsync(Query query)
        {
            return await _repository.CountAsync(query);
        }

        public async Task<IEnumerable<Addressee>> GetAllAsync(Query query)
        {
            return await _repository.GetAllAsync(query);
        }

        public async Task<bool> UpdateAsync(Query query)
        {
            return await _repository.UpdateAsync(query) > 0;
        }

        public async Task<bool> ExistsAsync(Query query)
        {
            return await _repository.ExistsAsync(query);
        }

        public Task<IEnumerable<MissiveReadListResult>> GetMissiveReadListAsync(MissiveReadListRequest request)
        {
            throw new NotImplementedException();
        }
    }
}
