package com.jeequan.jeepay.mch.ctrl.qrcode;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.icbc.api.internal.apache.http.impl.cookie.S;
import com.jeequan.jeepay.core.aop.MethodLog;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.entity.MchInfo;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.QRCodeParams;
import com.jeequan.jeepay.core.utils.JeepayKit;
import com.jeequan.jeepay.core.utils.SeqKit;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.mch.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.*;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 商户应用管理类
 *
 * @author zhuxiao
 *
 * @date 2021-06-16 09:15
 */
@RestController
@RequestMapping("/api/mchQrCodes")
public class MchQrCodeController extends CommonCtrl {

    @Autowired private MchQrcodeCardService mchQrcodeCardService;
    @Autowired private MchStoreService mchStoreService;
    @Autowired private MchAppService mchAppService;
    @Autowired private MchInfoService mchInfoService;
    @Autowired private MchApplymentService mchApplymentService;
    @Autowired private MchQrcShellService mchQrcShellService;

    @PreAuthorize("hasAuthority('ENT_MCH_QR_CODE_LIST')")
    @GetMapping
    public ApiRes list() {

       String  appSearchData=getValString("appSearchData");

        // 构造查询条件
        MchQrcodeCard mchQrCode = getObject(MchQrcodeCard.class);

        if(ObjectUtils.isNotEmpty(appSearchData)){

            mchQrCode.setQrcAlias(appSearchData);
        }


//        mchQrCode.setBindState(CS.YES);
        mchQrCode.setMchNo(getCurrentMchNo());
        // 门店条件
        List<String> storeIdList = getCurrentUser().getStoreIdList();
        if (CollectionUtil.isNotEmpty(storeIdList)) {
            mchQrCode.setStoreIdList(storeIdList);
        }

        IPage<MchQrcodeCard> resut = mchQrcodeCardService.selectPageRecords(getIPage(), mchQrCode);
        return ApiRes.page(resut);
    }

    @PreAuthorize("hasAuthority('ENT_MCH_QR_CODE_ADD')")
    @MethodLog(remark = "新建商户自制码牌")
    @PostMapping
    public ApiRes add() {

        // 处理金额类型
        handleParamAmount("fixedPayAmount");
        MchQrcodeCard mchQrCode = getObject(MchQrcodeCard.class);
        mchQrCode.setMchNo(getCurrentMchNo());
        mchQrCode.setQrcBelongType(MchQrcodeCard.QRC_BELONG_TYPE_MCH); // 商户自制码牌
        // ID
        mchQrCode.setQrcId(SeqKit.genQrcodeCardId());
        // 未传入商户appId 则使用默认应用
        if(StringUtils.isEmpty(mchQrCode.getAppId())){
            mchQrCode.setAppId(mchAppService.getDefaultApp(getCurrentMchNo()).getAppId());
        }
        MchStore mchStore = mchStoreService.getById(mchQrCode.getStoreId());
        if(mchStore == null){
            throw new BizException("门店不存在！");
        }
        if(StringUtils.isEmpty(mchStore.getBindAppId())){
            MchApplyment applyment = mchApplymentService.getById(mchStore.getMchApplyId());
            mchQrCode.setAppId(applyment.getAutoConfigMchAppId());
        }else{
            mchQrCode.setAppId(mchStore.getBindAppId());
        }
        if(StringUtils.isEmpty(mchQrCode.getAlipayWayCode())){
            mchQrCode.setAlipayWayCode(CS.PAY_WAY_CODE.ALI_JSAPI);
        }
        // 默认已绑定
        mchQrCode.setBindState(CS.YES);
        //获取默认的二维码模板
        MchQrcShell qrcShell = mchQrcShellService.getDefaultTemplate(CS.SYS_ROLE_TYPE.PLATFORM);
        if(qrcShell != null){
            mchQrCode.setQrcShellId(qrcShell.getSid());
        }
        //获取商户信息
        if (StringUtils.isNotEmpty(mchStore.getMchApplyId())){
            MchApplyment applyment = mchApplymentService.getById(mchStore.getMchApplyId());
            if (applyment != null){
                mchQrCode.setMchApplyName(applyment.getMchShortName());
                mchQrCode.setMchApplyId(mchStore.getMchApplyId());
            }
        }
        boolean result = mchQrcodeCardService.save(mchQrCode);
        if (!result) {
            return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
        }
        return ApiRes.ok();
    }

    @PreAuthorize("hasAnyAuthority('ENT_MCH_QR_CODE_VIEW', 'ENT_MCH_QR_CODE_EDIT')")
    @GetMapping("/{recordId}")
    public ApiRes detail(@PathVariable("recordId") Long recordId) {

        MchQrcodeCard dbRecord = mchQrcodeCardService.getById(recordId);

        if (dbRecord == null || !dbRecord.getMchNo().equals(getCurrentMchNo())) {
            return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
        }

        // 添加商户、门店、应用名称
        if (dbRecord.getBindState() == CS.YES) {
            if (dbRecord.getStoreId() != null) {
                MchStore mchStore = mchStoreService.getById(dbRecord.getStoreId());
                if (mchStore != null) {
                    dbRecord.addExt("storeName", mchStore.getStoreName());
                }
            }

            if (StringUtils.isNotBlank(dbRecord.getAppId())) {
                MchAppEntity mchAppEntity = mchAppService.getById(dbRecord.getAppId());
                if (mchAppEntity != null) {
                    dbRecord.addExt("appName", mchAppEntity.getAppName());
                }
            }
        }
        MchApplyment mchApplyment = mchApplymentService.getById(dbRecord.getMchApplyId());
        // 封装URL
        dbRecord.addExt("qrUrl", sysConfigService.getDBApplicationConfig().genUniJsapiPayUrl(QRCodeParams.TYPE_QRC, dbRecord.getEntryPage(), recordId + "", mchApplyment.getIsvNo()));
        return ApiRes.ok(dbRecord);
    }

    @PreAuthorize("hasAuthority('ENT_MCH_QR_CODE_EDIT')")
    @MethodLog(remark = "更新二维码信息")
    @PutMapping("/{recordId}")
    public ApiRes update(@PathVariable("recordId") Long recordId) {

        // 处理金额类型
        handleParamAmount("fixedPayAmount");

        MchQrcodeCard mchQrCode = getObject(MchQrcodeCard.class);
        mchQrCode.setQrcId(recordId);
        mchQrCode.setCreatedAt(null);
        mchQrCode.setUpdatedAt(null);

        MchQrcodeCard dbRecord = mchQrcodeCardService.getById(recordId);
        if (dbRecord == null || !dbRecord.getMchNo().equals(getCurrentMchNo())) {
            throw new BizException("无权操作！");
        }

        mchQrcodeCardService.updateOrReBindQR(mchQrCode, dbRecord);

        return ApiRes.ok();
    }

    @PreAuthorize("hasAuthority('ENT_MCH_QR_CODE_DEL')")
    @MethodLog(remark = "删除二维码")
    @DeleteMapping("/{recordId}")
    public ApiRes delete(@PathVariable("recordId") Long recordId) {
        MchQrcodeCard mchQrCode = mchQrcodeCardService.getById(recordId);

        if (!mchQrCode.getMchNo().equals(getCurrentMchNo())) {
            throw new BizException("无权操作！");
        }

        mchQrcodeCardService.removeById(recordId);
        return ApiRes.ok();
    }



    /** 解析二维码 && 验证二维码是否可绑定 **/
    @GetMapping("/parseQrCodeUrl")
    public ApiRes parseQrCodeUrl() {

        String url = getValStringRequired("qrUrl");

        // 不是支付平台开头的， 说明不是可用二维码
        if(!url.startsWith(sysConfigService.getDBApplicationConfig().getPaySiteUrl())){
            throw new BizException("二维码解析失败");
        }

        int tokenIndex = url.indexOf(JeepayKit.TOKEN_KEY + "=");
        if(tokenIndex <= 0){
            throw new BizException("二维码解析失败");
        }

        String token = url.substring(tokenIndex + 12);

        QRCodeParams qrCodeParams = JSON.parseObject(JeepayKit.aesDecode(token), QRCodeParams.class); //解析token

        MchQrcodeCard mchQrcodeCard = mchQrcodeCardService.getById(qrCodeParams.getId());

        // 不存在  不可用 已绑定
        if(mchQrcodeCard == null || mchQrcodeCard.getQrcState() != CS.YES || mchQrcodeCard.getBindState() != CS.NO){
            throw new BizException("当前码牌被解绑或已被停用");
        }

        return ApiRes.ok(mchQrcodeCard.getQrcId());
    }

    /** 绑定空码 **/
    @PostMapping("/bindEmptyQR")
    @PreAuthorize("hasAuthority('ENT_MCH_QR_CODE_ADD')")
    public ApiRes bindEmptyQR() {

        // 处理金额类型
        handleParamAmount("fixedPayAmount");

        MchQrcodeCard record = getObject(MchQrcodeCard.class);
        record.setMchNo(getCurrentMchNo());

        MchInfo mchInfo = mchInfoService.getById(getCurrentMchNo());
        record.setAgentNo(mchInfo.getAgentNo());

        MchQrcodeCard mchQrcodeCard = mchQrcodeCardService.getById( record.getQrcId());

        // 不存在  不可用 已绑定
        if(mchQrcodeCard == null){
            throw new BizException("当前码牌已被删除，不支持绑定，请更换其他码牌");
        }

        if(CS.YES == mchQrcodeCard.getBindState() || CS.NO == mchQrcodeCard.getQrcState()){
            throw new BizException("当前码牌已被停用或已被其他门店绑定");
        }

        if(MchQrcodeCard.QRC_TYPE_DZ == mchQrcodeCard.getQrcType()){
            throw new BizException("当前码牌为电子码牌，不支持绑定");
        }

        // 未传入商户appId 则使用默认应用
        if(StringUtils.isEmpty(record.getAppId())){
            record.setAppId(mchAppService.getDefaultApp(getCurrentMchNo()).getAppId());
        }

        if(record.getStoreId() == null ){
            throw new BizException("请选择门店");
        }
        //获取商户信息
        MchStore mchStore = mchStoreService.getById(record.getStoreId());
        if (StringUtils.isNotEmpty(mchStore.getMchApplyId())){
            MchApplyment applyment = mchApplymentService.getById(mchStore.getMchApplyId());
            if (applyment != null){
                record.setMchApplyName(applyment.getMchShortName());
                record.setMchApplyId(mchStore.getMchApplyId());
            }
        }

        record.setBindState(CS.YES); //已绑定

        mchQrcodeCardService.bindEmptyQR(record);

        return ApiRes.ok();
    }

    /**
     * @Author: zx
     * @Description: 解绑码牌
     * @Date: 15:59 2022/5/30
    */
    @PreAuthorize("hasAuthority('ENT_MCH_QR_CODE_EDIT')")
    @PostMapping("/unbind/{qrcId}")
    public ApiRes unbind(@PathVariable("qrcId") Long qrcId) {

        MchQrcodeCard dbRecord = mchQrcodeCardService.getById(qrcId);
        if (dbRecord == null || !dbRecord.getMchNo().equals(getCurrentMchNo()) || dbRecord.getQrcBelongType() != MchQrcodeCard.QRC_BELONG_TYPE_ISV_PRE) {
            return ApiRes.customFail("解绑失败");
        }

        mchQrcodeCardService.unbind(dbRecord);

        return ApiRes.ok();
    }

    /**
     * @Author: zx
     * @Description: 查看码牌绑定的设备列表
     * @Date: 15:59 2022/5/30
     */
    @PreAuthorize("hasAuthority('ENT_MCH_QR_CODE_EDIT')")
    @GetMapping("/bindDevice/{qrcId}")
    public ApiRes bindDevice(@PathVariable("qrcId") Long qrcId) {

        MchQrcodeCard dbRecord = mchQrcodeCardService.getById(qrcId);
        if (dbRecord == null || !dbRecord.getMchNo().equals(getCurrentMchNo())) {
            return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
        }

        IPage<MchStoreDevice> page = mchQrcodeCardService.getBindDevice(getIPage(), dbRecord, null);
        //返回门店名称
        for (MchStoreDevice record : page.getRecords()) {
            if (StringUtils.isNotEmpty(record.getStoreId())){
                MchStore mchStore = mchStoreService.getById(record.getStoreId());
                record.setStoreName(mchStore.getStoreName());
            }
        }
        return ApiRes.page(page);
    }

    /**
     * 根据设备号判断马牌设备是否绑定
     * @return
     */
    @GetMapping("/checkQrCodeBind/{qrcId}")
    public ApiRes checkQrCodeBind(@PathVariable("qrcId") String qrcId) {
        JSONObject res = new JSONObject();
        res.put("checkCode", "1");
        res.put("checkMsg", "当前设备允许绑定");
        try {
            mchQrcodeCardService.checkQrCodeBind(qrcId);
        }catch (BizException e){
            res.put("checkCode", "0");
            res.put("checkMsg", e.getMessage());
        }
        return ApiRes.ok(res);
    }
}
