package com.jeequan.jeepay.bizcommons.manage;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.interfaces.paychannel.IIsvmchTerminalService;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.core.model.terminal.TerminalChannelModel;
import com.jeequan.jeepay.core.utils.JeepayKit;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.service.impl.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/***
 * 终端设备管理
 *
 * @author terrfly
 * @date 2022/4/26 17:34
 */
@Slf4j
@Component
public class MchStoreTerminalManage {

    @Autowired private MchStoreTerminalService mchStoreTerminalService;
    @Autowired private MchInfoService mchInfoService;
    @Autowired private MchStoreService mchStoreService;
    @Autowired
    private MchApplymentService mchApplymentService;
    @Autowired private PayInterfaceDefineService payInterfaceDefineService;
    @Autowired private PayInterfaceConfigService payInterfaceConfigService;


    /** add */
    public ApiRes add(MchStoreTerminal record ) {

        if(mchStoreTerminalService.count(MchStoreTerminal.gw().eq(MchStoreTerminal::getMchNo, record.getMchNo())
                .eq(MchStoreTerminal::getStoreId, record.getStoreId()).eq(MchStoreTerminal::getTrmNo, record.getTrmNo())
                .eq(MchStoreTerminal::getAppId, record.getAppId())
        ) > 0 ){
            throw new BizException("当前设备编号已经存在！");
        }

        MchInfo mchInfo = mchInfoService.getById(record.getMchNo());

        record.setMchName(mchInfo.getMchShortName());
        record.setAgentNo(mchInfo.getAgentNo());
        record.setStoreName(mchStoreService.getById(record.getStoreId()).getStoreName());

        record.setChannelBindInfo(new JSONObject());
        mchStoreTerminalService.save(record);
        return ApiRes.ok();
    }


    /** update */
    public ApiRes update(MchStoreTerminal record) {

        // 不允许更改一下信息
        record.setMchNo(null);
        record.setAppId(null);
        record.setStoreId(null);
        record.setAgentNo(null);
        record.setCreatedAt(null);
        record.setUpdatedAt(null);

        mchStoreTerminalService.updateById(record);
        return ApiRes.ok();
    }


    /** update */
    public ApiRes updateDefault(Long trmId, Byte updateFlag) {

        // 查询DB数据
        MchStoreTerminal dbRecord = mchStoreTerminalService.getById(trmId);

        if(dbRecord == null){
            throw new BizException("数据不存在");
        }

        MchStoreTerminal updateRecord = new MchStoreTerminal();
        updateRecord.setTrmId(dbRecord.getTrmId());
        updateRecord.setDefaultFlag(updateFlag);

        if(updateFlag == CS.NO){
            mchStoreTerminalService.updateById(updateRecord);
        }else{

            //更新所有的为 否
            mchStoreTerminalService.update(new LambdaUpdateWrapper<MchStoreTerminal>()
                    .eq(MchStoreTerminal::getMchNo, dbRecord.getMchNo())
                    .eq(MchStoreTerminal::getAppId, dbRecord.getAppId())
                    .eq(MchStoreTerminal::getStoreId, dbRecord.getStoreId())
                    .set(MchStoreTerminal::getDefaultFlag, CS.NO)
            );

            mchStoreTerminalService.updateById(updateRecord);
        }

        return ApiRes.ok();
    }


    /** 报备列表 */
    public ApiRes getChannelBindInfos(Long recordId) {

        MchStoreTerminal dbRecord = mchStoreTerminalService.getById(recordId);

        // 查询出所有的支持通道集合
        List<String> ifCodeList = new ArrayList<>();
        payInterfaceConfigService.list(PayInterfaceConfig.gw().select(PayInterfaceConfig::getIfCode)
                .eq(PayInterfaceConfig::getInfoType, CS.SYS_ROLE_TYPE.MCH_APP)
                .eq(PayInterfaceConfig::getInfoId, dbRecord.getAppId())
                .eq(PayInterfaceConfig::getState, CS.YES)
        ).forEach(r -> ifCodeList.add(r.getIfCode()));

        if(ifCodeList.isEmpty()){
            return ApiRes.ok(ifCodeList);
        }


        JSONObject channelBindInfo = dbRecord.getChannelBindInfo();
        if(channelBindInfo == null){
            channelBindInfo = new JSONObject();
        }

        // 查询出所有的应用集合
        List<PayInterfaceDefine> result = payInterfaceDefineService.list(PayInterfaceDefine.gw().in(PayInterfaceDefine::getIfCode, ifCodeList));
        for (PayInterfaceDefine payInterfaceDefine : result) {

            TerminalChannelModel model = channelBindInfo.getObject(payInterfaceDefine.getIfCode(), TerminalChannelModel.class);

            // 判断是否为空
            if(model == null || model.getState() == null){
                model = new TerminalChannelModel().setState(TerminalChannelModel.STATE_NOT_BIND);
            }

            payInterfaceDefine.addExt("channelBindInfo", model);
        }

        return ApiRes.ok(result);
    }


    /** 终端报备 */
    public ApiRes channelSendup(Long recordId, String ifCode, Byte state) {

        MchStoreTerminal dbRecord = mchStoreTerminalService.getById(recordId);

        JSONObject channelBindInfo = dbRecord.getChannelBindInfo();
        if(channelBindInfo == null){
            channelBindInfo = new JSONObject();
        }

        String storeId = dbRecord.getStoreId();
        MchStore mchStore = mchStoreService.getById(storeId);
        String mchApplyId = mchStore.getMchApplyId();
        MchApplyment mchApplyment = mchApplymentService.getById(mchApplyId);

        // 单独接口的对象
        TerminalChannelModel ifCodeModel = channelBindInfo.getObject(ifCode, TerminalChannelModel.class);
        if(ifCodeModel == null){
            ifCodeModel = new TerminalChannelModel();
        }

        IIsvmchTerminalService isvmchTerminalService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(ifCode) + "IsvmchTerminalService", IIsvmchTerminalService.class);
        if(isvmchTerminalService == null){
            ifCodeModel.setState(TerminalChannelModel.STATE_FAIL).setErrInfo(ifCode + "接口不支持报备操作");
        }else{
            ChannelRetMsg channelRetMsg = isvmchTerminalService.sendup(dbRecord, mchApplyment.getIsvNo(), dbRecord.getMchNo(), dbRecord.getAppId(), ifCode, state == CS.YES);

            // 操作成功
            if(channelRetMsg.getChannelState() == ChannelRetMsg.ChannelState.CONFIRM_SUCCESS){

                ifCodeModel.setErrInfo(null);

                if(state == CS.YES){ // 报备
                    ifCodeModel.setChannelTrmNo(channelRetMsg.getChannelOrderId());
                }else{ // 取消报备
                    ifCodeModel.setChannelTrmNo(null);
                }

                ifCodeModel.setState(state);

            }else{ //操作失败
                ifCodeModel.setState(TerminalChannelModel.STATE_FAIL);
                ifCodeModel.setErrInfo(channelRetMsg.getChannelErrMsg());
            }
        }

        channelBindInfo.put(ifCode, ifCodeModel);

        MchStoreTerminal updateRecord = new MchStoreTerminal().setTrmId(recordId).setChannelBindInfo(channelBindInfo);
        mchStoreTerminalService.updateById(updateRecord);

        return ApiRes.ok();
    }


    /** 修改终端报备信息 */
    public ApiRes updChannelBindInfos(Long recordId, String ifCode, String channelTrmNo, Byte state) {


        MchStoreTerminal dbRecord = mchStoreTerminalService.getById(recordId);

        JSONObject channelBindInfo = dbRecord.getChannelBindInfo();
        if(channelBindInfo == null){
            channelBindInfo = new JSONObject();
        }

        // 单独接口的对象
        TerminalChannelModel ifCodeModel = channelBindInfo.getObject(ifCode, TerminalChannelModel.class);
        if(ifCodeModel == null){
            ifCodeModel = new TerminalChannelModel();
        }

        ifCodeModel.setChannelTrmNo(channelTrmNo);
        ifCodeModel.setState(state);
        channelBindInfo.put(ifCode, ifCodeModel);

        MchStoreTerminal updateRecord = new MchStoreTerminal().setTrmId(recordId).setChannelBindInfo(channelBindInfo);
        mchStoreTerminalService.updateById(updateRecord);

        return ApiRes.ok();
    }


}
