package com.yonge.cooleshow.biz.dal.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.microsvc.toolkit.common.webportal.exception.BizException;
import com.yonge.cooleshow.biz.dal.entity.*;
import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
import com.yonge.cooleshow.biz.dal.mapper.TenantEntryRecordMapper;
import com.yonge.cooleshow.biz.dal.service.*;
import com.yonge.cooleshow.common.constant.SysConfigConstant;
import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import com.yonge.cooleshow.biz.dal.wrapper.TenantApplyRecordWrapper;
import com.yonge.cooleshow.biz.dal.mapper.TenantApplyRecordMapper;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * 机构入驻申请记录
 * 2023-07-21 17:32:49
 */
@Slf4j
@Service
public class TenantApplyRecordServiceImpl extends ServiceImpl<TenantApplyRecordMapper, TenantApplyRecord> implements TenantApplyRecordService {


    @Autowired
    private TenantStaffService tenantStaffService;

    @Autowired
    private SmsCodeService smsCodeService;

    @Autowired
    private SysAreaService sysAreaService;

    @Autowired
    TenantApplyRecordMapper tenantApplyRecordMapper;

    @Autowired
    TenantEntryRecordMapper tenantEntryRecordMapper;

    @Autowired
    TenantInfoService tenantInfoService;

    @Autowired
    private SysMessageService sysMessageService;

    @Autowired
    private SysConfigService sysConfigService;

    @Autowired
    private SysUserMapper  sysUserMapper;

    /**
     * 查询详情
     * @param id 详情ID
     * @return TenantApplyRecord
     */
    @Override
    public TenantApplyRecord detail(Long id) {
        
        return baseMapper.selectById(id);
    }
    
    /**
     * 分页查询
     * @param page IPage<TenantApplyRecord>
     * @param query TenantApplyRecordWrapper.TenantApplyRecordQuery
     * @return IPage<TenantApplyRecord>
     */
    @Override
    public IPage<TenantApplyRecordWrapper.TenantApplyRecord> selectPage(IPage<TenantApplyRecordWrapper.TenantApplyRecord> page, TenantApplyRecordWrapper.TenantApplyRecordQuery query) {
        List<TenantApplyRecordWrapper.TenantApplyRecord> records = baseMapper.selectPage(page, query);
        List<TenantApplyRecordWrapper.TenantApplyRecord> infos = queryArea(records);
        return page.setRecords(infos);
    }

    /**
     * 添加
     * @param tenantApplyRecord TenantApplyRecordWrapper.TenantApplyRecord
     * @return Boolean
     */
    @Override
    public Boolean add(TenantApplyRecordWrapper.TenantApplyRecord tenantApplyRecord) {

        return this.save(JSON.parseObject(tenantApplyRecord.jsonString(), TenantApplyRecord.class));
    }

    /**
     * 更新
     * @param tenantApplyRecord TenantApplyRecordWrapper.TenantApplyRecord
     * @return Boolean
     */
    @Override
    public Boolean update(TenantApplyRecordWrapper.TenantApplyRecord tenantApplyRecord){

        return this.updateById(JSON.parseObject(tenantApplyRecord.jsonString(), TenantApplyRecord.class));       
    }

    /**
     * 申请入驻
     *
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void apply(TenantApplyRecordWrapper.TenantApply tenantApply) {

        // 检测验证码
        boolean b = smsCodeService.verifyValidCode(tenantApply.getPhone(), tenantApply.getCode(), null);
        if (!b) {
            throw new BizException("验证码错误");
        }


        // 根据手机号 判断是否已经有机构账户
        TenantStaff tenantStaff = tenantStaffService.getByPhone(tenantApply.getPhone());
        if (tenantStaff != null) {
            throw new BizException("该手机号已经有机构账号");
        }
//
//        QueryWrapper<SysUser> sysUserQueryWrapper = new QueryWrapper<>();
//        sysUserQueryWrapper.lambda().eq(SysUser::getPhone, tenantApply.getPhone());
//        List<SysUser> sysUsers = sysUserMapper.selectList(sysUserQueryWrapper);
//        if (!sysUsers.isEmpty() && sysUsers.stream().anyMatch(next -> next.getUserType().contains(ClientEnum.SYSTEM.getCode()))) {
//            throw new BizException("该手机号已经有系统员工账户");
//        }

        // 查询申请记录 是否存在正在申请中的
        TenantApplyRecord record = this.lambdaQuery()
                .eq(TenantApplyRecord::getPhone, tenantApply.getPhone())
                .in(TenantApplyRecord::getStatus, AuthStatusEnum.DOING, AuthStatusEnum.UNPASS)
                .last("limit 1")
                .one();

        // 保存申请记录
        TenantApplyRecord tenantApplyRecord = JSON.parseObject(tenantApply.jsonString(), TenantApplyRecord.class);
        if (record != null) {
            tenantApplyRecord.setId(record.getId());
        }
        tenantApplyRecord.setStatus(AuthStatusEnum.DOING);
        tenantApplyRecord.setUpdateTime(new Date());
        this.saveOrUpdate(tenantApplyRecord);

        // 审核人  审核理由 null
        this.lambdaUpdate()
                .eq(TenantApplyRecord::getId, tenantApplyRecord.getId())
                .set(TenantApplyRecord::getVerifyUserId, null)
                .set(TenantApplyRecord::getReason, null)
                .update();


    }

    @Override
    public IPage<TenantApplyRecordWrapper.TenantApply> historyPage(IPage<TenantApplyRecordWrapper.TenantApply> page, TenantApplyRecordWrapper.TenantApplyRecordQuery query) {
        long id = query.getId();
        //分页查询
       List<TenantApplyRecordWrapper.TenantApply> tenantInfos = baseMapper.selectHistoryPage(page, id);
       //查询对应省市区
        List<Integer> areaCodeList = tenantInfos.stream().map(next -> {
            Set<Integer> codes = new HashSet<>();
            codes.add(next.getCityCode());
            codes.add(next.getProvinceCode());
            codes.add(next.getRegionCode());
            return codes;
        }).flatMap(Collection::stream).filter(Objects::nonNull).distinct().collect(Collectors.toList());

        Map<Integer, String> codeNameMap = new HashMap<>();

        if (!CollectionUtils.isEmpty(areaCodeList)) {
            List<SysArea> sysAreaList = sysAreaService.queryByCodes(areaCodeList);
            codeNameMap = sysAreaList.stream().collect(Collectors.toMap(SysArea::getCode,
                    SysArea::getName));
        }

        for (TenantApplyRecordWrapper.TenantApply next : tenantInfos) {
            next.setProvinceName(codeNameMap.getOrDefault(next.getProvinceCode(), ""));
            next.setCityName(codeNameMap.getOrDefault(next.getCityCode(), ""));
            next.setRegionName(codeNameMap.getOrDefault(next.getRegionCode(), ""));
        }
        tenantInfos.stream().forEach(item->{
            String name = tenantEntryRecordMapper.selectName(item.getVerifyUserId());
            item.setVerifyUserName(name);
            item.setVerifyUserId(item.getVerifyUserId());
        });
        return page.setRecords(tenantInfos);
    }

    @Override
    public TenantApplyRecordWrapper.TenantApplyRecord queryNow(TenantApplyRecordWrapper.TenantApplyRecordQuery query) {
        Long id = query.getId();
        //查询本次提交记录
        TenantApplyRecordWrapper.TenantApplyRecord info = baseMapper.queryNow(query);

        //查询当前申请数据的状态
        AuthStatusEnum status = info.getStatus();

        if (status.equals(AuthStatusEnum.DOING)){
            //如果是审核中 申请表取一条数据  审核表取一条数据
            queryName2(info);
            //审核表取一条最新数据
            TenantApplyRecordWrapper.LastRecord lastRecordEntry = baseMapper.selectEntry(id);

            if (!(lastRecordEntry == null)){
                //设置地名
                queryName(lastRecordEntry);
            }
            info.setLastApplyRecord(lastRecordEntry);
            return info;
        } else {
            //如果是通过或者失败  审核表取前两条数据
            TenantApplyRecordWrapper.TenantApplyRecord tenantApplyRecord = baseMapper.selectLastEntry(id);
            queryName2(tenantApplyRecord);
            TenantApplyRecordWrapper.LastRecord lastRecord = baseMapper.selectSecondEntry(id);
            if (!(lastRecord == null)){
                queryName(lastRecord);
            }
            tenantApplyRecord.setLastApplyRecord(lastRecord);
            return tenantApplyRecord;
        }


    }

    private void queryName2(TenantApplyRecordWrapper.TenantApplyRecord info) {
        Set<Integer> codes = new HashSet<>();
        codes.add(info.getCityCode());
        codes.add(info.getProvinceCode());
        codes.add(info.getRegionCode());

        //将地区码转化为对应的地名
        List<Integer> areaCodeList = new ArrayList<>();
        areaCodeList.addAll(codes);

        Map<Integer, String> codeNameMap = new HashMap<>();

        if (!CollectionUtils.isEmpty(areaCodeList)) {
            List<SysArea> sysAreaList = sysAreaService.queryByCodes(areaCodeList);
            codeNameMap = sysAreaList.stream().collect(Collectors.toMap(SysArea::getCode,
                    SysArea::getName));
        }
        info.setProvinceName(codeNameMap.get(info.getProvinceCode()));
        info.setCityName(codeNameMap.get(info.getCityCode()));
        info.setRegionName(codeNameMap.get(info.getRegionCode()));
    }

    private void queryName(TenantApplyRecordWrapper.LastRecord lastRecordEntry) {
        Set<Integer> codes2 = new HashSet<>();
        codes2.add(lastRecordEntry.getCityCode());
        codes2.add(lastRecordEntry.getProvinceCode());
        codes2.add(lastRecordEntry.getRegionCode());

        //将地区码转化为对应的地名
        List<Integer> areaCodeList2 = new ArrayList<>();
        areaCodeList2.addAll(codes2);

        Map<Integer, String> codeNameMap2 = new HashMap<>();

        if (!CollectionUtils.isEmpty(areaCodeList2)) {
            List<SysArea> sysAreaList = sysAreaService.queryByCodes(areaCodeList2);
            codeNameMap2 = sysAreaList.stream().collect(Collectors.toMap(SysArea::getCode,
                    SysArea::getName));
        }
        lastRecordEntry.setProvinceName(codeNameMap2.get(lastRecordEntry.getProvinceCode()));
        lastRecordEntry.setCityName(codeNameMap2.get(lastRecordEntry.getCityCode()));
        lastRecordEntry.setRegionName(codeNameMap2.get(lastRecordEntry.getRegionCode()));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean entry(TenantApplyRecordWrapper.TenantEntry entry,Long verifyUserId) {
        Boolean ifPass = entry.getIfPass();
        Long id = entry.getId();
        TenantApplyRecord applyRecord = tenantApplyRecordMapper.selectById(id);
        TenantApplyRecordWrapper.TenantApplyRecord tenantApplyRecord= new TenantApplyRecordWrapper.TenantApplyRecord();

        tenantApplyRecord.setTenantApplyRecordId(applyRecord.getId());
        tenantApplyRecord.setName(applyRecord.getName());
        tenantApplyRecord.setLogo(applyRecord.getLogo());
        tenantApplyRecord.setProvinceCode(applyRecord.getProvinceCode());
        tenantApplyRecord.setCityCode(applyRecord.getCityCode());
        tenantApplyRecord.setRegionCode(applyRecord.getRegionCode());
        tenantApplyRecord.setUsername(applyRecord.getUsername());
        tenantApplyRecord.setPhone(applyRecord.getPhone());
        tenantApplyRecord.setVerifyUserId(verifyUserId);
        tenantApplyRecord.setReason(entry.getReason());
        tenantApplyRecord.setBriefIntroduction(applyRecord.getBriefIntroduction());
        if (ifPass == true){
            tenantApplyRecord.setStatus(AuthStatusEnum.PASS);


            //机构账户新增逻辑
            TenantInfo tenantInfo = new TenantInfo();
            tenantInfo.setLogo(applyRecord.getLogo());
            tenantInfo.setName(applyRecord.getName());
            tenantInfo.setProvinceCode(applyRecord.getProvinceCode());
            tenantInfo.setCityCode(applyRecord.getCityCode());
            tenantInfo.setRegionCode(applyRecord.getRegionCode());
            tenantInfo.setUsername(applyRecord.getUsername());
            tenantInfo.setPhone(applyRecord.getPhone());
            tenantInfo.setEnableFlag(true);
            tenantInfo.setBriefIntroduction(applyRecord.getBriefIntroduction());
            if (tenantInfoService.add(tenantInfo)) {
                applyRecord.setUserId(tenantInfo.getUserId());
                tenantApplyRecordMapper.updateById(applyRecord);
            }
            //更改当前记录的审核状态
            tenantApplyRecordMapper.updateStatusById(id);
        } else {
            tenantApplyRecord.setStatus(AuthStatusEnum.UNPASS);
            tenantApplyRecordMapper.updateUnpassStatusById(id);
        }

        String name = tenantEntryRecordMapper.selectName(verifyUserId);
        tenantApplyRecord.setVerifyUserName(name);

        TenantEntryRecord tenantEntryRecord = JSON.parseObject(JSON.toJSONString(tenantApplyRecord), TenantEntryRecord.class);
         tenantEntryRecordMapper.insert(tenantEntryRecord);


        CompletableFuture.runAsync(() -> {
            sendMessage(entry, ifPass, tenantEntryRecord);
        });
        return true;
    }

    private void sendMessage(TenantApplyRecordWrapper.TenantEntry entry, Boolean ifPass, TenantEntryRecord entryRecord) {
        //发送短信
        Map<Long, String> receivers = new HashMap<>();
        receivers.put(0L, entryRecord.getPhone());
        if (Boolean.TRUE.equals(ifPass)) {
            try {
                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.SMS_TENANT_AUTH_PASS,
                        receivers, null, 0, null, ClientEnum.TENANT.getCode());
            } catch (Exception e) {
                log.error("机构入驻审核极光消息推送异常");
            }

        } else {
            try {
                String serviceConfig = sysConfigService.findConfigValue(SysConfigConstant.CUSTOMER_SERVICE_PHONE);
                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.SMS_TENANT_AUTH_UNPASS,
                        receivers, null, 0, null, ClientEnum.TENANT.getCode(), entry.getReason(),serviceConfig);
            } catch (Exception e) {
                log.error("机构入驻审核极光消息推送异常");
            }
        }
    }


    /**
     * 匹配地区码与省市区
     *
     * @param tenantInfos
     * @return
     */
    private List<TenantApplyRecordWrapper.TenantApplyRecord> queryArea(List<TenantApplyRecordWrapper.TenantApplyRecord> tenantInfos) {
        List<Integer> areaCodeList = tenantInfos.stream().map(next -> {
            Set<Integer> codes = new HashSet<>();
            codes.add(next.getCityCode());
            codes.add(next.getProvinceCode());
            codes.add(next.getRegionCode());
            return codes;
        }).flatMap(Collection::stream).filter(Objects::nonNull).distinct().collect(Collectors.toList());

        Map<Integer, String> codeNameMap = new HashMap<>();

        if (!CollectionUtils.isEmpty(areaCodeList)) {
            List<SysArea> sysAreaList = sysAreaService.queryByCodes(areaCodeList);
            codeNameMap = sysAreaList.stream().collect(Collectors.toMap(SysArea::getCode,
                    SysArea::getName));
        }

        for (TenantApplyRecordWrapper.TenantApplyRecord next : tenantInfos) {
            next.setProvinceName(codeNameMap.getOrDefault(next.getProvinceCode(), ""));
            next.setCityName(codeNameMap.getOrDefault(next.getCityCode(), ""));
            next.setRegionName(codeNameMap.getOrDefault(next.getRegionCode(), ""));
        }

        return tenantInfos;
    }
}