using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Sugar.Enties;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Utils;
using Utils.Jwt;

namespace PMS.NetCore.Controllers
{
    /// <summary>
    /// 收款通企业收银台接口
    /// </summary>
    [Produces("application/json;charset=UTF-8")]
    [Route("api/Paypal")]
    [ServiceFilter(typeof(Filter.TokenAuthorize))]
    public class PaypalController : BaseController
    {
        /// <summary>
        /// 支付结果通知
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost]
        [Route("PaymentNotice")]
        public JsonResult PaymentNotice([FromBody] PaypalReq req)
        {
            logger.Info($"【PaymentNotice】req:{JsonConvert.SerializeObject(req)}");
            //初始化返回参数
            var res = new PaypalRes
            {
                version = "1.0",
                txCode = "BILPAY",
                respCode = "",
                respDesc = "",
                merchBatch = req.merchBatch,
                merchId = req.merchId
            };

            try
            {
                //var paypalRes = JsonConvert.DeserializeObject<PaypalReq>(req);
                if (req.version != "1.0" || req.txCode != "BILPAY")
                {
                    res.respCode = "LX11C901";
                    res.respDesc = "参数异常";
                    logger.Info($"【PaymentNotice】res:{JsonConvert.SerializeObject(res)}");
                    return Json(res);
                }
                var service = new maxbillcodeManager();

               
                var service1 = new fdc_pm_revfareManager();
                var service2 = new fdc_pm_revfare_bManager();
                var fareb = new fdc_pm_fare_bManager().Db.Queryable<fdc_pm_fare_b>().First(m => m.farerowid == req.orderId);
                if(fareb==null)
                {
                    res.respCode = "LX11C001";
                    res.respDesc = "失败--无此应收费用记录";
                    logger.Info($"【PaymentNotice】res:{JsonConvert.SerializeObject(res)}");
                    return Json(res);
                }
                #region 构建fdc_pm_revfare实例
                var rev = new fdc_pm_revfare();
                rev.pk_revfarecode = service.GetMaxBillCode("", "S", true);
                rev.hcode = fareb.hcode;
                rev.ownerid = fareb.ownerid;
                
                rev.revnmny = req.trnAmt.ToDecimal() / 100;
                //收款日期
                var receiveDate = (req.trnDate.Substring(0, 4) + "-" + req.trnDate.Substring(4, 2) + "-" + req.trnDate.Substring(6)).ToDateTime();
                rev.dbilldate = receiveDate;
                rev.doperatordate = receiveDate;
                rev.dapprovedate = receiveDate;
                rev.voperatorid = "1099";   //系统管理员
                rev.vapproveid = "1099";   //系统管理员
                rev.prerevflag = "N";
                rev.billstatus = "1";    //支付状态
                rev.billtype = "S";     //普通收款单
                rev.paytype = "2003";    //暂定为银0159
                rev.issettle = "1";
                #endregion
                logger.Info($"【PaymentNotice】收款单主表rev:{JsonConvert.SerializeObject(rev)}");
                var success = false;
                if(!service1.Db.Queryable<fdc_pm_revfare>().Any(it=>it.pk_revfarecode==rev.pk_revfarecode))
                {
                    success=service1.Insert(rev);
                }
                else
                {
                    success=service1.Update(rev);
                }
                if(!success)
                { 
                    res.respCode = "LX11C001";
                    res.respDesc = "失败-插入收款单主表失败";
                    logger.Info($"【PaymentNotice】res:{JsonConvert.SerializeObject(res)}");
                    return Json(res);
                }
                
                #region 构建fdc_pm_revfare_b实例
                var detail = new fdc_pm_revfare_b();
                detail.revfarerowid = service.GetMaxBillCode("", "", true);
                detail.pk_revfarecode = rev.pk_revfarecode;
                detail.farerowid = req.orderId;
                detail.hcode = fareb.hcode;
                detail.narea = fareb.narea;
                detail.billitemcode = fareb.billitemcode;
                detail.nneedmny = fareb.nneedpaymny;
                detail.nrevmny = req.trnAmt.ToDecimal() / 100;  //缴费金额
                detail.nprice = fareb.nprice.SConvertString();
                detail.dbdate = fareb.dbegindate;
                detail.dedate = fareb.denddate;
                detail.prerevflag = rev.prerevflag;
                detail.issettle = rev.issettle;
                detail.pk_paytype = rev.paytype;
                detail.billtype = rev.billtype;
                detail.pk_meterid = fareb.pk_meterid;
                #endregion
                logger.Info($"【PaymentNotice】收款单子表detail:{JsonConvert.SerializeObject(detail)}");
                var success1 = false;
                if (!service2.Db.Queryable<fdc_pm_revfare_b>().Any(it => it.revfarerowid == detail.farerowid))
                {
                    success1 = service2.Insert(detail);
                }
                else
                {
                    success1 = service2.Update(detail);
                }
                if (!success1)
                { 
                    res.respCode = "LX11C001";
                    res.respDesc = "失败--插入收款单子表失败";
                    logger.Info($"【PaymentNotice】res:{JsonConvert.SerializeObject(res)}");
                    return Json(res);
                }
               
                
                res.respCode = "LX11C000";
                res.respDesc = "交易成功";
                logger.Info($"【PaymentNotice】res:{JsonConvert.SerializeObject(res)}");
                return Json(res);
            }
            catch(Exception ex)
            {
                logger.Error(ex);
                res.respCode = "LX11C999";
                res.respDesc = "系统异常,请稍后重试"+ex.Message;
                logger.Info($"【PaymentNotice】res:{JsonConvert.SerializeObject(res)}");
                return Json(res);
            }


            }
    }
    /// <summary>
    /// 支付结果通知请求参数
    /// 1. 仅通知成功交易（线下交易模式会以收方账户动账为主进行通知）；
    /// 2. 通知会存在重复通知，请兼容重复通知的场景；
    /// 3. 不作为结果唯一标准，请以单笔查询为准； 
    /// </summary>
    public class PaypalReq
    {
        /// <summary>
        /// 版本号  固定1.0
        /// </summary>
        public string version { get; set; }
        /// <summary>
        /// 交易码  该接口固定为：BILPAY
        /// </summary>
        public string txCode { get; set; }
        /// <summary>
        /// 缴费平台商户编号
        /// </summary>
        public string merchId { get; set; }


        #region 线上线下接口都使用的字段   当线下接口当checkStatus = Y，存在以下信息
        /// <summary>
        /// 缴费平台流水号 缴费平台针对每笔交易唯一键值 建议商户落地保存
        /// </summary>
        public string cmbOrderId { get; set; }
        /// <summary>
        /// 商户方订单号 作为商户方订单唯一键值标识
        /// </summary>
        public string orderId { get; set; }
      
        /// <summary>
        /// 缴费编号，请求商户方，获取缴费信息
        /// </summary>
        public string payNo { get; set; }
        /// <summary>
        /// 缴费金额  非0的整数字符串，单位分
        /// </summary>
        public string trnAmt { get; set; }
        /// <summary>
        /// 缴费批次   缴费平台批次号（一般跟交易发生日期一致，主要用于对账选择交易的范围，日终核对时，缴费平台按此值筛选发送明细数据）建议商户落地保存
        /// </summary>
        public string settleBatch { get; set; }
        /// <summary>
        /// 商户批次按照商户查询响应中的批次(非必填字段)
        /// </summary>
        public string merchBatch { get; set; }
        /// <summary>
        /// 缴费日期  支付完成时间格式YYYYMMDD
        /// </summary>
        public string trnDate { get; set; }
        /// <summary>
        /// 缴费时间  支付完成时间格式24HHmmSS
        /// </summary>
        public string trnTime { get; set; }
        /// <summary>
        /// 支付状态 支付状态，Y:成功；N:失败；R:退款；T:支付中   非必填字段
        /// </summary>
        public string trnStatus { get; set; }
       

        /// <summary>
        /// 商户方账户  非必填字段
        /// </summary>
        public string rcvAccNo { get; set; }
        /// <summary>
        /// 商户方账户名称  非必填字段
        /// </summary>
        public string rcvAccName { get; set; }
        /// <summary>
        /// 客户方账户  非必填字段
        /// </summary>
        public string payAccNo { get; set; }
        /// <summary>
        /// 客户方账户名称  非必填字段
        /// </summary>
        public string payAccName { get; set; }
        /// <summary>
        /// 支付方式   02：一网通；03：招行线上app支付；10：微信；11：支付宝；12：转账码；13：虚拟户；14白名单；21：预付款全额抵扣；
        /// 非必填字段
        /// </summary>
        public string payType { get; set; }
        /// <summary>
        /// 通知模式  01：线上模式；02：线下模式
        /// </summary>
        public string orderType { get; set; }
        /// <summary>
        /// 商户保留字段  查询响应字段信息
        /// 非必填字段
        /// </summary>
        public string note { get; set; }
        #endregion


        /// <summary>
        /// 主机流水号 主要为聚合订单号、转账模式的主机流水号、一网通订单号等信息
        /// 非必填字段
        /// </summary>
        public string hostSerial { get; set; }
        
        /// <summary>
        /// 主机缴费批次   
        /// 线下接口使用
        /// </summary>
        public string hostSettleBatch { get; set; }
        /// <summary>
        /// 商户方账户  
        /// 线下接口使用
        /// 非必填
        /// </summary>
        public string hostRcvAccNo { get; set; }
        /// <summary>
        /// 商户方账户名称  
        /// 线下接口使用
        /// 非必填
        /// </summary>
        public string hostRcvAccName { get; set; }
        /// <summary>
        /// 商户方开户行名称 
        /// 线下接口使用
        /// 非必填
        /// </summary>
        public string hostRcvAccBank { get; set; }
        /// <summary>
        /// 虚拟子户
        /// 线下接口使用
        /// 非必填
        /// </summary>
        public string hostSubAccNo { get; set; }
        /// <summary>
        /// 客户方账户 
        /// 线下接口使用
        /// 非必填
        /// </summary>
        public string hostPayAccNo { get; set; }
        /// <summary>
        /// 客户方户名
        /// 线下接口使用
        /// 非必填
        /// </summary>
        public string hostPayAccName { get; set; }
        /// <summary>
        /// 币种 
        /// 线下接口使用
        /// 非必填
        /// </summary>
        public string hostCurrencyNo { get; set; }
        /// <summary>
        /// 主机交易日期
        /// 线下接口使用
        /// 非必填
        /// </summary>
        public string hostTrnDate { get; set; }
        /// <summary>
        /// 主机交易时间
        /// 线下接口使用
        /// 非必填
        /// </summary>
        public string hostTrnTime { get; set; }
        /// <summary>
        /// 摘要
        /// 线下接口使用
        /// 非必填
        /// </summary>
        public string hostCustAbs { get; set; }
        /// <summary>
        /// 借贷方向，D（debit）:借;C(credit):贷,站在商户方账户的角度
        /// 线下接口使用
        /// 非必填
        /// </summary>
        public string hostDrCr { get; set; }
        /// <summary>
        /// 是否对账 Y:对账成功（勾连成功）；F:对账失败（挂账、匿名账务）；N（待处理对账）；B(手工对账)
        /// 线下接口使用
        /// 非必填
        /// </summary>
        public string checkStatus { get; set; }
        /// <summary>
        /// 主机金额 非0的整数字符串，单位分
        /// 线下接口使用
        /// 非必填
        /// </summary>
        public string hostTrnAmt { get; set; }
       
    }
    /// <summary>
    /// 响应参数  
    /// 1. 仅通知成功交易（线下交易模式会以收方账户动账为主进行通知）；
    /// 2. 通知会存在重复通知，请兼容重复通知的场景；
    /// 3. 不作为结果唯一标准，请以单笔查询为准；
    /// LX11C000 交易成功
    /// LX11CXXX 失败
    /// LX11C999 系统异常, 请稍后重试
    /// LX11C998 网络连接超时, 请稍后重试
    /// LX11C997 数据异常
    /// LX11C996 系统繁忙, 请稍后重试
    /// LX11C995 签名验证失败
    /// LX11C994 生成签名失败
    /// LX11C901 参数异常
    /// </summary>
    public class PaypalRes
    {
        /// <summary>
        /// 版本号 接口版本号，固定1.0
        /// </summary>
        public string version { get; set; }
        /// <summary>
        /// 校验码  该接口固定为：BILPAY
        /// </summary>
        public string txCode { get; set; }
        /// <summary>
        /// 响应码   LX11C000:交易成功  LX11CXXX:失败
        /// </summary>
        public string respCode { get; set; }
        /// <summary>
        /// 响应描述
        /// </summary>
        public string respDesc { get; set; }
        /// <summary>
        /// 商户号  缴费平台商户编号
        /// </summary>
        public string merchId { get; set; }
        /// <summary>
        /// 商户批次  非必填
        /// </summary>
        public string merchBatch { get; set; }

    }
}
