package com.mmc.iuav.user.service.fdd.impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.fadada.sdk.base.client.FddBaseClient;
import com.fadada.sdk.base.model.req.AddSignatureParams;
import com.fadada.sdk.extra.client.FddExtraClient;
import com.fadada.sdk.extra.model.req.DefaultSignatureParams;
import com.fadada.sdk.extra.model.req.QuerySignatureParams;
import com.fadada.sdk.extra.model.req.RemoveSignatureParams;
import com.mmc.iuav.page.PageResult;
import com.mmc.iuav.response.ResultBody;
import com.mmc.iuav.response.ResultEnum;
import com.mmc.iuav.user.constant.fdd.FddConnectConstant;
import com.mmc.iuav.user.constant.fdd.FddConstant;
import com.mmc.iuav.user.dao.UserServiceDao;
import com.mmc.iuav.user.dao.fdd.SealManageDao;
import com.mmc.iuav.user.dao.fdd.UserFddAuthDao;
import com.mmc.iuav.user.entity.UserAccountDO;
import com.mmc.iuav.user.entity.fdd.SealInfoDO;
import com.mmc.iuav.user.entity.fdd.UserFddDO;
import com.mmc.iuav.user.model.dto.LoginSuccessDTO;
import com.mmc.iuav.user.model.fdd.dto.SealInfoDTO;
import com.mmc.iuav.user.model.fdd.seal.SealDetail;
import com.mmc.iuav.user.model.fdd.vo.SealInfoVO;
import com.mmc.iuav.user.model.fdd.vo.SealVO;
import com.mmc.iuav.user.service.fdd.SealManageService;
import com.mmc.iuav.user.service.fdd.UserFddAuthService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author LW
 * @date 2022/8/31 17:29
 * 概要：
 */
@Service
public class SealManageServiceImpl implements SealManageService {
    @Resource
    UserServiceDao userServiceDao;
    @Resource
    UserFddAuthService userFddAuthService;
    @Resource
    UserFddAuthDao userFddAuthDao;
    @Resource
    SealManageDao sealManageDao;

    @Override
    public ResultBody uploadSeal(SealVO sealVO, LoginSuccessDTO loginSuccessDTO) {
        ResultBody resultBody = this.checkAuthStatus(sealVO.getPort(), loginSuccessDTO);
        if (!resultBody.getCode().equals("200")) {
            return resultBody;
        }
        UserFddDO userFddInfo = (UserFddDO) resultBody.getResult();
        sealVO.setUnionId(userFddInfo.getUnionId());
        FddBaseClient baseClient = new FddBaseClient(FddConnectConstant.APP_ID, FddConnectConstant.APP_KEY, FddConnectConstant.VERSION, FddConnectConstant.HOST);
        AddSignatureParams params = new AddSignatureParams();
        //客户编号
        params.setCustomerId(userFddInfo.getCustomerId());
        //下面章图片base64、签章图片、图片公网地址三选一
//        params.setSignatureImgBase64(""); //签章图片base64
//        params.setFile(new File("D:\\sign.png")); //签章图片
        //签章图片公网地址
        params.setImgUrl(sealVO.getSealUrl());
        String result = baseClient.invokeAddSignature(params);
        if (!JSONObject.parseObject(result).getString(FddConstant.CODE).equals(FddConstant.SUCCESS)) {
            return ResultBody.error(JSONObject.parseObject(result).getString(FddConstant.MSG));
        } else {
            // 根据当前用户查询印章列表
            getSealInfoListByUnionId(sealVO.getUnionId());
            // 获取返回的印章编号
            String dataStr = JSONObject.parseObject(result).getString(FddConstant.DATA);
            String signatureId = JSONObject.parseObject(dataStr).getString(FddConstant.SIGNATURE_ID);
            SealInfoDO sealInfoDO = new SealInfoDO();
            sealInfoDO.setSealName(sealVO.getSealName());
            sealInfoDO.setSignatureId(signatureId);
            sealInfoDO.setUnionId(sealVO.getUnionId());
            sealInfoDO.setSealUrl(sealVO.getSealUrl());
            // 新增印章信息
            sealManageDao.insertSealInfo(sealInfoDO);
            return ResultBody.success();
        }
    }

    private void getSealInfoListByUnionId(String unionId) {
        List<SealInfoDO> sealInfoList = sealManageDao.getSealInfoListByUnionId(unionId);
        // 判断是否有状态是默认的章(默认：0 非默认：1)
        List<Integer> sealIds = sealInfoList.stream()
                .filter(d -> d.getSealStatus() == 1)
                .map(SealInfoDO::getId).collect(Collectors.toList());
        // 将默认章的状态进行更换
        if (sealIds.size() > 0) {
            sealManageDao.updateSealStatusById(sealIds);
        }
    }

    @Override
    public PageResult getSealInfoList(SealInfoVO param, LoginSuccessDTO loginSuccessDTO) {
        if (param.getPort().equals(0)) {
            UserAccountDO userInfo = userServiceDao.getUserAccountById(loginSuccessDTO.getUserAccountId());
            param.setUId(userFddAuthService.replaceUnableString(userInfo.getUnionId()));
        } else {
            param.setUId(loginSuccessDTO.getUserAccountId().toString());
        }
        int count = sealManageDao.countSealInfo(param);
        if (count == 0) {
            return PageResult.buildPage(param.getPageNo(), param.getPageSize(), count);
        }
        Integer pageNo = param.getPageNo();
        param.buildCurrentPage();
        // 获取印章列表信息
        List<SealInfoDO> sealInfoList = sealManageDao.getSealInfoList(param);
        List<SealInfoDTO> list = sealInfoList.stream().map(SealInfoDO::buildSealInfoDTO).collect(Collectors.toList());
        return PageResult.buildPage(pageNo, param.getPageSize(), count, list);
    }

    @Override
    public ResultBody removeSeal(String signatureId, Integer port, LoginSuccessDTO loginSuccessDTO) {
        ResultBody resultBody = checkAuthStatus(port, loginSuccessDTO);
        if (!resultBody.getCode().equals("200")) {
            return resultBody;
        }
        UserFddDO userFddInfo = (UserFddDO) resultBody.getResult();
        // 调用法大大删除印章接口
        FddExtraClient client = new FddExtraClient(FddConnectConstant.APP_ID, FddConnectConstant.APP_KEY, FddConnectConstant.VERSION, FddConnectConstant.HOST);
        RemoveSignatureParams params = new RemoveSignatureParams();
        params.setCustomerId(userFddInfo.getCustomerId());
        params.setSignatureId(signatureId);
        String result = client.invokeRemoveSignature(params);
        if (!JSONObject.parseObject(result).getString(FddConstant.CODE).equals(FddConstant.SUCCESS)) {
            return ResultBody.error(JSONObject.parseObject(result).getString(FddConstant.MSG));
        }
        sealManageDao.deletedSealInfo(signatureId);
        return ResultBody.success();
    }


    @Override
    @Transactional
    public ResultBody checkAuthStatus(Integer port, LoginSuccessDTO loginSuccessDTO) {
        String uid;
        if (port.equals(0)) {
            UserAccountDO userInfo = userServiceDao.getUserAccountById(loginSuccessDTO.getUserAccountId());
            String unionId = userInfo.getUnionId();
            uid = userFddAuthService.replaceUnableString(unionId);

            UserFddDO userFddInfo = userFddAuthDao.getAppUserFddInfo(uid);
            if (userFddInfo == null) {
                uid = userFddAuthService.replaceUnableString(userInfo.getOpenId());
            } else {
                Integer accountType = userFddInfo.getAccountType();
                Integer personVerifyStatus = userFddInfo.getPersonVerifyStatus();
                Integer entVerifyStatus = userFddInfo.getEntVerifyStatus();

                boolean isPersonVerified = accountType.equals(1) && !personVerifyStatus.equals(2);
                boolean isEntVerified = accountType.equals(2) && !entVerifyStatus.equals(4);

                if (isPersonVerified || isEntVerified) {
                    uid = userFddAuthService.replaceUnableString(userInfo.getOpenId());
                }
            }
        } else {
            uid = loginSuccessDTO.getUserAccountId().toString();
        }
        // 获取用户法大大的（实名/企业）认证信息
        UserFddDO userFddInfo = userFddAuthDao.getAppUserFddInfo(uid);
        if (userFddInfo == null) {
            return ResultBody.error(ResultEnum.BUSINESS_LICENSE_CHECK_ERROR);
        }
        boolean isPersonVerified = userFddInfo.getAccountType().equals(1) && userFddInfo.getPersonVerifyStatus().equals(2);
        boolean isEntVerified = userFddInfo.getAccountType().equals(2) && userFddInfo.getEntVerifyStatus().equals(4);
        if (!isPersonVerified && !isEntVerified) {
            return ResultBody.error(ResultEnum.BUSINESS_LICENSE_CHECK_NOT_PASS);
        }
        return ResultBody.success(userFddInfo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultBody defaultSeal(String signatureId, Integer port, LoginSuccessDTO loginSuccessDTO) {
        ResultBody resultBody = checkAuthStatus(port, loginSuccessDTO);
        if (!resultBody.getCode().equals("200")) {
            return resultBody;
        }
        UserFddDO userFddInfo = (UserFddDO) resultBody.getResult();
        FddExtraClient client = new FddExtraClient(FddConnectConstant.APP_ID, FddConnectConstant.APP_KEY, FddConnectConstant.VERSION, FddConnectConstant.HOST);
        DefaultSignatureParams params = new DefaultSignatureParams();
        params.setCustomerId(userFddInfo.getCustomerId());
        params.setSignatureId(signatureId);
        String result = client.invokeDefaultSignature(params);
        // 获取印章列表
        getSealInfoListByUnionId(userFddInfo.getUnionId());
        sealManageDao.updateSealStatusBySignatureId(signatureId);
        if (!JSONObject.parseObject(result).getString(FddConstant.CODE).equals(FddConstant.SUCCESS)) {
            // 如果失败，手动回滚修改的数据
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultBody.error(JSONObject.parseObject(result).getString(FddConstant.MSG));
        }
        return ResultBody.success();
    }

    @Override
    public ResultBody getSealInfo(String signatureId, Integer port, LoginSuccessDTO loginSuccessDTO) {
        ResultBody resultBody = checkAuthStatus(port, loginSuccessDTO);
        if (!resultBody.getCode().equals("200")) {
            return resultBody;
        }
        UserFddDO userFddInfo = (UserFddDO) resultBody.getResult();
        FddExtraClient client = new FddExtraClient(FddConnectConstant.APP_ID, FddConnectConstant.APP_KEY, FddConnectConstant.VERSION, FddConnectConstant.HOST);
        QuerySignatureParams params = new QuerySignatureParams();
        params.setCustomerId(userFddInfo.getCustomerId());
        params.setSignatureId(signatureId);
        String result = client.invokeQuerySignature(params);
        if (!JSONObject.parseObject(result).getString(FddConstant.CODE).equals(FddConstant.SUCCESS)) {
            return ResultBody.error(JSONObject.parseObject(result).getString(FddConstant.MSG));
        }
        String dataStr = JSONObject.parseObject(result).getString(FddConstant.DATA);
        return ResultBody.success(this.buildSealDetail(dataStr));
    }

    /**
     * 构建印章信息对象
     */
    public SealDetail buildSealDetail(String result) {
        JSONObject jsonObject = JSONArray.parseArray(result).getJSONObject(0);
        SealDetail sealDetail = new SealDetail();
        sealDetail.setSignatureImg(jsonObject.getString("signature_img_base64"));
        sealDetail.setSignatureId(jsonObject.getString("signature_id"));
        sealDetail.setSignatureScope(jsonObject.getInteger("signature_scope"));
        sealDetail.setSignatureType(jsonObject.getString("signature_type"));
        sealDetail.setSignatureSource(jsonObject.getString("signature_source"));
        return sealDetail;
    }

    @Override
    public ResultBody editSealName(String signatureId, Integer port, LoginSuccessDTO loginSuccessDTO, String sealName) {
        ResultBody resultBody = checkAuthStatus(port, loginSuccessDTO);
        UserFddDO userFddInfo = (UserFddDO) resultBody.getResult();
        sealManageDao.updateSealName(userFddInfo.getUnionId(), signatureId, sealName);
        return ResultBody.success();
    }
}
