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

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jeequan.jeepay.agent.ctrl.CommonCtrl;
import com.jeequan.jeepay.bizcommons.manage.sms.SmsManager;
import com.jeequan.jeepay.components.mq.model.CleanAgentLoginAuthCacheMQ;
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.smsconfig.SmsBizDiyContentModel;
import com.jeequan.jeepay.db.entity.AgentInfo;
import com.jeequan.jeepay.db.entity.MchInfo;
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.Date;
import java.util.List;
import java.util.Set;

/***
* 服务商管理
*
* @author terrfly
*
* @date 2022/3/15 15:25
*/
@RestController
@RequestMapping("/api/subAgents")
public class SubAgentInfoController extends CommonCtrl {

    @Autowired private IMQSender mqSender;
    @Autowired private SmsManager smsManager;

    @PreAuthorize("hasAuthority('ENT_AGENT_LIST')")
    @GetMapping
    public ApiRes list() {
        AgentInfo agentInfo = getObject(AgentInfo.class);

        LambdaQueryWrapper<AgentInfo> wrapper = AgentInfo.gw();
        wrapper.eq(AgentInfo::getPid, getCurrentAgentNo());
        wrapper.eq(StringUtils.isNotEmpty(agentInfo.getAgentNo()), AgentInfo::getAgentNo, agentInfo.getAgentNo());
        wrapper.eq(StringUtils.isNotEmpty(agentInfo.getIsvNo()), AgentInfo::getIsvNo, agentInfo.getIsvNo());
        wrapper.like(StringUtils.isNotEmpty(agentInfo.getAgentName()), AgentInfo::getAgentName, agentInfo.getAgentName());
        wrapper.eq(agentInfo.getState() != null, AgentInfo::getState, agentInfo.getState());
        wrapper.like(StringUtils.isNotEmpty(agentInfo.getContactTel()), AgentInfo::getContactTel, agentInfo.getContactTel());
        wrapper.like(StringUtils.isNotEmpty(agentInfo.getLoginUsername()), AgentInfo::getLoginUsername, agentInfo.getLoginUsername());
        wrapper.orderByDesc(AgentInfo::getCreatedAt);

        // app端 联合模糊查询字段
        String unionAgentInfo = getValString("unionAgentInfo");
        if (StringUtils.isNotBlank(unionAgentInfo)) {
            wrapper.and(i -> i.like(AgentInfo::getAgentNo, unionAgentInfo)
                    .or().like(AgentInfo::getAgentName, unionAgentInfo)
                    .or().like(AgentInfo::getContactTel, unionAgentInfo));
        }

        IPage<AgentInfo> pages = agentInfoService.page(getIPage(), wrapper);
        for (AgentInfo info:pages.getRecords()) {
            info.setContactTel(DesensitizedUtil.mobilePhone(info.getContactTel()));
            long count = mchInfoService.count(MchInfo.gw().eq(MchInfo::getAgentNo, info.getAgentNo()));
            info.addExt("mchCount", count);
        }
        return ApiRes.page(pages);
    }

    @PreAuthorize("hasAuthority('ENT_AGENT_INFO_ADD')")
    @MethodLog(remark = "新增服务商")
    @PostMapping
    public ApiRes add() {
        // 当前服务商是否允许发展下级代理
        AgentInfo pAgentInfo = agentInfoService.getById(getCurrentAgentNo());
        if (pAgentInfo.getAddAgentFlag() != CS.YES) {
            throw new BizException("当前服务商不可发展下级服务商");
        }

        AgentInfo agentInfo = getObject(AgentInfo.class);
        agentInfo.setPid(getCurrentAgentNo());

        AgentInfo thisAgent = agentInfoService.getById(getCurrentAgentNo());
        agentInfo.setIsvNo(thisAgent.getIsvNo());

        // 获取传入的服务商登录名、登录密码
        String loginPassword = getValString("loginPassword");
        Byte isNotify = getValByteRequired("isNotify");

        if (StringUtils.isBlank(loginPassword)) {
            loginPassword = null;
        }
        agentInfo.setAgentNo("P" + DateUtil.format(new Date(), "yyMMdd")+ RandomUtil.randomNumbers(6));
        // 当前登录用户信息
        SysUser sysUser = getCurrentUser().getSysUser();
        agentInfo.setCreatedUid(sysUser.getSysUserId());
        agentInfo.setCreatedBy(sysUser.getRealname());

        agentInfoService.addAgentV2(agentInfo, loginPassword, true);

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

    @PreAuthorize("hasAuthority('ENT_AGENT_INFO_DEL')")
    @MethodLog(remark = "删除服务商")
    @DeleteMapping(value="/{agentNo}")
    public ApiRes delete(@PathVariable("agentNo") String agentNo) {

        List<Long> userIdList = agentInfoService.removeByAgentNo(agentNo);
        // 推送mq删除redis用户缓存
        mqSender.send(CleanAgentLoginAuthCacheMQ.build(userIdList));

        return ApiRes.ok();
    }

    @PreAuthorize("hasAuthority('ENT_AGENT_INFO_EDIT')")
    @MethodLog(remark = "更新服务商信息")
    @PutMapping(value="/{agentNo}")
    public ApiRes update(@PathVariable("agentNo") String agentNo) {

        AgentInfo dbAgentInfo = agentInfoService.getById(agentNo);
        if (dbAgentInfo == null) {
            throw new BizException("服务商信息不存在");
        }

        //获取查询条件
        AgentInfo agentInfo = getObject(AgentInfo.class);
        agentInfo.setAgentNo(agentNo); //设置服务商号主键

        agentInfo.setIsvNo(null); // 不允许更改
        agentInfo.setPid(null);
        agentInfo.setLoginUsername(null); // 防止修改用户登录名


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

        // 判断要修改的服务商信息是否需要审核 如果为审核失败/待认证->待审核
        if (dbAgentInfo.getState() == AgentInfo.AUDIT_STATE_FALSE || dbAgentInfo.getState() == AgentInfo.AUDIT_STATE_UN_AUTH) {
            agentInfo.setState(AgentInfo.AUDIT_STATE_ING);
        }

        // 更新 & 得到需要删除的用户ID的记录
        Set<Long> removeCacheUserIdList = agentInfoService.updateAgent(agentInfo, getReqParamJSON(), resetPass, confirmPwd);

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

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

        return ApiRes.ok();
    }

    @PreAuthorize("hasAnyAuthority('ENT_AGENT_INFO_EDIT', 'ENT_AGENT_INFO_VIEW')")
    @GetMapping(value="/{agentNo}")
    public ApiRes detail(@PathVariable("agentNo") String agentNo) {
        AgentInfo agentInfo = agentInfoService.getById(agentNo);
        if (agentInfo == null || !agentInfo.getPid().equals(getCurrentAgentNo())) {
            return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
        }

        return ApiRes.ok(agentInfo);
    }
}
