using System;
using System.Collections.Generic;
using System.Threading.Tasks;
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.Extensions;
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 RechargeService : BaseService<RechargeEntity, RechargeOutputDto, long>, IRechargeService
    {
        private readonly IRechargeRepository _rechargeRepository;
        private readonly IRechargeIntroRepository _rechargeIntroRepository;

        public RechargeService(
            IRechargeRepository repository,
            IRechargeIntroRepository rechargeIntroRepository
        ) : base(repository)
        {
            _rechargeRepository = repository;
            _rechargeIntroRepository = rechargeIntroRepository;
        }


        /// <summary>
        /// ·ÖÒ³²éѯ
        /// </summary>
        /// <param name="search"></param>
        /// <returns></returns>
        public async Task<PageResult<RechargeOutputDto>> FindWithPagerSearchAsync(SearchRechargeModel search)
        {
            bool order = search.Order == "asc" ? false : true;
            string where = GetDataPrivilege(false);
            if (search.State >= 0)
            {
                @where += $" and State={search.State}";
            }

            if (!string.IsNullOrEmpty(search.StartTime))
            {
                @where += $" and StartTime >='{search.StartTime} 00:00:00'";
            }

            if (!string.IsNullOrEmpty(search.EndTime))
            {
                @where += $" or EndTime <='{search.EndTime} 23:59:59'";
            }

            PagerInfo pagerInfo = new PagerInfo
            {
                CurrenetPageIndex = search.CurrenetPageIndex,
                PageSize = search.PageSize
            };
            List<RechargeOutputDto> list = (await repository.FindWithPagerAsync(where, pagerInfo, search.Sort, order)).MapTo<RechargeOutputDto>();
            foreach (var item in list)
            {
                item.StatusName = EnumExtensions
                    .ParseEnum(typeof(ActivityStatusEnum), item.State.ToString()).ToDescription();
                item.rechargeIntros = (await _rechargeIntroRepository.GetListWhereAsync($" ParentId={item.Id}")).MapTo<RechargeIntroOutputDto>();
            }
            PageResult<RechargeOutputDto> pageResult = new PageResult<RechargeOutputDto>
            {
                CurrentPage = pagerInfo.CurrenetPageIndex,
                Items = list,
                ItemsPerPage = pagerInfo.PageSize,
                TotalItems = pagerInfo.RecordCount
            };
            return pageResult;
        }

        /// <summary>
        ///     Òì²½ÐÂÔö³äÖµ»î¶¯ÏêÇéÊý¾Ý
        /// </summary>
        /// <param name="input"></param>
        /// <param name="parentId"></param>
        /// <param name="userId">´´½¨ÈË</param>
        /// <returns></returns>
        public async Task<bool> InsertRechargeIntroAsync(List<RechargeIntroAddInput> input, long parentId, long userId)
        {
            //¹Ø±ÕÆäËû³äÖµ»î¶¯
            RechargeEntity rechargeEntity = await _rechargeRepository.GetWhereAsync($" IsDeleted=0 and State=1 and Id!={parentId}");
            if (rechargeEntity != null)
            {
                rechargeEntity.State = (int)ActivityStatusEnum.End;
                await repository.UpdateAsync(rechargeEntity, rechargeEntity.Id).ConfigureAwait(false);
            }
            foreach (var item in input)
            {
                RechargeIntroEntity entity = new RechargeIntroEntity()
                {
                    Id = YitIdHelper.NextId(),
                    ParentId = parentId,
                    ProductName = string.Format(CommonConst.RechargeIntro_Name, item.ProductValue),
                    ProductValue = item.ProductValue,
                    SendValue = item.SendValue,
                    AllValue = item.ProductValue + item.SendValue,
                    Price = item.Price,
                    Description = string.Format(CommonConst.RechargeIntro_Description, item.ProductValue + item.SendValue),
                    CreatedUserId = userId,
                    CreatedTime = DateTime.Now
                };
                await _rechargeIntroRepository.InsertAsync(entity);
            }
            return true;
        }

        /// <summary>
        ///     Òì²½¸üÐÂÊý¾Ý
        /// </summary>
        /// <param name="input"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<CommonResult> UpdateAsync(RechargeUpdateInput input, long userId)
        {
            CommonResult result = new CommonResult();
            RechargeEntity info = await repository.GetAsync(input.Id);
            if (!(info?.Id > 0))
            {
                result.Success = false;
                result.ErrMsg = "³äÖµ»î¶¯ÐÅÏ¢²»´æÔÚ";
                return result;
            }
            info.Name = input.Name;
            info.State = (int)ActivityStatusEnum.Ongoing;
            info.ModifiedUserId = userId;
            info.ModifiedTime = DateTime.Now;
            foreach (var item in input.rechargeIntros)
            {
                RechargeIntroEntity entity = await _rechargeIntroRepository.GetAsync(item.Id);
                entity.ProductName = string.Format(CommonConst.RechargeIntro_Name, item.ProductValue);
                entity.ProductValue = item.ProductValue;
                entity.SendValue = item.SendValue;
                entity.AllValue = item.ProductValue + item.SendValue;
                entity.Price = item.Price;
                entity.Description = string.Format(CommonConst.RechargeIntro_Description, item.ProductValue + item.SendValue);
                entity.ModifiedUserId = userId;
                entity.ModifiedTime = DateTime.Now;
                await _rechargeIntroRepository.UpdateAsync(entity, entity.Id).ConfigureAwait(false);
            }
            await repository.UpdateAsync(info, input.Id).ConfigureAwait(false);
            //¹Ø±ÕÆäËû³äÖµ»î¶¯
            RechargeEntity rechargeEntity = await _rechargeRepository.GetWhereAsync($" IsDeleted=0 and State=1 and Id!={input.Id}");
            if (rechargeEntity != null)
            {
                rechargeEntity.State = (int)ActivityStatusEnum.End;
                await repository.UpdateAsync(rechargeEntity, rechargeEntity.Id).ConfigureAwait(false);
            }
            result.Success = true;
            return result;
        }
    }
}