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

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.converter.MchInfoConverter;
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.MchApp;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.Capability;
import com.jeequan.jeepay.core.utils.SeqKit;
import com.jeequan.jeepay.db.entity.*;
import com.jeequan.jeepay.mgr.config.SystemYmlConfig;
import com.jeequan.jeepay.mgr.ctrl.CommonCtrl;
import com.jeequan.jeepay.service.impl.MchAppService;
import com.jeequan.jeepay.service.impl.PackageOrderService;
import com.jeequan.jeepay.service.impl.ProductAppConnService;
import com.jeequan.jeepay.service.impl.ProductInfoService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 商户应用管理类
 */
@RestController
@RequestMapping("/api/mchApps")
public class MchAppController extends CommonCtrl {

    @Autowired
    private MchAppService mchAppService;
    @Autowired
    private SystemYmlConfig systemYmlConfig;
    @Autowired
    private PackageOrderService packageOrderService;
    @Autowired
    private ProductAppConnService productAppConnService;
    @Autowired
    private ProductInfoService productInfoService;
    @Autowired
    private MchInfoConverter mchInfoConverter;

    /**
     * @Author: ZhuXiao
     * @Description: 应用列表
     * @Date: 9:59 2021/6/16
     */
    @PreAuthorize("hasAuthority('ENT_MCH_APP_LIST')")
    @GetMapping
    public ApiRes list() {
        MchAppEntity mchAppEntity = getObject(MchAppEntity.class);

        IPage<MchAppEntity> pages = mchAppService.selectPage(getIPage(true), mchAppEntity);

        return ApiRes.ok(pages);
    }

    /**
     * @Author: ZhuXiao
     * @Description: 新建应用
     * @Date: 10:05 2021/6/16
     */
    @PreAuthorize("hasAuthority('ENT_MCH_APP_ADD')")
    @MethodLog(remark = "新建应用")
    @PostMapping
    public ApiRes add() {
        MchApp mchApp = getObject(MchApp.class);
        mchApp.setAppId(SeqKit.getMchAppId());
        MchInfo mchInfo = mchInfoService.getById(mchApp.getMchNo());
        if (mchInfo == null) {
            return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
        }
        mchApp.setAgentNo(mchInfo.getAgentNo());
        mchApp.setTopAgentNo(mchInfo.getTopAgentNo());
        //默认设置为审核中
        mchApp.setState(MchAppEntity.AUDIT);

        // 如果当前为默认
        if (mchApp.getDefaultFlag() == CS.YES) {
            mchAppService.update(new LambdaUpdateWrapper<MchAppEntity>()
                    .set(MchAppEntity::getDefaultFlag, CS.NO)
                    .eq(MchAppEntity::getMchNo, mchApp.getMchNo())
            );
        }

        // 根据功能code获取功能的信息
        List<Capability> openFuncList = new ArrayList<>();
        if (!CollUtil.isEmpty(mchApp.getCapabilityCodeList())){
            for (String code : mchApp.getCapabilityCodeList()) {
                Capability capability = Capability.MAP.get(code);
                Assert.notNull(capability, "非法的功能代码");

                openFuncList.add(capability);
            }
        }
        mchApp.setPreCapabilities(openFuncList);

        boolean result = mchAppService.save(mchInfoConverter.toDbEntity(mchApp));
        if (!result) {
            return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_CREATE);
        }
        return ApiRes.ok();
    }

    /**
     * @Author: ZhuXiao
     * @Description: 应用详情
     * @Date: 10:13 2021/6/16
     */
    @PreAuthorize("hasAnyAuthority('ENT_MCH_APP_VIEW', 'ENT_MCH_APP_EDIT')")
    @GetMapping("/{appId}")
    public ApiRes detail(@PathVariable("appId") String appId) {
        MchAppEntity mchAppEntity = mchAppService.selectById(appId);
        if (mchAppEntity == null) {
            return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_SEARCH);
        }
        return ApiRes.ok(mchAppEntity);
    }

    /**
     * @Author: ZhuXiao
     * @Description: 更新应用信息
     * @Date: 10:11 2021/6/16
     */
    @PreAuthorize("hasAuthority('ENT_MCH_APP_EDIT')")
    @MethodLog(remark = "更新应用信息")
    @PutMapping("/{appId}")
    public ApiRes update(@PathVariable("appId") String appId) {
        MchApp mchApp = getObject(MchApp.class);
        mchApp.setAppId(appId);

        MchAppEntity dbMchAppEntity = mchAppService.getById(appId);
        if (!dbMchAppEntity.getDefaultFlag().equals(mchApp.getDefaultFlag())) {
            // 如果修改当前为默认
            if (mchApp.getDefaultFlag() == CS.YES) {
                mchAppService.update(new LambdaUpdateWrapper<MchAppEntity>()
                        .set(MchAppEntity::getDefaultFlag, CS.NO)
                        .eq(MchAppEntity::getMchNo, dbMchAppEntity.getMchNo())
                );
            } else {
                throw new BizException("应用不可修改为非默认！");
            }
        }

        // 根据功能code获取功能的信息
        List<Capability> openFuncList = new ArrayList<>();
        if (!CollUtil.isEmpty(mchApp.getCapabilityCodeList())){
            for (String code : mchApp.getCapabilityCodeList()) {
                Capability capability = Capability.MAP.get(code);
                Assert.notNull(capability, "非法的功能代码");

                openFuncList.add(capability);
            }
        }
        mchApp.setPreCapabilities(openFuncList);

        boolean result = mchAppService.updateById(mchInfoConverter.toDbEntity(mchApp));
        if (!result) {
            return ApiRes.fail(ApiCodeEnum.SYS_OPERATION_FAIL_UPDATE);
        }
        return ApiRes.ok();
    }

    /**
     * @Author: ZhuXiao
     * @Description: 删除应用
     * @Date: 10:14 2021/6/16
     */
    @PreAuthorize("hasAuthority('ENT_MCH_APP_DEL')")
    @MethodLog(remark = "删除应用")
    @DeleteMapping("/{appId}")
    public ApiRes delete(@PathVariable("appId") String appId) {

        MchAppEntity mchAppEntity = mchAppService.getById(appId);
        mchAppService.removeByAppId(appId);
        return ApiRes.ok();
    }


    /**
     * 功能描述: 查询系统公钥
     */
    @PreAuthorize("hasAnyAuthority('ENT_MCH_APP_ADD', 'ENT_MCH_APP_EDIT')")
    @GetMapping("/sysRSA2PublicKey")
    public ApiRes sysRSA2PublicKey() {
        return ApiRes.ok(systemYmlConfig.getSysRSA2PublicKey());
    }

    @GetMapping("/getNewProductList")
    @MethodLog(remark = "新获取产品列表")
    public ApiRes getNewProductList() {
        String appId = getValString("appId");
        if (StringUtils.isBlank(appId)) {
            return ApiRes.customFail("appId不能为空!");
        }
        //获取已审核通过和正在审核的产品列表包括产品和商户的绑定关系
        //1.获取t_product_app表中已经通过审核和待审核的数据并拿到product_id
        LambdaQueryWrapper<PackageOrder> appWrapper = new LambdaQueryWrapper<>();
        appWrapper.in(PackageOrder::getState, PackageOrder.STATE_AUDITING, PackageOrder.STATE_SUCCESS);
        List<PackageOrder> appList = packageOrderService.list(appWrapper);
        List<String> productIdCollect = appList.stream()
                .map(PackageOrder::getProductId)
                .collect(Collectors.toList());
        //2通过product_id获取到具体的产品信息
        LambdaQueryWrapper<ProductInfo> infoWrapper = new LambdaQueryWrapper<>();
        infoWrapper.in(ProductInfo::getProductId, productIdCollect);
        List<ProductInfo> infoList = productInfoService.list(infoWrapper);
        //3.获取关联关系
        // 获取当前商户信息
        String mchNo = getCurrentUser().getSysUser().getBelongInfoId();
        //合并信息，通过审核和待审核的产品和当前appid绑定的数据，有则返回1，没有则为0
        for (ProductInfo itemProductInfo : infoList) {
            String productId = itemProductInfo.getProductId();
            LambdaQueryWrapper<ProductAppConn> appConnWrapper = new LambdaQueryWrapper<>();
            appConnWrapper.eq(ProductAppConn::getProductId, productId)
                    .eq(ProductAppConn::getAppId, appId)
                    .eq(ProductAppConn::getState, 1)
                    .eq(ProductAppConn::getMchNo, mchNo);
            //传入审核状态
            List<PackageOrder> appStateList = appList.stream().filter(u -> productId.equals(u.getProductId())).collect(Collectors.toList());
            if (!appStateList.isEmpty()) {
                int checkState = appStateList.get(0).getState();
                itemProductInfo.setCheckState(checkState);
            }
            //添加绑定状态
            List<ProductAppConn> appConnList = productAppConnService.list(appConnWrapper);
            if (!appConnList.isEmpty()) {
                itemProductInfo.setState(1);
            } else {
                itemProductInfo.setState(0);
            }
        }
        Page page = new Page();
        page.setRecords(infoList);
        page.setTotal(infoList.size());
        page.setCurrent(1);
        return ApiRes.ok(page);
    }

    @PreAuthorize("hasAnyAuthority('ENT_MCH_APP_AUDIT')")
    @PostMapping("/audit")
    public ApiRes audit() {
        MchAppEntity mchApp = getObject(MchAppEntity.class);
        mchAppService.audit(mchApp);
        return ApiRes.ok();
    }
}
