using Knoks.Core.Data.Interfaces;
using Knoks.Core.Entities;
using Knoks.Core.Logic.Interfaces;
using Knoks.Framework.DataAccess;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;


namespace Knoks.Core.Data.Dao
{
    public class GeneralDao : IGeneralDao
    {
        #region Fields
        private readonly IProcExecutor _executor;
        private readonly ILogger<GeneralDao> _logger;
        private readonly IKnokSettings _settings;
        #endregion

        public GeneralDao(ILogger<GeneralDao> logger, IProcExecutor executor, IKnokSettings settings)
        {
            _executor = executor;
            _logger = logger;
            _settings = settings;
        }

        public async Task<IEnumerable<Country>> GetCountries(string countrySymbol)
        {
            _logger.LogDebug("GetCountries : {0}", countrySymbol);

            return (await _executor.Go("REG_GetCountries", new { CountrySymbol = countrySymbol })).Тables[0].Rows.Select(row => row.To<Country>());
        }

        public async Task<IEnumerable<Language>> GetLanguages()
        {
            _logger.LogDebug("GetLanguages");

            return (await _executor.Go("REG_GetLanguages")).Тables[0].Rows.Select(row => row.To<Language>());
        }

        public async Task<IEnumerable<KnokStatus>> GetKnokStatuses()
        {
            _logger.LogDebug("GetLanguages");

            return (await _executor.Go("BO_GetKnokStatuses")).Тables[0].Rows.Select(row => row.To<KnokStatus>());
        }

        public async Task<ExchangeStart> GetKnokStartValues(long exchangeId, string currency1, string currency2)
        {
            var t = (await _executor.Go(DatabaseNames.Prices, "ExchangeStartValues", new { ExchangeId = exchangeId, PairSymbol = currency1 + currency2 }));
            if (t.Тables[0].Rows.Count == 0)
            {
                return new ExchangeStart();
            }
            var r = t.Тables[0][0];
            var res = r.To<ExchangeStartValues>();

            var result = new ExchangeStart
            {
                EntryFrom = res.EntryFrom,
                EntryTo = res.EntryTo,
                ExitFrom = res.EntryFrom + _settings.MinAP,
                ExitTo = res.EntryTo + _settings.MinAP,
                StopLoss = res.EntryFrom - _settings.MaxSL
            };

            return result;
        }

        public async Task<IEnumerable<RankCount>> GetUserRank(long? userId)
        {
            var t = (await _executor.Go("GetUserRankCount", new { UserId = userId })).Тables[0].Rows.Select(row => row.To<RankCount>());
            var res = t.ToList();
            if (!res.Any(x => x.Rank == UserRank.Knight))
            {
                res.Add(new RankCount
                {
                    Rank = UserRank.Knight,
                    Count = 0
                });
            }
            if (!res.Any(x => x.Rank == UserRank.Jedi))
            {
                res.Add(new RankCount
                {
                    Rank = UserRank.Jedi,
                    Count = 0
                });
            }
            if (!res.Any(x => x.Rank == UserRank.Master))
            {
                res.Add(new RankCount
                {
                    Rank = UserRank.Master,
                    Count = 0
                });
            }
            if (!res.Any(x => x.Rank == UserRank.Padawan))
            {
                res.Add(new RankCount
                {
                    Rank = UserRank.Padawan,
                    Count = 0
                });
            }
            if (!res.Any(x => x.Rank == UserRank.Ranger))
            {
                res.Add(new RankCount
                {
                    Rank = UserRank.Ranger,
                    Count = 0
                });
            }
            return res;
        }

        public async Task<IEnumerable<KnokLossCount>> GetKnoksLossCount(long? userId)
        {
            return (await _executor.Go("BO_GetKnoksLossCount", new { UserId = userId })).Тables[0].Rows.Select(row => row.To<KnokLossCount>());
        }

        public async Task AddKnokFeedBack(Feedback feedback)
        {
            var clear = feedback.Clear ?? 0;
            var educational = feedback.Educational ?? 0;
            var comprehensive = feedback.Comprehensive ?? 0;
            var knokBenefit = feedback.KnokBenefit ?? 0;
            var res = await _executor.Go("BO_AddTraderFeedbacks", new
            {
                knokId = feedback.KnokId,
                userId = feedback.UserId,
                feedbackType = feedback.FeedbackType,
                comment = feedback.Comment,
                clear,
                educational,
                comprehensive,
                knokBenefit
            });            
        }
    }
}
