package cn.pluss.platform.merchantStore.impl;

import cn.pluss.platform.SubMerchantApplyOrderService;
import cn.pluss.platform.api.Result;
import cn.pluss.platform.api.ResultGenerator;
import cn.pluss.platform.channel.MerchantAuditService;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.mapper.MerchantBaseInfoMapper;
import cn.pluss.platform.mapper.MerchantChannelStatusMapper;
import cn.pluss.platform.mapper.MerchantStoreMapper;
import cn.pluss.platform.mapper.NoticeMapper;
import cn.pluss.platform.merchant.MerchantBaseInfoService;
import cn.pluss.platform.merchantChannelStatus.MerchantChannelStatusService;
import cn.pluss.platform.merchantImage.MerchantImageService;
import cn.pluss.platform.merchantStore.MerchantStoreService;
import cn.pluss.platform.operationRecord.OperationRecordService;
import cn.pluss.platform.userApp.UserAppService;
import cn.pluss.platform.util.ExcelUtil;
import cn.pluss.platform.user.impl.GeneralPushUtil;
import cn.pluss.platform.util.SendMsgUtil;
import cn.pluss.platform.util.StringUtil;
import cn.pluss.platform.vo.StoreInfoVO;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import lombok.var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;

@Slf4j
@Service("merchantStoreService")
@RequiredArgsConstructor
public class MerchantStoreServiceImpl extends ServiceImpl<MerchantStoreMapper, MerchantStore> implements MerchantStoreService {

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private MerchantBaseInfoMapper merchantBaseInfoMapper;

    @Setter(onMethod_ = {@Autowired, @Lazy, @Qualifier("sxfMerchantAuditService")})
    private MerchantAuditService sxfMerchantAuditService;

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private MerchantChannelStatusMapper merchantChannelStatusMapper;

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private MerchantImageService merchantImageService;

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private MerchantChannelStatusService merchantChannelStatusService;

    @Setter(onMethod_ = {@Autowired,@Lazy})
    private SubMerchantApplyOrderService merchantApplyOrderService;

    @Setter(onMethod_ = {@Autowired,@Lazy})
    private UserAppService userAppService;

    @Setter(onMethod_ = {@Autowired,@Lazy})
    private MerchantBaseInfoService merchantBaseInfoService;

    @Resource
    private NoticeMapper noticeMapper;

    @Setter(onMethod_ = {@Autowired,@Lazy})
    private SendMsgUtil sendMsgUtil;

    @Autowired
    private GeneralPushUtil generalPushUtil;

    @Autowired
    private OperationRecordService opService;

    @Override
    public void disableMerchantStore(Long opUserId, Long userId, String remark) {
        MerchantBaseInfo mbi = merchantBaseInfoService.getMerchantBaseInfoByUserId(userId.toString());
        if (mbi == null) { return; }

        Map<String, Object> params = new HashMap<>(2);

        OperationRecord operationRecord = new OperationRecord();
        operationRecord.setOperator(opUserId.toString())
                .setUserId(userId.toString())
                .setCreateTime(new Date())
                .setRemark(remark)
                .setDictValue("GBSHJYGN");
        opService.save(operationRecord);
        params.put("status", "2");
        params.put("id", mbi.getUserId());
        disableMerchantStore(params);
    }

    @Override
    public void enableMerchantStore(Long opUserId, Long userId, String remark) {
        MerchantBaseInfo mbi = merchantBaseInfoService.getMerchantBaseInfoByUserId(userId.toString());
        if (mbi == null) { return; }

        Map<String, Object> params = new HashMap<>(2);

        OperationRecord operationRecord = new OperationRecord();
        operationRecord.setOperator(opUserId.toString())
                .setUserId(userId.toString())
                .setCreateTime(new Date())
                .setRemark(remark)
                .setDictValue("KTSHJYGN");
        opService.save(operationRecord);
        params.put("status", "1");
        params.put("id", userId);
        disableMerchantStore(params);
    }

    @Override
    public MerchantStore queryMerchantStore(MerchantStore merchantStore){
        return baseMapper.selectOne(new QueryWrapper<>(merchantStore));
    }

    @Override
    public List<MerchantStore> queryMerchantStoreList(MerchantStore merchantStore){
        return baseMapper.selectList(new QueryWrapper<>(merchantStore));
    }
    @Override
    public List<MerchantStore> queryMerchantNoStoreList(MerchantStore merchantStore){
        return baseMapper.queryMerchantNoStoreList(merchantStore);
    }

    @Override
    public Map<String, Object> queryMerchantStoreByPage(Integer currPage, Integer size, MerchantStore merchantStore, MerchantBaseInfo merchantBaseInfo, String merchantType, String userId) {
        Map<String, Object> map = new HashMap<>(16);
        Map<String, Object> result = new HashMap<>(16);
        map.put("pageSize", size);
        map.put("offset", (currPage - 1) * size);

        map.put("status", merchantStore.getStatus());
        map.put("storeName", merchantStore.getStoreName());
        map.put("location",merchantBaseInfo.getLocation());
        map.put("productDesc", merchantStore.getProductDesc());
        map.put("merchantName", merchantBaseInfo.getMerchantName());
        map.put("payEcdemicSwitch", merchantStore.getPayEcdemicSwitch());
        map.put("isMarket", merchantStore.getIsMarket());

//        map.put("merchantType", merchantStore.getMerchantType());
        map.put("address", merchantStore.getProName());
        map.put("merchantCode", merchantStore.getMerchantCode());
        map.put("userId", userId);
        map.put("merchantType", merchantType);
        map.put("alias", merchantStore.getAlias());
        map.put("mcsStatus", merchantStore.getMcsStatus());
        map.put("startTime", merchantStore.getStartTime());
        map.put("endTime", merchantStore.getEndTime());

        List<StoreInfoVO> merchantStoreList;
        Page<StoreInfoVO> pageData = queryNewStoreListPage(map);
        merchantStoreList = pageData.getRecords();
        long count = pageData.getTotal();

        result.put("merchantStoreList", merchantStoreList);
        result.put("count", count);
        result.put("pageCount", StringUtil.getPageCount(count, size));
        result.put("currPage", currPage);
        result.put("code", 200);
        return result;
    }

    @Override
    public Map<String, Object> getCertInfo(String userId) {
        Map<String, Object> result = Maps.newHashMap();

        MerchantBaseInfo merchantBaseInfo = new MerchantBaseInfo();
        merchantBaseInfo.setUserId(userId);
        merchantBaseInfo = merchantBaseInfoMapper.queryMerchantBaseInfo(merchantBaseInfo);
        MsgException.checkNull(merchantBaseInfo, "缺少商户基本信息");

        MerchantImage merchantImage = new MerchantImage();
        merchantImage.setMerchantCode(merchantBaseInfo.getMerchantCode());

        QueryWrapper<MerchantImage> queryWrapper = new QueryWrapper<>(merchantImage);

        List<String> photoTypeList = Arrays.asList(
                MerchantImage.ImageType.CASH_DESK_WITH_PERSON
                , MerchantImage.ImageType.HAND_IDCARD_PHOTO
                , MerchantImage.ImageType.MERCHANT_PROTOCOL
                , MerchantImage.ImageType.MERCHANT_SUB_PROTOCOL
        );
        queryWrapper.in("photoType", photoTypeList);
        List<MerchantImage> merchantImageList = merchantImageService.list(queryWrapper);

        for (MerchantImage item : merchantImageList) {
            switch (item.getPhotoType()) {
                case MerchantImage.ImageType.CASH_DESK_WITH_PERSON:
                    result.put("cashDeskWithPerson", item);
                    break;
                case MerchantImage.ImageType.HAND_IDCARD_PHOTO:
                    result.put("handCard", item);
                    break;
                case MerchantImage.ImageType.MERCHANT_PROTOCOL:
                    result.put("merchantProtocol", item);
                    break;
                case MerchantImage.ImageType.MERCHANT_SUB_PROTOCOL:
                    result.put("merchantSubProtocol", item);
                    break;
                default:
                    break;
            }

        }

        return result;
    }

    @Override
    public void saveMerchantStore(MerchantStore merchantStore){
        baseMapper.insert(merchantStore);
    }
    @Override
    public void updateMerchantStore(MerchantStore merchantStore){
        baseMapper.updateById(merchantStore);
    }
    @Override
    public void deleteMerchantStore(MerchantStore merchantStore){
        baseMapper.deleteById(merchantStore.getId());
    }
    @Override
    public List<MerchantStore> queryMerchantStorePage(Map map){
        return baseMapper.queryMerchantStorePage(map);
    }
    @Override
    public Integer queryMerchantStorePageCount(Map map){
        return baseMapper.queryMerchantStorePageCount(map);
    }

    @SuppressWarnings("unchecked")
    @Override
	public Page<StoreInfoVO> queryNewStoreListPage(Map<String, Object> map) {
        List<List<?>> queryData = baseMapper.queryNewStoreListPage(map);
        List<StoreInfoVO> record = (List<StoreInfoVO>) queryData.get(0);
        Page<StoreInfoVO> page = new Page<>();
        page.setRecords(record);
        long total = ((Long) queryData.get(1).get(0));
        page.setTotal(total);
        return page;
	}

    @Override
    public <E extends IPage<MerchantStore>> E page(E page, Wrapper<MerchantStore> queryWrapper) {


        return super.page(page, queryWrapper);
    }

    @Override
    public void disableMerchantStore(Map<String,Object> params) {
        baseMapper.disableMerchantStore(params);
    }

    @Override
    public void pesUpdateMerchantStore(Map<String,Object> params) {
        baseMapper.pesUpdateMerchantStore(params);
    }

    /**
     * getMerchantInfo:(得到商户名称，门店名称). <br/>
     *
     * @param merchantCode
     * @param storeId
     * @return
     * 
     * @author Administrator
     * @since JDK 1.8
     */
    @Override
    public MerchantStore getMerchantInfo(String merchantCode, String storeId) {
        // 因害怕表数据有误 分别根据merchantCode 查商家表 storeId查门店表
        MerchantStore merchantStore = new MerchantStore();
        merchantStore.setStoreId(storeId);
        MerchantBaseInfo merchantBaseInfo = new MerchantBaseInfo();
        merchantBaseInfo.setMerchantCode(merchantCode);
        List<MerchantBaseInfo> queryMerchantBaseInfoList = merchantBaseInfoMapper
                .queryMerchantBaseInfoList(merchantBaseInfo);
        if (queryMerchantBaseInfoList != null && !queryMerchantBaseInfoList.isEmpty()) {
            merchantBaseInfo = queryMerchantBaseInfoList.get(0);
            merchantStore.setMerchantCode(merchantCode);
        } else {
            return null;
        }
        List<MerchantStore> queryMerchantStoreList = baseMapper.queryMerchantStoreList(merchantStore);
        if (queryMerchantStoreList != null && !queryMerchantStoreList.isEmpty()) {
            merchantStore = queryMerchantStoreList.get(0);
            merchantStore.setMerchantName(merchantBaseInfo.getMerchantName());
        } else {
            return null;
        }
        return merchantStore;
    }

    @Override
    public StoreInfoVO selectStatus(Map<String, Object> params) {
        return baseMapper.selectStatus(params);
    }

    @Override
    public void operatMarketMerchantStore(Map<String, Object> params) {
        baseMapper.operatMarketMerchantStore(params);
    }

    @Override
    public StoreInfoVO showMerchantStoreReceipt(Integer userId) {
        return baseMapper.showMerchantStoreReceipt(userId);
    }

    @Override
    public void manualMerchantIncom() {
        QueryWrapper<MerchantBaseInfo> queryWrapper = new QueryWrapper<>();
        List<MerchantBaseInfo> list = merchantBaseInfoMapper.selectList(queryWrapper);
        for (MerchantBaseInfo m:list) {
            if(StringUtil.isEmpty(m.getMerchantCode())){
                continue;
            }
            if(StringUtil.isEmpty(m.getUserId())){
                continue;
            }
            QueryWrapper<MerchantChannelStatus> channelStatusQueryWrapper = new QueryWrapper<MerchantChannelStatus>()
                    .eq("merchantCode",m.getMerchantCode());
            MerchantChannelStatus channel = merchantChannelStatusMapper.selectOne(channelStatusQueryWrapper);
            if(channel == null){
                try {
                    sxfMerchantAuditService.merchantAudit(m.getUserId()+"", false);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public StoreInfoVO selectParticulars(Integer id) {
        return merchantBaseInfoMapper.selectParticulars(id);
    }


    /**
     * @description: 更新d0状态以及发送微信认证通知
     * @date: 2021/8/4 11:22
     * @param channelStatus:
     * @param status:
     * @return cn.pluss.platform.api.Result<?>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> updateChannelStatusAndWxCert(MerchantChannelStatus channelStatus, String status) {
        if (channelStatus == null || !MerchantChannelStatus.AUDIT_STATUS_QUICK_CASH.equals(channelStatus.getStatus())) {
            throw new MsgException("当前进件状态不允许执行该操作");
        }
        channelStatus.setStatus(status);
        merchantChannelStatusService.updateById(channelStatus);

        // 检查银盛微信认证通知状态
        val merchantCode = channelStatus.getMerchantCode();
        val qWrapper = new LambdaQueryWrapper<SubMerchantApplyOrder>()
                .eq(SubMerchantApplyOrder::getChannelId, 4)
                .eq(SubMerchantApplyOrder::getMerchantCode, merchantCode)
                .orderByDesc(SubMerchantApplyOrder::getCreateTime)
                .last("limit 1");

        val subMerchApplyOrder = merchantApplyOrderService.getOne(qWrapper);
        if (subMerchApplyOrder == null) {
            return ResultGenerator.genSuccessResult("操作成功",null);
        }

        val mbi = merchantBaseInfoService.getMerchantBaseInfoByMerchantCode(merchantCode);
        var userApp = new UserApp().setMerchantCode(merchantCode).setUserType("promoter");
        userApp = userAppService.getOne(new QueryWrapper<>(userApp));

        String content2 = "D0支付已开通，请悉知";
        generalPushUtil.sendAllPlatByAlias(Collections.singletonList(userApp.getUserId() + ""), "商户D0开通通知", content2, "1");

        Notice notice2 = new Notice(1, 1, userApp);
        notice2.setConrtent(content2);
        noticeMapper.saveNotice(notice2);

        val certStatus = subMerchApplyOrder.getStatus();
        if ("confirmcontact".equals(certStatus) || "confirmlegalperson".equals(certStatus) || "passed".equals(certStatus)) {
            String content = "请商户进行微信实名认证，短信将发送至商户联系人手机号，已认证可忽略";
            generalPushUtil.sendAllPlatByAlias(Collections.singletonList(userApp.getUserId() + ""), "商户微信认证通知", content, "1");

            Notice notice = new Notice(1, 1, userApp);
            notice.setConrtent(content);
            noticeMapper.saveNotice(notice);
            try {
                sendMsgUtil.verifyMsg(mbi.getContactMobile(), userApp.getMerchantCode() + "?i=4");
            } catch (MsgException e) {
                log.error(e.getMessage());
            }
        } else if ("rejected".equals(certStatus) || "freezed".equals(certStatus) || "canceled".equals(certStatus) || "unknow".equals(certStatus)) {
            // 驳回或者未知状态标位已处理
            Notice notice = new Notice(1, 1, userApp);
            String pushMsg = "您好！您的商户微信认证因“##”被驳回，请联系收银呗客服修改资料并重新审核";
            pushMsg = pushMsg.replace("##", subMerchApplyOrder.getRemark());
            notice.setConrtent(pushMsg);
            noticeMapper.saveNotice(notice);
            generalPushUtil.sendAllPlatByAlias(Collections.singletonList(userApp.getUserId() + ""), "商户微信认证通知", pushMsg, "1");
        }
        return ResultGenerator.genSuccessResult("操作成功",null);
    }

    /**
     * @description:批量导入d0excel开通文件
     * @date: 2021/8/4 11:37
     * @param file:
     * @return cn.pluss.platform.api.Result<?>
     */
    @Override
    public Result<?> exportD0Excel(MultipartFile file) {
        if(file.isEmpty()){
            return ResultGenerator.genFailResult("请选择文件");
        }
        try {
            List<String[]> excelData = ExcelUtil.getExcelData(file, 1);
            if(excelData.isEmpty()){
                return ResultGenerator.genFailResult("文件解析出错");
            }
            for (String[] s:excelData) {
                if(StringUtil.isEmpty(s[0])){
                    continue;
                }
                if(!s[0].startsWith("826")){
                    continue;
                }
                MerchantChannelStatus channelStatus = merchantChannelStatusService.getByMerchantIdLock(s[0]);
                try {
                    updateChannelStatusAndWxCert(channelStatus,"3");
                }catch (RuntimeException e){
                    e.printStackTrace();
                    continue;
                }
            }
            return ResultGenerator.genSuccessResult("操作成功！",null);
        } catch (IOException e) {
            e.printStackTrace();
            return ResultGenerator.genFailResult(e.getMessage());
        }
    }

    @Override
    public MerchantStore getStoreByMerchantCode(String merchantCode) {
        QueryWrapper<MerchantStore> queryWrapper = new QueryWrapper<MerchantStore>().eq("merchantCode",merchantCode);
        return baseMapper.selectOne(queryWrapper);
    }
}