using Senparc.Weixin.Entities.TemplateMessage;
using System;
using System.Data;
using System.Threading.Tasks;
using Wx;
using Yitter.IdGenerator;
using Znyc.Cloudcar.Admin.Commons;
using Znyc.Cloudcar.Admin.Commons.Entitys;
using Znyc.Cloudcar.Admin.Commons.Enums;
using Znyc.Cloudcar.Admin.Commons.Mapping;
using Znyc.Cloudcar.Admin.Commons.Pages;
using Znyc.Cloudcar.Admin.Commons.Services;
using Znyc.Cloudcar.Admin.Security.Dtos;
using Znyc.Cloudcar.Admin.Security.Entitys;
using Znyc.Cloudcar.Admin.Security.IRepositories;
using Znyc.Cloudcar.Admin.Security.IServices;

namespace Znyc.Cloudcar.Admin.Security.Services
{
    /// <summary>
    /// </summary>
    public class AuditService : BaseService<AuditEntity, AuditOutputDto, long>, IAuditService
    {
        private readonly IEquipmentRepository _equipmentRepository;
        private readonly IAuditRepository _auditRepository;
        private readonly ICurrencyRecordRepository _currencyRecordRepository;
        private readonly ICurrencyService _currencyService;
        private readonly IMessageLogsService _messageLogsService;
        private readonly ICloudcarService _CloudcarService;
        private readonly IUserService _userService;

        public AuditService(
            IEquipmentRepository equipmentRepository,
            IAuditRepository repository,
            ICloudcarService CloudcarService,
            IUserService userService,
            IMessageLogsService messageLogsService,
            ICurrencyRecordRepository currencyRecordRepository,
            ICurrencyService currencyService
        ) : base(repository)
        {
            _auditRepository = repository;
            _equipmentRepository = equipmentRepository;
            _CloudcarService = CloudcarService;
            _userService = userService;
            _messageLogsService = messageLogsService;
            _currencyRecordRepository = currencyRecordRepository;
            _currencyService = currencyService;
        }

        /// <summary>
        ///     ͬ������ʵ�塣
        /// </summary>
        /// <param name="entity">ʵ��</param>
        /// <param name="trans">�������</param>
        /// <returns></returns>
        public override long Insert(AuditEntity entity, IDbTransaction trans = null)
        {
            long result = repository.Insert(entity, trans);
            return result;
        }

        /// <summary>
        ///     �첽����ʵ�塣
        /// </summary>
        /// <param name="entity">ʵ��</param>
        /// <param name="id">����ID</param>
        /// <param name="trans">�������</param>
        /// <returns></returns>
        public override async Task<bool> UpdateAsync(AuditEntity entity, long id, IDbTransaction trans = null)
        {
            bool result = await repository.UpdateAsync(entity, id, trans);
            return result;
        }

        /// <summary>
        ///     �첽������ʵ�塣
        /// </summary>
        /// <param name="entity">ʵ��</param>
        /// <param name="trans">�������</param>
        /// <returns></returns>
        public override async Task<int> InsertAsync(AuditEntity entity, IDbTransaction trans = null)
        {
            int result = await repository.InsertAsync(entity, trans);
            return result;
        }

        public async Task<PageResult<AuditOutputDto>> FindWithPagerSearchAsync(SearchUserModel search)
        {
            bool order = search.Order == "asc" ? false : true;
            string where = GetDataPrivilege(false);
            if (!string.IsNullOrEmpty(search.Keywords))
            {
                where += string.Format(
                    " and (Title like '%{0}%' or Content like '%{0}%' or Name like '%{0}%' or  Phone like '%{0}%')",
                    search.Keywords);
            };
            PagerInfo pagerInfo = new PagerInfo
            {
                CurrenetPageIndex = search.CurrenetPageIndex,
                PageSize = search.PageSize
            };
            System.Collections.Generic.List<AuditEntity> list = await repository.FindWithPagerAsync(where, pagerInfo, search.Sort, order);
            PageResult<AuditOutputDto> pageResult = new PageResult<AuditOutputDto>
            {
                CurrentPage = pagerInfo.CurrenetPageIndex,
                Items = list.MapTo<AuditOutputDto>(),
                ItemsPerPage = pagerInfo.PageSize,
                TotalItems = pagerInfo.RecordCount
            };
            return pageResult;
        }

        /// <summary>
        ///     ���ͨ��
        /// </summary>
        /// <param name="pid"></param>
        /// <param name="productType"></param>
        /// <returns></returns>
        public async Task<CommonResult> AuditSuccessAsync(AuditEntity info,int promoteType)
        {
            CommonResult result = new CommonResult();
            string messageTitle = "";
            string productTitle = "";
            long userId = 0;
            string toUser = "";
            string url = "";
            AuditEntity audit = new AuditEntity
            {
                Id = YitIdHelper.NextId(),
                EquipmentId = info.EquipmentId,
                AuditUserId = info.CreatedUserId,
                HandleStatus = (int)HandleStatusEnum.Finding,
                Note = "",
                CreatedTime = info.CreatedTime,
                ModifiedTime = info.CreatedTime,
                CreatedUserId = info.CreatedUserId
            };

            EquipmentEntity equipment = await _equipmentRepository.GetAsync(info.EquipmentId);
            if (equipment.State == (int)ProductStatusEnum.Review && equipment!=null)
            {
                equipment.State = (int)ProductStatusEnum.Sell;
                equipment.ModifiedTime = DateTime.Now;
                if (equipment.IsTop == true)
                {
                    equipment.TopExpireDate = DateTime.Now.AddDays(1);
                }
                equipment.PromoteType = promoteType;
                equipment.Introduction = EmojiFilterHelper.FilterEmoji(equipment.Introduction);
                await _equipmentRepository.UpdateAsync(equipment, equipment.Id).ConfigureAwait(false);
                productTitle = equipment.Title;
                userId = equipment.UserId;
                messageTitle = ReturnConst.Cloud_Approved;
                toUser = (await _userService.GetAsync(equipment.UserId)).OpenId;
                url = string.Format("/pages/detail/detail?id={0}", info.EquipmentId);
            }
            else
            {
                result.ResData = "����Ϣ�����ڻ�δ�������!";
                result.Success = false;
                return result;
            };
           
           

            audit.EquipmentTitle = productTitle;
            await _auditRepository.InsertAsync(audit);
            MessageInputDto messageInputDto = new MessageInputDto
            {
                MessageTitle = messageTitle,
                EquipmentId = info.EquipmentId,
                EquipmentTitle = productTitle,
                UserId = userId,
                CreatedUserId = info.CreatedUserId,
                Content = ""
            };

            await _messageLogsService.AddAsync(messageInputDto).ConfigureAwait(false);
            TemplateMessageData templateMessageData = new TemplateMessageData
            {
                ["thing1"] = new(messageTitle),
                ["time2"] = new(DateTime.Now.ToString($"yyyy{ReturnConst.Year}MM{ReturnConst.Month}dd{ReturnConst.Day} HH:mm")),
                ["phrase3"] = new(ReturnConst.Approved),
                ["thing4"] = new(ReturnConst.Approved_Note)
            };


            //Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(templateMessageData));
            await CommonHelper.SendProductAsync(templateMessageData, toUser, url).ConfigureAwait(false);
            result.Success = true;
            return result;
        }

        /// <summary>
        ///     ���ʧ��
        /// </summary>
        /// <param name="productAuditInput"></param>
        /// <returns></returns>
        public async Task<CommonResult> AuditFailAsync(AuditEntity productAuditInput)
        {
            CommonResult result = new CommonResult();
            string messageTitle = "";
            string productTitle = "";
            long userId = 0;
            string toUser = "";
            string url = "";
            AuditEntity audit = new AuditEntity
            {
                Id = YitIdHelper.NextId(),
                EquipmentId = productAuditInput.EquipmentId,
                AuditUserId = productAuditInput.CreatedUserId,
                HandleStatus = (int)HandleStatusEnum.Fail,
                Note = productAuditInput.Note,
                CreatedTime = productAuditInput.CreatedTime,
                ModifiedTime = productAuditInput.CreatedTime,
                CreatedUserId = productAuditInput.CreatedUserId
            };

            EquipmentEntity equipment = await _equipmentRepository.GetAsync(productAuditInput.EquipmentId);
            //  productTitle = apply.Title;
            if (equipment.State == (int)ProductStatusEnum.Review &&  equipment != null)
            {
                equipment.State = (int)ProductStatusEnum.Fail;
                equipment.ModifiedTime = DateTime.Now;
                if (equipment.IsTop == true)
                {
                    equipment.IsTop = false;
                    equipment.TopExpireDate = Convert.ToDateTime("0001-01-01 00:00:00");
                    //���Ʊ�
                    await _currencyService.TopReturnForApplyJob(equipment.UserId, equipment.Id, productAuditInput.CreatedUserId);
                }
                equipment.Introduction = EmojiFilterHelper.FilterEmoji(equipment.Introduction);
                await _equipmentRepository.UpdateAsync(equipment, equipment.Id).ConfigureAwait(false);
                userId = equipment.UserId;
                productTitle = equipment.Title;
                 messageTitle = ReturnConst.Cloud_Audit_Failed;
                toUser = (await _userService.GetAsync(equipment.UserId)).OpenId;
                url = string.Format("/pages/detail/detail?id={0}", productAuditInput.EquipmentId);

            }
            else
            {
                result.ResData = "����Ϣ�����ڻ�δ�������!";
                result.Success = false;
                return result;
            }



            audit.EquipmentTitle = productTitle;
            await _auditRepository.InsertAsync(audit);
            MessageInputDto messageInputDto = new MessageInputDto
            {
                MessageTitle = messageTitle,
                EquipmentId = productAuditInput.EquipmentId,
                EquipmentTitle = productTitle,
                UserId = userId,
                CreatedUserId = productAuditInput.CreatedUserId,
                Content = ""
            };
            await _messageLogsService.AddAsync(messageInputDto).ConfigureAwait(false);
            TemplateMessageData templateMessageData = new TemplateMessageData
            {
                ["thing1"] = new(messageTitle),
                ["time2"] = new(DateTime.Now.ToString($"yyyy{ReturnConst.Year}MM{ReturnConst.Month}dd{ReturnConst.Day} HH:mm")),
                ["phrase3"] = new(ReturnConst.Audit_Failed),
                ["thing4"] = new(productAuditInput.Note)
            };
            await CommonHelper.SendProductAsync(templateMessageData, toUser, url).ConfigureAwait(false);
            result.Success = true;
            return result;
        }
    }
}