using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XYY.Core.Standard.Data.Infrastructure;
using XYY.Service.Standard.Finance.Charging.Base;
using Dapper;
using RestSharp;
using XYY.Service.Standard.Finance.Charging.Express;
using XYY.Common.Standard;
using XYY.Model.Standard.Charging;
using XYY.Data.Standard.Charging;
using XYY.Service.Standard.Finance.Charging.Dto;
using XYY.Core.Standard.Mvc;

namespace XYY.Service.Standard.Finance.Charging.CustomerOrderFee
{
    public interface IChargeLogService
    {
        Task<long> SaveChargeLog(Finance_Charge_Log log);
        Task<long> SaveChargeLog(ExpressFeechargesModel chargeModel, bool success, string errorMessage);
        Task<PageResult<ChargeLogDto>> QueryData(QueryModel queryModel);
        Task<ApiJsonModel> RetryCharge(RetryChargingParam param);
        Task<List<ApiJsonModel>> RetryList(List<string> systemNoList);
    }

    public class ChargeLogService : IChargeLogService
    {
        IFinance_Charge_LogRepository _finance_Charge_LogRepository;
        ICustomerOrderFeeService _customerOrderFeeService;
        IUnitOfWork _unitOfWork;

        public ChargeLogService(IFinance_Charge_LogRepository finance_Charge_LogRepository, ICustomerOrderFeeService customerOrderFeeService, IUnitOfWork unitOfWork)
        {
            _finance_Charge_LogRepository = finance_Charge_LogRepository;
            _customerOrderFeeService = customerOrderFeeService;

            _unitOfWork = unitOfWork;
        }

        public async Task<PageResult<ChargeLogDto>> QueryData(QueryModel queryModel)
        {
            string sql =
                @"select L.*,c.CompanyName as CustomerName,ch.PublicName as ChannelName from Finance_Charge_Log L 
                inner join User_Customer c on L.CustomerId=c.Id
                inner join Logistics_Channel ch on L.ExpressId=ch.Id";
            var result = await _unitOfWork.GetPagingListAsync<ChargeLogDto>(queryModel, sql);
            return result;
        }

        public async Task<ApiJsonModel> RetryCharge(RetryChargingParam param)
        {
            try
            {
                if (param == null || param.Id <= 0)
                    throw new Exception("参数无效");

                var log = await _finance_Charge_LogRepository.GetAsync(param.Id);
                if (log == null)
                    throw new Exception("找不到记录");

                var chargingModel = Newtonsoft.Json.JsonConvert.DeserializeObject<ExpressFeechargesModel>(log.Json);
                if (!chargingModel.IsChargeBranchCompany)
                {
                    throw new Exception("扣费对象必须为分公司");
                }
                var chargeResult = await _customerOrderFeeService.Charges(chargingModel);
                if (chargeResult.success == true)
                {
                    await _finance_Charge_LogRepository.UpdateByConditionAsync(i => i.Id == param.Id, new { Success = true });
                }
                return chargeResult;
            }
            catch (Exception ex)
            {
                return new ApiJsonModel
                {
                    success = false,
                    error = ex.Message
                };
            }
        }

        public async Task<List<ApiJsonModel>> RetryList(List<string> systemNoList)
        {
            List<ApiJsonModel> models = new List<ApiJsonModel>();

            if (systemNoList == null || systemNoList.Count <= 0)
                throw new Exception("参数无效");

            var list = await _finance_Charge_LogRepository.
                QueryBySqlAsync($"select * from Finance_Charge_Log(nolock) where BillNo in ({string.Join(',', systemNoList.Select(x => "'" + x + "'"))})");


            foreach (var log in list)
            {
                try
                {
                    if (log == null)
                        throw new Exception("找不到记录");

                    var chargingModel = Newtonsoft.Json.JsonConvert.DeserializeObject<ExpressFeechargesModel>(log.Json);
                    if (!chargingModel.IsChargeBranchCompany)
                    {
                        throw new Exception("扣费对象必须为分公司");
                    }
                    var chargeResult = await _customerOrderFeeService.Charges(chargingModel);
                    if (chargeResult.success == true)
                    {
                        await _finance_Charge_LogRepository.UpdateByConditionAsync(i => i.Id == log.Id, new { Success = true });
                    }
                    models.Add(chargeResult);
                }
                catch (Exception ex)
                {
                    models.Add(new ApiJsonModel
                    {
                        success = false,
                        error = ex.Message
                    });
                }
            }

            return models;
        }

        public async Task<long> SaveChargeLog(Finance_Charge_Log log)
        {
            long id = await _finance_Charge_LogRepository.InsertAsync(log);
            return id;
        }

        public async Task<long> SaveChargeLog(ExpressFeechargesModel message, bool success, string errorMessage)
        {
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(message);
            Finance_Charge_Log log = new Finance_Charge_Log
            {
                BillNo = message.BillNo,
                CreateTime = DateTime.Now,
                CustomerId = message.CustomerId,
                ErrorMessage = errorMessage,
                ExpressId = message.ExpressId,
                TrackingNumber = message.TrackingNumber,
                Json = json,
                Success = success
            };
            long id = await SaveChargeLog(log);
            return id;
        }
    }
}
