package cn.pluss.platform.ali.device.impl;

import cn.pluss.platform.ali.device.AliDeviceService;
import cn.pluss.platform.alidevice.AliScanCodeDevicePayEntity;
import cn.pluss.platform.alidevice.AliScanCodeDevicePayEnum;
import cn.pluss.platform.alidevice.AliScanCodeDeviceStatus;
import cn.pluss.platform.alidevice.RespDeviceEntity;
import cn.pluss.platform.api.Result;
import cn.pluss.platform.api.ResultCode;
import cn.pluss.platform.api.ResultGenerator;
import cn.pluss.platform.deviceStock.DeviceStockService;
import cn.pluss.platform.dto.MerChantOrderDTO;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.mercOrderToken.MercOrderTokenService;
import cn.pluss.platform.merchant.MerchantBaseInfoService;
import cn.pluss.platform.merchantChannelStatus.MerchantChannelStatusService;
import cn.pluss.platform.merchantOrder.MerchantOrderService;
import cn.pluss.platform.pay.PayService;
import cn.pluss.platform.ryx.pay.RyxPayService;
import cn.pluss.platform.sxf.pay.SxfPayService;
import cn.pluss.platform.util.ParametersUtil;
import cn.pluss.platform.util.StringUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 *
 *阿里云扫码王服务实现类
 *@author: bzg
 *@time: 2021/12/22 11:34
 */
@Service("aliScanCodeDeviceService")
@Slf4j
public class AliScanCodeDeviceServiceImpl implements AliDeviceService {

    @Resource
    private DeviceStockService deviceStockService;
    @Resource
    private MerchantBaseInfoService baseInfoService;
    @Resource
    private MerchantOrderService merchantOrderService;
    @Resource
    private MercOrderTokenService mercOrderTokenService;

    @Setter(onMethod_ = {@Autowired, @Qualifier("ysPayOldService")})
    private PayService ysPayOldService;

    @Resource
    private RyxPayService ryxPayService;

    @Resource
    private SxfPayService sxfPayService;

    @Resource
    private MerchantChannelStatusService channelService;

    @Override
    public RespDeviceEntity getDeviceStatusV1(String deviceNo) {
        if(StringUtil.isEmpty(deviceNo)){
            return RespDeviceEntity.fail("无效的设备号!");
        }
        DeviceStock deviceStock = deviceStockService.getDevicebyNo(deviceNo);
        return AliScanCodeDeviceStatus.getAliDeviceStatusV1(deviceStock);
    }

    @Override
    public RespDeviceEntity getDeviceStatusV2(String deviceNo) {
        if(StringUtil.isEmpty(deviceNo)){
            return RespDeviceEntity.fail("无效的设备号!");
        }
        DeviceStock deviceStock = deviceStockService.getDevicebyNo(deviceNo);
        return AliScanCodeDeviceStatus.getAliDeviceStatusV2(deviceStock);
    }

    @Override
    public Result<Object> bindDevice(String deivceNo, String userId) {
        DeviceStock deviceStock = deviceStockService.getDevicebyNo(deivceNo);
        MsgException.checkNull(deviceStock,"无效的设备号");
        MsgException.check("3".equals(deviceStock.getStatus()),"当前设备已被其他商户绑定");
        MerchantBaseInfo baseInfo = baseInfoService.getMerchantBaseInfoByUserId(userId);
        MsgException.checkNull(baseInfo,"无效用户");
        deviceStock.setActMercId(baseInfo.getId().toString());
        deviceStock.setActMercName(baseInfo.getAlias());
        deviceStockService.updateById(deviceStock);
        return ResultGenerator.genSuccessResult("绑定成功",null);
    }


    @Override
    public RespDeviceEntity orderPay(AliScanCodeDevicePayEntity entity, String payCode) {
        log.info("【阿里云扫码王】主扫请求参数：{}", JSON.toJSONString(entity));
        if(StringUtil.isEmpty(entity.getCode()) && StringUtil.isEmpty(entity.getSn())){
            return RespDeviceEntity.fail("缺失设备SN号");
        }
        String deviceNo = StringUtil.isEmpty(entity.getCode()) ? entity.getSn() : entity.getCode();
        entity.setCode(deviceNo);
        entity.setSn(deviceNo);
        if(StringUtil.isEmpty(entity.getFee())){
            return RespDeviceEntity.fail("缺少支付金额");
        }
        if (!StringUtil.isNumber(entity.getFee().toString())) {
            return RespDeviceEntity.fail("金额格式不正确,保留两位小数，单位(元)!");
        }
        RespDeviceEntity rde = this.getDeviceStatusV2(entity.getCode());
        if(rde.getCode() != 0 || rde.getData() == null){
            return rde;
        }
        AliScanCodeDeviceStatus deviceStatus = (AliScanCodeDeviceStatus)rde.getData();
        if(StringUtil.isEmpty(deviceStatus.getMercId())){
            return RespDeviceEntity.fail("该设备还未激活，请激活后再使用");
        }
        MerchantBaseInfo baseInfo = baseInfoService.getById(deviceStatus.getMercId());
        if(baseInfo == null){
            return RespDeviceEntity.fail("商户异常，暂时无法交易！");
        }
        try {
            if(AliScanCodeDevicePayEnum.BARCODE.getCode().equals(payCode)){
                if(StringUtil.isEmpty(entity.getAuth())){
                    return RespDeviceEntity.fail("未获取到付款码信息");
                }
                MerChantOrderDTO dto = new MerChantOrderDTO();
                dto.setType("0");
                dto.setMerchantCode(baseInfo.getMerchantCode());
                dto.setMerchantName(baseInfo.getAlias());
                dto.setConsumeFee(entity.getFee());
                dto.setAuthCode(entity.getAuth());
                dto.setMerchantBaseInfo(baseInfo);
                dto.setDeviceNo(entity.getCode());
                dto.setRemark(entity.getRemark());
                try {
                    Result<Object> mapResult = merchantOrderService.toActivePay(dto);
                    Object data = mapResult.getData();
                    if (ResultCode.TRANSUNKNOW.code() == mapResult.getCode()) {
                        return RespDeviceEntity.await(mapResult.getMessage(),((Map)data).get("orderNumber"));
                    }else if (ResultCode.SUCCESS.code() == mapResult.getCode()) {
                        return RespDeviceEntity.success(mapResult.getMessage(),((Map)data).get("orderNumber"));
                    }else{
                        return RespDeviceEntity.fail(mapResult.getMessage());
                    }
                }catch (Exception e){
                    return RespDeviceEntity.fail(e.getMessage());
                }
            }else if(AliScanCodeDevicePayEnum.QRCODE.getCode().equals(payCode)){
                String orderNumber = "AS_"+StringUtil.getBillno();
                MercOrderToken token = new MercOrderToken(baseInfo,entity.getFee(),entity.getCode(),orderNumber);
                mercOrderTokenService.save(token);
                String payUrl = ParametersUtil.domain + "/wap/merchant/scanPayAuth?tk="+token.getToken();
                Map<String, Object> result = new HashMap<>(2);
                result.put("trace",orderNumber);
                result.put("qr_code",payUrl);
                return RespDeviceEntity.success("获取成功",result);
            }else{
                return RespDeviceEntity.fail("未知操作");
            }
        }catch (MsgException e){
            e.printStackTrace();
            return RespDeviceEntity.fail(e.getMessage());
        }
    }

    @Override
    public RespDeviceEntity orderQuery(String orderNumber) {
        if(StringUtil.isEmpty(orderNumber)){
            return RespDeviceEntity.fail("缺少订单号");
        }
        QueryWrapper<MerchantOrder> queryWrapper = new QueryWrapper<MerchantOrder>().eq("orderNumber",orderNumber);
        MerchantOrder order = merchantOrderService.getOne(queryWrapper);
        if(order == null){
            return RespDeviceEntity.await("等待支付中...",orderNumber);
        }
        Map<String,Object> result = new HashMap<>(2);
        if("1".equals(order.getStatus())){
            result.put("amount",order.getConsumeFee().toString());
            return RespDeviceEntity.success("支付成功",result);
        }else if("5".equals(order.getStatus()) || "7".equals(order.getStatus())){
            try {
                Integer chnnelId = "2".equals(order.getAisleSwitch()) ? 1 : Integer.valueOf(order.getAisleSwitch());
                MerchantChannelStatus channel = channelService.getByMerchantCode(order.getMerchantCode(), chnnelId);
                JSONObject res = null;
                switch (channel.getChannel()){
                    case 1:
                        res = sxfPayService.tradeQuery(order,channel.getMerchantId());
                        break;
                    case 3:
                        res = ryxPayService.tradeQuery(order,channel.getMerchantId());
                        break;
                    case 4:
                        res = ysPayOldService.tradeQuery(order,channel.getMerchantId());
                        break;
                }
                if(res != null){
                    String payStatus = res.getString("payStatus");
                    if("0".equals(payStatus)){
                        return RespDeviceEntity.fail("支付失败",order.getOrderNumber());
                    }
                }
                return RespDeviceEntity.await("支付状态未知",order.getOrderNumber());
            }catch (Exception e){
                return RespDeviceEntity.await("支付状态未知",order.getOrderNumber());
            }
        }else{
            return RespDeviceEntity.fail("支付失败",order.getOrderNumber());
        }
    }
}
