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

namespace XYY.Service.Standard.Finance.Charging.CustomerAccount
{
    public interface ICustomerAccountService
    {
        /// <summary>
        /// 是否欠费
        /// </summary>
        /// <param name="customerId"></param>
        /// <returns></returns>
        Task<bool> IsArrears(int customerId);

        /// <summary>
        /// 扣费
        /// </summary>
        /// <param name="customerId"></param>
        /// <returns></returns>
        Task<bool> Deduction(int customerId, decimal fee, bool isLock);

        /// <summary>
        /// 计收入帐
        /// </summary>
        /// <returns></returns>
        Task<bool> Income(int customerId, decimal fee, int? CurrentOverdueDays = null);

        /// <summary>
        /// 付款
        /// </summary>
        /// <param name="customerId"></param>
        /// <param name="fee"></param>
        /// <returns></returns>
        Task<ApiJsonModel> Payment(PaymentModel detail);
    }

    public class CustomerAccountService : ICustomerAccountService
    {
        private readonly IUnitOfWork _unitOfWork;

        public CustomerAccountService(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        /// <summary>
        /// 取消扣费
        /// </summary>
        /// <param name="customerId"></param>
        /// <param name="fee"></param>
        /// <returns></returns>
        public async Task<bool> Income(int customerId, decimal fee, int? CurrentOverdueDays = null)
        {
            fee = Math.Abs(fee);
            //首先判断一次当前用户是否欠费，并且欠费金额+收入可更新为不欠费
            await _unitOfWork.Connection.ExecuteAsync($@"update Finance_Customer_Account set Arrears=0 where customerId={customerId} and Arrears=1 and Balance<=0-{fee}"
                    , null, _unitOfWork.Transaction);
            //更新相关的费用            
            string sql = @"update Finance_Customer_Account set Balance +=" + fee + " where customerId=" + customerId;
            if (CurrentOverdueDays.HasValue)
            {
                sql = @"update Finance_Customer_Account set Balance +=" + fee + ",CurrentOverdueDays="
                    + CurrentOverdueDays.Value + " where customerId=" + customerId;
            }
            if (await _unitOfWork.Connection.ExecuteAsync(sql, null, _unitOfWork.Transaction) == 0)
            {
                return false;
            }
            return true;


        }

        /// <summary>
        /// 扣费
        /// </summary>
        /// <param name="customerId"></param>
        /// <param name="fee"></param>
        /// <returns></returns>
        public async Task<bool> Deduction(int customerId, decimal fee, bool isLock)
        {
            string sql = "";
            if (isLock)
                sql = @"update Finance_Customer_Account set Balance -=" + fee + " where customerId=" + customerId + " and  Balance+Quota>0 ";
            else
                sql = @"update Finance_Customer_Account set Balance -=" + fee + " where customerId=" + customerId;
            return await _unitOfWork.Connection.ExecuteAsync(sql, null, _unitOfWork.Transaction) > 0;
        }



        /// <summary>
        /// 是否欠费
        /// </summary>
        /// <param name="customerId"></param>
        /// <returns></returns>
        public async Task<bool> IsArrears(int customerId)
        {
            string sql = $@"select isnull( Arrears,0) from Finance_Customer_Account(nolock) where CustomerId = {customerId}";
            return await _unitOfWork.Connection.QuerySingleOrDefaultAsync<bool>(sql);//QuerySingleAsync如果没有数据时会报错
        }
 
        public async Task<ApiJsonModel> Payment(PaymentModel detail)
        {
            detail.CreateTime = DateTime.Now;
            detail.TransactionNo = "CP" + DateTime.Now.ToString("yyyyMMddHHmmssfff");
            detail.AccountingNo = "ANO" + DateTime.Now.ToString("yyyyMMddHHmmssfff");
            detail.IncomeOrESxpense = "收入";
            detail.TransactionType = 3;
            detail.AccountingDate = detail.TransactionTime;
            if (_unitOfWork.Connection.State == System.Data.ConnectionState.Closed)
            {
                _unitOfWork.Connection.Open();
            }
            using (_unitOfWork.Transaction = _unitOfWork.Connection.BeginTransaction())
            {
                try
                {
                    bool isIncome = await Income(detail.CustomerId, detail.SettlementAmount,detail.CurrentOverdueDays);
                    if (isIncome)
                    {
                        await _unitOfWork.InsertAsync(detail.Copy<Finance.Charging.Base.Finance_ChargesDetail>());
                        _unitOfWork.Commit();
                        return ApiJsonModel.OK();
                    }
                    else
                    {
                        return ApiJsonModel.Error("写入收入信息失败");
                    }
                }
                catch (Exception ex)
                {
                    _unitOfWork.Transaction.Rollback();
                    return ApiJsonModel.Error(ex.Message);
                }
                finally
                {

                    _unitOfWork.Connection.Close();
                    _unitOfWork.Dispose();

                }
            }
        }
    }


}
