using Fuel.Core.Transactions.Dto;
using Org.BouncyCastle.Asn1.Ocsp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static FreeSql.Internal.GlobalFilter;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using FuelServer.Core.Entity;
using Fuel.Core.Nozzle.Dto;
using Org.BouncyCastle.Asn1.X509;
using System.Linq.Expressions;

namespace Fuel.Application.Service
{
    public class TransactionsService : ITransactionsService
    {
        private readonly EntityHelper _entityHelper;
        private readonly IHttpContextAccessor _httpContextAccessor;
        public TransactionsService(EntityHelper entityHelper, IHttpContextAccessor httpContextAccessor)
        {
            _entityHelper = entityHelper;
            _httpContextAccessor = httpContextAccessor;
        }

        public async Task<transactions> CreateTransactions(UploadTransactions uploadTransactions)
        {
            string Buid  = _httpContextAccessor.HttpContext.Request.Headers["Buid"].FirstOrDefault();
            Guid guid = Guid.Parse(Buid);
            string key = string.Empty;
            if (uploadTransactions.Type == 1)//预支付
            {
                key = uploadTransactions.NozzleId + ":" +
                         uploadTransactions.OriginalAmount + ":" +
                         uploadTransactions.Qty + ":" +
                         uploadTransactions.MiniProgramID + ":" +
                         Buid;
            }
            else//后支付
            {
                key = uploadTransactions.NozzleId + ":" +
                       uploadTransactions.OriginalAmount + ":" +
                       uploadTransactions.Qty + ":" +
                       uploadTransactions.MiniProgramID + ":" +
                       uploadTransactions.FuelItemTransactionEndTime + ":" +
                        uploadTransactions.TransactionNumber + ":" +
                       Buid;
            }
            transactions output = await GetRedisTransactions(uploadTransactions, key);
            if (output != null)
            {
                return output;
            }
            var _product = await _entityHelper.GetEntitiesAsync<product>(_ => _.Buid == guid && _.ProductName == uploadTransactions.Product);
            var _nozzle = await _entityHelper.GetEntitiesAsync<nozzle>(_ => _.Buid == guid && _.ExternalGunNumber == uploadTransactions.NozzleId);
            var transactions = uploadTransactions.ToTransactions(uploadTransactions, guid, _product.FirstOrDefault(), _nozzle.FirstOrDefault());
            var respond = await _entityHelper.InsertEntityAsync(transactions);
            string jsonString = JsonConvert.SerializeObject(respond);

            RedisHelper.SetAsync(key, jsonString, 3600);
            return respond;
        }
        public async Task<List<transactions>> GetTransactionsAsync(TransactionsInput input)
        {
            string Buid = _httpContextAccessor.HttpContext.Request.Headers["Buid"].FirstOrDefault();
            Guid guid = Guid.Parse(Buid);
            Expression<Func<transactions, bool>> where = p => p.Buid == guid;
            if (input.TransactionID != null)
            {
                where = CombineExpressions(where, p => p.Id == input.TransactionID);
            }
            if (input.type != null)
            {
                var status = (transactionsORDERSTATUS)input.type.Value;
                where = CombineExpressions(where, p => p.OrderStatus == status);
            }
            if (input.MiniProgramID != null)
            {
                where = CombineExpressions(where, p => p.MiniProgramID == input.MiniProgramID);
            }
            if (input.TransactionSTime != null)
            {
                where = CombineExpressions(where, p => p.TransactionTime >= input.TransactionSTime);
            }
            if (input.TransactionETime != null)
            {
                where = CombineExpressions(where, p => p.TransactionTime == input.TransactionETime);
            }
            if (!string.IsNullOrEmpty(input.Product))
            {
                where = CombineExpressions(where, p => p.ProductName == input.Product);
            }

            return await _entityHelper.GetEntitiesAsync<transactions>(where);
        }
        /// <summary>
        /// 查询redis订单缓存
        /// </summary>
        /// <returns></returns>
        public async Task<transactions> GetRedisTransactions(UploadTransactions uploadTransactions,string key)
        {
            string Buid = _httpContextAccessor.HttpContext.Request.Headers["Buid"].FirstOrDefault();
            var respond = RedisHelper.GetAsync(key).Result;
            if (respond == null)
            {
                return null;
            }
            transactions transactions = JsonConvert.DeserializeObject<transactions>(respond);
            return transactions;
        }
        // 辅助方法：组合两个表达式
        private static Expression<Func<T, bool>> CombineExpressions<T>(Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
        {
            ParameterExpression param = expr1.Parameters[0];
            Expression body = Expression.AndAlso(expr1.Body, Expression.Invoke(expr2, param));
            return Expression.Lambda<Func<T, bool>>(body, param);
        }

    }
}
