package cn.pluss.platform.merchant.impl;

import cn.pluss.platform.channel.MchChannelRateNewService;
import cn.pluss.platform.converter.Converter;
import cn.pluss.platform.dto.MerchantRateNewRecordDTO;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.mapper.MerchantRateNewRecordMapper;
import cn.pluss.platform.merchant.MerchantBaseInfoService;
import cn.pluss.platform.merchant.MerchantRateNewRecordService;
import cn.pluss.platform.merchant.MerchantRateNewService;
import cn.pluss.platform.merchantChannelStatus.MerchantChannelStatusService;
import cn.pluss.platform.notice.NoticeService;
import cn.pluss.platform.notice.template.NoticeTemplateService;
import cn.pluss.platform.user.impl.GeneralPushUtil;
import cn.pluss.platform.userApp.UserAppService;
import cn.pluss.platform.vo.MerchantRateNewRecordVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 商户费率表(新) 服务实现类
 * </p>
 *
 * @author Djh
 * @since 2021-08-09
 */
@Service
public class MerchantRateNewRecordServiceImpl extends ServiceImpl<MerchantRateNewRecordMapper, MerchantRateNewRecord> implements MerchantRateNewRecordService {

    @Autowired
    private UserAppService userAppService;

    @Autowired
    private MerchantChannelStatusService mcsService;

    @Autowired
    private MerchantRateNewService rateNewService;

    @Autowired @Lazy
    private NoticeService noticeService;

    @Autowired
    private MerchantBaseInfoService mbiService;

    @Autowired
    private GeneralPushUtil generalPushUtil;

    @Autowired @Lazy
    private NoticeTemplateService nTempService;

    @Setter(onMethod_ = {@Autowired})
    private MchChannelRateNewService ryxChangeRateNewService;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Override
    public Page<MerchantRateNewRecordVO> apiPage(Page<MerchantRateNewRecord> page, MerchantRateNewRecordDTO entity) {
        UserApp tokenUserApp = userAppService.queryUserAppByToken();

        LambdaQueryWrapper<UserApp> qWrapperSearchUserApp = new LambdaQueryWrapper<>();
        qWrapperSearchUserApp.eq(UserApp::getUserId, entity.getUserId());
        UserApp searchUserApp = userAppService.getOne(qWrapperSearchUserApp);

        if (!Objects.equals(entity.getUserId(), tokenUserApp.getUserId() + "")) {
            if (searchUserApp == null || !Objects.equals(searchUserApp.getParentId(), tokenUserApp.getUserId())) {
                throw new MsgException("拒绝访问");
            }
        }

        if (searchUserApp.getMerchantCode() == null) {
            throw new MsgException("暂未进件");
        }

        LambdaQueryWrapper<MerchantChannelStatus> qWrapperMcs = new LambdaQueryWrapper<MerchantChannelStatus>()
                .eq(MerchantChannelStatus::getMerchantCode, searchUserApp.getMerchantCode())
                .eq(MerchantChannelStatus::getStatus, "3");
        List<MerchantChannelStatus> mcsList = mcsService.list(qWrapperMcs);

        List<String> merchantIdList = new ArrayList<String>();
        for (MerchantChannelStatus mcs : mcsList) {
            merchantIdList.add(mcs.getMerchantId());
        }

        if (merchantIdList.isEmpty()) {
            Page<MerchantRateNewRecordVO> resultPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
            resultPage.setRecords(new ArrayList<>());
            return resultPage;
        }

        LambdaQueryWrapper<MerchantRateNewRecord> qWrapper = new LambdaQueryWrapper<MerchantRateNewRecord>()
                .in(MerchantRateNewRecord::getMerchantId, merchantIdList)
                .orderByDesc(MerchantRateNewRecord::getCreateTime);

        Page<MerchantRateNewRecord> queryData = page(page, qWrapper);

        List<MerchantRateNewRecordVO> resultList = new ArrayList<>();
        
        for (MerchantRateNewRecord queryDatum : queryData.getRecords()) {
            MerchantRateNewRecordVO vo = Converter.INSTANCE.toVO(queryDatum);
            if (Objects.equals(vo.getChannel(), 4)) {
                vo.setChannelType("D0");
            } else {
                vo.setChannelType("D1");
            }
            MerchantRateNewRecordVO.setRateValue(vo);
            resultList.add(vo);
        }

        Page<MerchantRateNewRecordVO> resultPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        resultPage.setRecords(resultList);

        return resultPage;
    }

    @Override
    public void onSuccess(MerchantRateNewRecord rateNewRecord) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                LambdaQueryWrapper<MerchantRateNew> qWrapper = new LambdaQueryWrapper<MerchantRateNew>()
                        .eq(MerchantRateNew::getMerchantId, rateNewRecord.getMerchantId())
                        .eq(MerchantRateNew::getChannel, rateNewRecord.getChannel());

                MerchantRateNew rateNewExist = rateNewService.getOne(qWrapper);
                if (rateNewExist == null) {
                    rateNewExist = ryxChangeRateNewService.getDefaultRate();
                }

                LambdaQueryWrapper<MerchantChannelStatus> qWrapper2 = new LambdaQueryWrapper<MerchantChannelStatus>()
                        .eq(MerchantChannelStatus::getMerchantId, rateNewRecord.getMerchantId())
                        .eq(MerchantChannelStatus::getChannel, rateNewRecord.getChannel());
                MerchantChannelStatus mcs = mcsService.getOne(qWrapper2);

                Converter.INSTANCE.cp(rateNewRecord, rateNewExist);

                rateNewRecord.setStatus("1");
                rateNewRecord.setUpdateTime(new Date());
                rateNewService.saveOrUpdate(rateNewExist);
                saveOrUpdate(rateNewRecord);

                // 获取用户id
                List<String> aliasList = new ArrayList<>();

                LambdaQueryWrapper<UserApp> qWrapper3 = Wrappers.lambdaQuery();
                qWrapper3.eq(UserApp::getMerchantCode, mcs.getMerchantCode());
                qWrapper3.eq(UserApp::getUserType, "promoter");
                UserApp ua = userAppService.getOne(qWrapper3);
                aliasList.add(ua.getUserId() + "");

                LambdaQueryWrapper<MerchantBaseInfo> qWrapper6 = Wrappers.lambdaQuery();
                qWrapper6.eq(MerchantBaseInfo::getMerchantCode, mcs.getMerchantCode());
                MerchantBaseInfo mbi = mbiService.getOne(qWrapper6);

                // 获取上级用户id
                UserApp uaParent = null;
                if (ua.getParentId() != null) {
                    LambdaQueryWrapper<UserApp> qWrapper4 = Wrappers.lambdaQuery();
                    qWrapper4.eq(UserApp::getUserId, ua.getParentId());
                    uaParent = userAppService.getOne(qWrapper4);
                    aliasList.add(uaParent.getUserId() + "");
                }

                // 获取通知模板
                NoticeTemplate template = nTempService.getNoticeTemplateByType("14");
                String templateContent;
                if (template == null) {
                    templateContent = "尊敬的商户“$1”，您的交易费率调整审核已通过，费率修改记录在个人页面【商户认证】-【商户费率】-右上角【变更记录】中查看，如有疑问请咨询您的业务员。";
                } else {
                    templateContent = template.getContent();
                }
                templateContent = templateContent.replace("$1", mbi.getAlias());

                List<Notice> noticeList = new ArrayList<>();

                Notice notice = new Notice(1, -1, ua.getUserId() + "", ua.getUserName());
                notice.setConrtent(templateContent);
                notice.setDesc(templateContent);
                notice.setTitle("费率修改通知");
                noticeList.add(notice);

                if (uaParent != null) {
                    Notice notice2 = new Notice(1, -1, uaParent.getUserId() + "", uaParent.getUserName());
                    notice2.setConrtent(templateContent);
                    notice2.setDesc(templateContent);
                    notice2.setTitle("费率修改通知");
                    noticeList.add(notice2);
                }

                noticeService.saveBatch(noticeList);
                generalPushUtil.sendAllPlatByAlias(aliasList, "费率修改通知", templateContent, "1");
            }
        });

    }

    @Override
    public void onFail(MerchantRateNewRecord rateNewRecord) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                MerchantChannelStatus mcs = mcsService.getByMerchantId(rateNewRecord.getMerchantId());
                UserApp userApp = new UserApp().setMerchantCode(mcs.getMerchantCode()).setUserType("promoter");
                UserApp ua = userAppService.getOne(new QueryWrapper<>(userApp));

                List<String> aliasList = new ArrayList<>();

                // 获取上级用户id
                UserApp uaParent = null;
                if (ua.getParentId() != null) {
                    LambdaQueryWrapper<UserApp> qWrapper4 = Wrappers.lambdaQuery();
                    qWrapper4.eq(UserApp::getUserId, ua.getParentId());
                    uaParent = userAppService.getOne(qWrapper4);
                    aliasList.add(uaParent.getUserId() + "");
                }

                // 失败
                rateNewRecord.setStatus("2");
                saveOrUpdate(rateNewRecord);

                List<Notice> noticeList = new ArrayList<>();

                Notice notice = new Notice(1, -1, ua.getUserId() + "", ua.getUserName());
                notice.setConrtent("费率修改失败");
                notice.setDesc("费率修改失败");
                notice.setTitle("费率修改通知");
                noticeList.add(notice);

                if (uaParent != null) {
                    Notice notice2 = new Notice(1, -1, uaParent.getUserId() + "", uaParent.getUserName());
                    notice.setConrtent("费率修改失败");
                    notice.setDesc("费率修改失败");
                    notice.setTitle("费率修改通知");
                    noticeList.add(notice2);
                }

                noticeService.saveBatch(noticeList);
                generalPushUtil.sendAllPlatByAlias(aliasList, "费率修改通知", "费率修改失败", "1");
            }
        });
    }
}
