package com.jeequan.jeepay.agent.ctrl.merchant;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.DesensitizedUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.bizcommons.manage.sms.SmsManager;
import com.jeequan.jeepay.components.mq.model.CleanMchLoginAuthCacheMQ;
import com.jeequan.jeepay.components.mq.model.ResetIsvMchAppInfoConfigMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
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.SysUser;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.PrefixConfig;
import com.jeequan.jeepay.core.model.smsconfig.SmsBizDiyContentModel;
import com.jeequan.jeepay.core.utils.SeqKit;
import com.jeequan.jeepay.db.entity.AgentInfo;
import com.jeequan.jeepay.db.entity.MchInfo;
import com.jeequan.jeepay.service.impl.MchInfoService;
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.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 商户管理类
 *
 * @author pangxiaoyu
 * @site https://www.jeequan.com
 * @date 2021-06-07 07:15
 */
@RestController
@RequestMapping("/api/mchInfo")
public class MchInfoController extends CommonCtrl {

    @Autowired private IMQSender mqSender;
    @Autowired private SmsManager smsManager;
    @Autowired private PrefixConfig prefixConfig;
    @Autowired private MchInfoService mchInfoService;

    /**
     * @author: pangxiaoyu
     * @date: 2021/6/7 16:14
     * @describe: 商户信息列表
     */
    @PreAuthorize("hasAuthority('ENT_MCH_LIST')")
    @GetMapping(value = "")
    public ApiRes list() {
        MchInfo mchInfo = getObject(MchInfo.class);
        // 仅查询当前服务商数据
        mchInfo.setAgentNo(getCurrentAgentNo());
        // 扩展员仅查询自己的数据
        if (getCurrentUser().isEpUser()){
            mchInfo.setCreatedUid(getCurrentUser().getSysUser().getSysUserId());
        }
        Page<MchInfo> listPage = mchInfoService.getListPage(getIPage(), mchInfo);
        return ApiRes.page(listPage);
    }

    /**
     * @author: pangxiaoyu
     * @date: 2021/6/7 16:14
     * @describe: 新增商户信息
     */
    @PreAuthorize("hasAuthority('ENT_MCH_INFO_ADD')")
    @MethodLog(remark = "新增商户")
    @PostMapping
    public ApiRes add() {
        AgentInfo pAgentInfo = agentInfoService.getById(getCurrentAgentNo());
        // 当前服务商是否允许发展下级商户
        if (pAgentInfo.getAddMchFlag() != CS.YES) {
            throw new BizException("当前服务商不可发展下级商户");
        }
        MchInfo mchInfo = getObject(MchInfo.class);
        // 获取传入的商户登录名、登录密码
        String loginPassword = getValString("loginPassword");
        Byte isNotify = getValByteRequired("isNotify");
        if (StringUtils.isBlank(loginPassword)) {
            loginPassword = null;
        }
        mchInfo.setMchNo(SeqKit.genMchNo());

        // 当前服务商
        mchInfo.setAgentNo(getCurrentAgentNo());
        mchInfo.setTopAgentNo(agentInfoService.queryTopAgentNo(getCurrentAgentNo()));
        // 商户类型
        mchInfo.setType(MchInfo.TYPE_ISVSUB);
        // 商户级别
        mchInfo.setMchLevel(MchInfo.MCH_LEVEL_M0);
        // 商户退款权限
        JSONArray refundModeArray = new JSONArray();
        refundModeArray.add(MchInfo.REFUND_MODEL_PLAT);
        refundModeArray.add(MchInfo.REFUND_MODEL_API);
        mchInfo.setRefundMode(refundModeArray);

        // 当前登录用户信息
        SysUser sysUser = getCurrentUser().getSysUser();
        mchInfo.setCreatedUid(sysUser.getSysUserId());
        mchInfo.setCreatedBy(sysUser.getRealname());

        mchInfoService.addMch(mchInfo, loginPassword);
        // 发送短信通知
        if (isNotify == CS.YES) {
            smsManager.sendDiyContentSms(SmsBizDiyContentModel.genUserOpenAccount(mchInfo.getContactTel(), mchInfo.getLoginUsername(), loginPassword));
        }
        return ApiRes.ok();
    }

    /**
     * @author: pangxiaoyu
     * @date: 2021/6/7 16:14
     * @describe: 删除商户信息
     */
    @PreAuthorize("hasAuthority('ENT_MCH_INFO_DEL')")
    @MethodLog(remark = "删除商户")
    @RequestMapping(value="/{mchNo}", method = RequestMethod.DELETE)
    public ApiRes delete(@PathVariable("mchNo") String mchNo) {
        MchInfo mchInfo = mchInfoService.getById(mchNo);
        if (mchInfo == null) {
            throw new BizException("该商户不存在");
        }
        if (!mchInfo.getAgentNo().equals(getCurrentAgentNo())) {
            return ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR);
        }
        List<Long> userIdList = mchInfoService.removeByMchNo(mchNo);

        // 推送mq删除redis用户缓存
        mqSender.send(CleanMchLoginAuthCacheMQ.build(userIdList));

        // 推送mq到目前节点进行更新数据
        mqSender.send(ResetIsvMchAppInfoConfigMQ.build(ResetIsvMchAppInfoConfigMQ.RESET_TYPE_MCH_INFO, null, mchNo, null));
        return ApiRes.ok();
    }

    /**
     * @author: pangxiaoyu
     * @date: 2021/6/7 16:14
     * @describe: 更新商户信息
     */
    @PreAuthorize("hasAuthority('ENT_MCH_INFO_EDIT')")
    @MethodLog(remark = "更新商户信息")
    @RequestMapping(value="/{mchNo}", method = RequestMethod.PUT)
    public ApiRes update(@PathVariable("mchNo") String mchNo) {

        //获取查询条件
        MchInfo mchInfo = getObject(MchInfo.class);
        mchInfo.setMchNo(mchNo); //设置商户号主键

        mchInfo.setType(null); //防止变更商户类型
        mchInfo.setAgentNo(null);
//        mchInfo.setIsvNo(null); // 防止变更服务商ID
        mchInfo.setTopAgentNo(null);    // 防止变更顶级代理ID
        mchInfo.setRefundMode(null);    // 防止变更退款权限
        mchInfo.setLoginUsername(null); // 防止修改用户登录名


        MchInfo dbRecord = mchInfoService.getById(mchNo);
        if (dbRecord == null || !getCurrentAgentNo().equals(dbRecord.getAgentNo())) {
            return ApiRes.fail(ApiCodeEnum.SYS_PERMISSION_ERROR);
        }

        // 状态禁止操作：平台停用 -> 启用
        if (mchInfo.getState() != null && mchInfo.getState() == CS.YES && dbRecord.getState() == MchInfo.STATE_NO_MGR) {
            throw new BizException("商户状态停用，请联系运营平台处理");
        }
        // 数据库状态为 由平台停用的，不可修改
        if (dbRecord.getState() == MchInfo.STATE_NO_MGR) {
            mchInfo.setState(null);
        }


        boolean resetPass = getReqParamJSON().getBooleanValue("resetPass");
        String confirmPwd = null;
        if(resetPass){
            confirmPwd = getReqParamJSON().getBoolean("defaultPass") ? null : Base64.decodeStr(getValStringRequired("confirmPwd"));
        }

        // 更新商户 & 得到需要删除的商户用户ID的记录
        Set<Long> removeCacheUserIdList = mchInfoService.updateMch(mchInfo, resetPass, confirmPwd);

        // 推送mq删除redis用户认证信息
        if (!removeCacheUserIdList.isEmpty()) {
            mqSender.send(CleanMchLoginAuthCacheMQ.build(new ArrayList<>(removeCacheUserIdList)));
        }

        // 推送mq到目前节点进行更新数据
        mqSender.send(ResetIsvMchAppInfoConfigMQ.build(ResetIsvMchAppInfoConfigMQ.RESET_TYPE_MCH_INFO, null, mchNo, null));

        return ApiRes.ok();
    }

    /**
     * @author: pangxiaoyu
     * @date: 2021/6/7 16:14
     * @describe: 查询商户信息
     */
    @PreAuthorize("hasAnyAuthority('ENT_MCH_INFO_VIEW', 'ENT_MCH_INFO_EDIT')")
    @RequestMapping(value="/{mchNo}", method = RequestMethod.GET)
    public ApiRes detail(@PathVariable("mchNo") String mchNo) {
        MchInfo mchInfo = mchInfoService.getById(mchNo);
        if (mchInfo == null) {
            return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
        }

        if (mchInfo.getState() == MchInfo.STATE_NO_MGR) {
            mchInfo.setState(CS.NO);
        }

        return ApiRes.ok(mchInfo);
    }
}
