package cn.pluss.platform.ys.impl;

import cn.jiguang.common.utils.StringUtils;
import cn.pluss.platform.SubMerchantApplyOrderService;
import cn.pluss.platform.channel.MerchantCertService;
import cn.pluss.platform.dto.AccountDTO;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.merchant.AccountService;
import cn.pluss.platform.merchant.MerchantBaseInfoService;
import cn.pluss.platform.merchantChannelStatus.MerchantChannelStatusService;
import cn.pluss.platform.merchantImage.MerchantImageService;
import cn.pluss.platform.userApp.UserAppService;
import cn.pluss.platform.util.Base64Util;
import cn.pluss.platform.util.FileUtil;
import cn.pluss.platform.util.OssOperatUtil;
import cn.pluss.platform.ys.YsConfig;
import cn.pluss.platform.ys.YsService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import lombok.var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author djh
 */
@Slf4j
@Service("ysCertService")
public class YsCertServiceImpl implements MerchantCertService {

    @Autowired
    private MerchantBaseInfoService mbiService;

    @Autowired
    private MerchantChannelStatusService mcsService;

    @Setter(onMethod_ = {@Autowired,@Lazy})
    private UserAppService userAppService;

    @Autowired
    private MerchantImageService merchantImageService;

    @Autowired
    private SubMerchantApplyOrderService subMerchantApplyOrderService;

    @Autowired
    private YsService ysService;

    @Setter(onMethod_ = {@Autowired,@Lazy})
    private AccountService accountService;

    @Override
    public void wxCert(String merchantId, String merchantCode) {
        MerchantBaseInfo mbi = new MerchantBaseInfo()
                .setMerchantCode(merchantCode);
        mbi = mbiService.getOne(new QueryWrapper<>(mbi));

        MerchantImage merImg = new MerchantImage()
                .setMerchantCode(merchantCode)
                .setPhotoType(MerchantImage.ImageType.SHOP_FRONT_DOOR);
        merImg = merchantImageService.getOne(new QueryWrapper<>(merImg));

        MerchantImage merImg2 = new MerchantImage()
                .setMerchantCode(merchantCode)
                .setPhotoType(MerchantImage.ImageType.STORE_INTERIOR_PHOTO);
        merImg2 = merchantImageService.getOne(new QueryWrapper<>(merImg2));


        JSONObject reqData = new JSONObject();
        reqData.put("merchantNo", merchantId);

        AccountDTO account = accountService.getAccount(mbi.getUserId());

        if ("1".equals(mbi.getMerchantType()) || account.getSettleType().startsWith(Account.SETTLE_TYPE_PRIVATE_ILLEGAL)) {
            reqData.put("managementType", "00");
            reqData.put("storeName", mbi.getAlias());

            String base641 = Base64Util.compressPic(FileUtil.getBase64FromUrl(merImg.getPicUrl()), 150);
            String base642 = Base64Util.compressPic(FileUtil.getBase64FromUrl(merImg2.getPicUrl()), 150);
            reqData.put("shopPhoto", base641);
            reqData.put("storeEnvirPhoto", base642);
        }


        JSONObject resp = ysService.requestApiCommon(YsConfig.WX_AUTH, reqData, YsService.TYPE_AUDIT);

        if ("success".equals(resp.getString("status"))) {
            String applyNo = resp.getString("applyNo");

            // 将之前微信认证请求发生错误的信息直接全部清理
            LambdaQueryWrapper<SubMerchantApplyOrder> qWrapper = Wrappers.lambdaQuery();
            qWrapper.eq(SubMerchantApplyOrder::getMerchantCode, merchantCode)
                    .eq(SubMerchantApplyOrder::getChannelId, 4);

            subMerchantApplyOrderService.remove(qWrapper);

            SubMerchantApplyOrder subMerchantApplyOrder = new SubMerchantApplyOrder()
                    .setMerchantCode(mbi.getMerchantCode())
                    .setSubMchType("WX")
                    .setStatus("0")
                    .setApplyNo(applyNo)
                    .setChannelId(4);

            subMerchantApplyOrderService.save(subMerchantApplyOrder);
        } else {
            String msg = resp.getString("statusMeg");
            log.error("商户微信认证异常{}", msg);
            if (msg.endsWith("该商户状态未注册")) {
                // 类似于没有微信子商户号的情况
                return;
            }

//            throw new MsgException(msg);

            SubMerchantApplyOrder subMerchantApplyOrder = new SubMerchantApplyOrder()
                    .setMerchantCode(mbi.getMerchantCode())
                    .setSubMchType("WX")
                    .setStatus("0")
                    .setRemark(msg)
                    .setResultStatus(SubMerchantApplyOrder.RES_STATUS_COMMIT_ERROR)
                    .setChannelId(4);

            // 先更新
            LambdaUpdateWrapper<SubMerchantApplyOrder> uWrapper = Wrappers.lambdaUpdate();
            uWrapper.eq(SubMerchantApplyOrder::getMerchantCode, merchantCode);
            uWrapper.eq(SubMerchantApplyOrder::getChannelId, 4);
            uWrapper.eq(SubMerchantApplyOrder::getResultStatus, "4");
            uWrapper.set(SubMerchantApplyOrder::getStatus, "0")
                    .set(SubMerchantApplyOrder::getResultStatus, SubMerchantApplyOrder.RES_STATUS_COMMIT_ERROR)
                    .set(SubMerchantApplyOrder::getRemark, msg)
                    .set(SubMerchantApplyOrder::getUpdateTime, new Date());
            boolean updateFlag = subMerchantApplyOrderService.update(uWrapper);
            if (!updateFlag) {
                subMerchantApplyOrderService.save(subMerchantApplyOrder);
            }
        }
    }

    @Override
    public void wxReCert(String merchantId, String merchantCode) {
        var subMerchantApplyOrder = new SubMerchantApplyOrder()
                .setMerchantCode(merchantCode)
                .setStatus("1")
                .setChannelId(4);
        subMerchantApplyOrder = subMerchantApplyOrderService.getOne(new QueryWrapper<>(subMerchantApplyOrder));

        wxCertCancel(merchantId, subMerchantApplyOrder);

        wxCert(merchantId, merchantCode);
    }

    @Override
    public JSONObject wxCertResult(String merchantId, String wxApplyNo) {
        var subMerchantApplyOrder = new SubMerchantApplyOrder()
                .setApplyNo(wxApplyNo)
                .setChannelId(4);

        subMerchantApplyOrder = subMerchantApplyOrderService.getOne(new QueryWrapper<>(subMerchantApplyOrder));

        val reqParam = new JSONObject();
        reqParam.put("applyNo", wxApplyNo);

        var userApp = new UserApp()
                .setMerchantCode(subMerchantApplyOrder.getMerchantCode())
                .setUserType("promoter");
        userApp = userAppService.queryUserApp(userApp);
        val mbi = mbiService.getMerchantBaseInfoByUserId(userApp.getUserId() + "");

        var resp = ysService.requestApiCommon(YsConfig.WX_AUTH_STATUS, reqParam, YsService.TYPE_AUDIT);

        var status = resp.getString("status");
        subMerchantApplyOrder.setResultStatus(status);
        subMerchantApplyOrder.setRemark(resp.getString("rejectReason"));

        val qrcodeData = resp.getString("qrcodeData");
        if (StringUtils.isNotEmpty(qrcodeData)) {
            val inputStream = Base64Util.base64ToInputStream(qrcodeData);
            val fileUrl = OssOperatUtil.upload(inputStream, UUID.randomUUID().toString().replace("-", ""), "png");
            subMerchantApplyOrder.setInfoQrcode(fileUrl);
        }


        List<String> alisaList = new ArrayList<>();
        alisaList.add(userApp.getUserId() + "");
        if ("confirmcontact".equals(status) || "confirmlegalperson".equals(status) || "passed".equals(status)) {
            subMerchantApplyOrder.setStatus("1");
        } else if ("rejected".equals(status) || "freezed".equals(status) || "canceled".equals(status) || "unknow".equals(status)) {
            // 驳回或者未知状态标位已处理
            subMerchantApplyOrder.setStatus("1");
        } else if ("waitting".equals(status)) {
            subMerchantApplyOrder.setRemark("待微信审核");
        }

        subMerchantApplyOrderService.updateById(subMerchantApplyOrder);


        return null;
    }

    @Override
    public JSONObject wxCertCallback(JSONObject certResult) {
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void wxCertCancel(String merchantId, SubMerchantApplyOrder subMerchantApplyOrder) {
        val reqParam = new JSONObject();
        reqParam.put("applyNo", subMerchantApplyOrder.getApplyNo());

        var resp = ysService.requestApiCommon(YsConfig.WX_AUTH_CANCEL, reqParam, YsService.TYPE_AUDIT);
        if ("success".equals(resp.getString("status"))) {
            subMerchantApplyOrder.setStatus("2");
            subMerchantApplyOrderService.saveOrUpdate(subMerchantApplyOrder);
        } else {
            throw new MsgException(resp.getString("statusMeg"));
        }
    }

    @Override
    public void wxCertAuthStatus(String merchantId) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("merchantNo", merchantId);
        JSONObject result = ysService.requestApiCommon(YsConfig.WX_AUTHORIZE_STATUS, jsonObject, YsService.TYPE_AUDIT);

        String authStateX = result.getString("authStateX");
        if (Objects.equals(authStateX, "AUTHORIZE_STATE_AUTHORIZED")) {
            LambdaUpdateWrapper<MerchantChannelStatus> uWrapper = Wrappers.lambdaUpdate();
            uWrapper.set(MerchantChannelStatus::getAuthorizationStatus, MerchantChannelStatus.AUTHORIZATION_STATUS_AUTHORIZED);
            uWrapper.eq(MerchantChannelStatus::getMerchantId, merchantId);
            uWrapper.eq(MerchantChannelStatus::getChannel, 4);
            mcsService.update(uWrapper);
        }
    }
}
