package com.yunzhi.marketing.service.impl;

import com.alibaba.fastjson.JSONObject;
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.yunzhi.marketing.base.ResponseBean;
import com.yunzhi.marketing.bo.request.HousingRaiseRequestBO;
import com.yunzhi.marketing.bo.request.RaiseOrderRequestBO;
import com.yunzhi.marketing.bo.request.RaiseRecordRequestBO;
import com.yunzhi.marketing.center.taUser.entity.TaUser;
import com.yunzhi.marketing.center.taUser.service.impl.TaUserServiceImpl;
import com.yunzhi.marketing.common.CommConstant;
import com.yunzhi.marketing.common.SMSUtils;
import com.yunzhi.marketing.eContract.entity.TaContract;
import com.yunzhi.marketing.eContract.entity.TaContractBusiness;
import com.yunzhi.marketing.eContract.service.ITaContractBusinessService;
import com.yunzhi.marketing.eContract.service.ITaContractService;
import com.yunzhi.marketing.entity.*;
import com.yunzhi.marketing.mapper.*;
import com.yunzhi.marketing.service.*;
import jodd.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * <p>
 * 认筹单(认筹记录表)  服务实现类
 * </p>
 *
 * @author jobob
 * @since 2020-02-26
 */
@Service
public class TaRaiseRecordServiceImpl extends ServiceImpl<TaRaiseRecordMapper, TaRaiseRecord> implements ITaRaiseRecordService {

    private Logger logger = LoggerFactory.getLogger(TaRaiseRecordServiceImpl.class);

    @Autowired
    private TaRaiseRecordMapper taRaiseRecordMapper;

    @Autowired
    private TaRaiseMapper taRaiseMapper;

    @Autowired
    private TaHousingResourcesMapper taHousingResourcesMapper;

    @Autowired
    private TaSalesBatchMapper taSalesBatchMapper;

    @Autowired
    private TaPersonMapper taPersonMapper;

    @Autowired
    private TaRaiseHouseMapper taRaiseHouseMapper;

    @Autowired
    private TaUserServiceImpl taUserService;

    @Autowired
    private MiniAppServiceImpl miniAppService;

    @Autowired
    private TaPersonServiceImpl taPersonService;

    @Autowired
    private TaBuildingMapper taBuildingMapper;

    @Autowired
    SMSUtils smsUtils;

    @Autowired
    private ITaRaiseService taRaiseService;

    @Autowired
    private ITaOrderService taOrderService;

    @Autowired
    private ITaBuildingImgService taBuildingImgService;

    @Autowired
    private ITaRaiseHouseService taRaiseHouseService;

    @Autowired
    private ITaHousingResourcesService taHousingResourcesService;

    @Autowired
    private ITaBuildingApartmentService taBuildingApartmentService;

    @Autowired
    private ITaContractService iTaContractService;

    @Autowired
    private ITaContractBusinessService iTaContractBusinessService;

    @Override
    public ResponseBean listHousingRaiseByCondition(HousingRaiseRequestBO requestBO, Integer pageNumber, Integer pageSize) {
        logger.info("TaRaiseRecordServiceImpl.listRaiseRecordByCondition 接收参数：bo:{},pageNumber:{},pageSize:{}", JSONObject.toJSONString(requestBO), pageNumber, pageSize);

        ResponseBean responseBean = new ResponseBean();
        IPage<TaRaiseRecord> pg = new Page<>(pageNumber, pageSize);
        responseBean.addSuccess(taRaiseRecordMapper.listHousingRaiseByCondition(pg, requestBO));
        return responseBean;
    }

    @Override
    public ResponseBean listRaiseRecordByCondition(RaiseRecordRequestBO recordRequestBO, Integer pageNumber, Integer pageSize) {
        logger.info("TaRaiseRecordServiceImpl.listRaiseRecordByCondition 接收参数：bo:{},pageNumber:{},pageSize:{}", JSONObject.toJSONString(recordRequestBO), pageNumber, pageSize);

        ResponseBean responseBean = new ResponseBean();
        IPage<TaRaiseRecord> pg = new Page<>(pageNumber, pageSize);
        responseBean.addSuccess(taRaiseRecordMapper.listRaiseRecordByCondition(pg, recordRequestBO));
        return responseBean;
    }

    @Override
    public ResponseBean listRaiseOrderByCondition(RaiseOrderRequestBO orderRequestBO, Integer pageNumber, Integer pageSize) {
        logger.info("TaRaiseRecordServiceImpl.listOrderByCondition 接收参数：bo:{},pageNumber:{},pageSize:{}", JSONObject.toJSONString(orderRequestBO), pageNumber, pageSize);

        ResponseBean responseBean = new ResponseBean();
        IPage<TaRaiseRecord> pg = new Page<>(pageNumber, pageSize);
        responseBean.addSuccess(taRaiseRecordMapper.listRaiseOrderByCondition(pg, orderRequestBO));
        return responseBean;
    }

    /**
     * 小程序端保存认筹单信息
     *
     * @param taRaiseRecord
     * @param orgId
     * @param personId
     * @return
     */
    @Override
    public TaRaiseRecord saveRaiseInfo(TaRaiseRecord taRaiseRecord, Integer orgId, String personId) throws Exception {
        List<Integer> houseList = taRaiseRecord.getHouseList();
        if (houseList.size() < 1) {
            throw new Exception("请选择房源！");
        }
//        //校验手机号
//        if(!smsUtils.checkCaptcha(taRaiseRecord.getTel(),taRaiseRecord.getCaptcha())){
//            throw new Exception("验证码错误。");
//        }
        //获取认筹信息
        TaRaise taRaise = taRaiseMapper.selectById(taRaiseRecord.getRaiseId());
        //如果是自动锁房就要判断里面的房源有没有被锁住
        if (taRaise.getHouseLockingType().equals(CommConstant.HOUSE_LOCKING_TYPE_AUTO)) {
            if (houseList.size() > 1) {
                throw new Exception("此认筹为自动锁房只能选择一个房源！");
            }
            //获取房源详细信息
            TaHousingResources taHousingResources = taHousingResourcesMapper.selectById(houseList.get(0));
            if (null == taHousingResources) {
                throw new Exception("此房源不存在！");
            }
            if (CommConstant.HOUSE_LOCKING_STATUS_LOCKED.equals(taHousingResources.getHouseLockingStatus())) {
                throw new Exception("此房源已被锁定！");
            }
            //检验成功的话先锁定房源
//            lockedHouseResources(taHousingResources);
        }
        //判断销售批次是否是发布状态和房源是否正常状态
        checkHouseStatus(taRaiseRecord, orgId, personId, taRaise);

        //插入认筹单
        saveRaiseRecord(taRaiseRecord, orgId, personId, taRaise);

        //发送订阅消息
        sendRaiseMsg(taRaiseRecord.getRaiseRecordId(), personId, "认筹通知", "已提交认筹", "点击详情查看认筹单", "房源紧俏，请赶紧缴费", true);

        return taRaiseRecord;
    }

    //判断销售批次是否是发布状态和房源是否正常状态
    private void checkHouseStatus(TaRaiseRecord taRaiseRecord, Integer orgId, String personId, TaRaise taRaise) throws Exception {
        //销售批次是否有效状态
        TaSalesBatch taSalesBatch = taSalesBatchMapper.selectById(taRaise.getSalesBatchId());
        if (!taSalesBatch.getStatus().equals(CommConstant.STATUS_NORMAL)) {
            throw new Exception("此销售批次已经取消发布！");
        }
        //判断房源是否已经删除
        List<Integer> houseList = taRaiseRecord.getHouseList();
        for (Integer houseId : houseList) {
            TaHousingResources taHousingResources = taHousingResourcesMapper.selectById(houseId);
            if (taHousingResources.getStatus() != CommConstant.STATUS_NORMAL) {
                throw new Exception("存在已经删除的房源！");
            }
            //判断我是否认筹过这些房源
//            QueryWrapper<TaRaiseHouse> taRaiseHouseQueryWrapper = new QueryWrapper<>();
//            taRaiseHouseQueryWrapper.eq("org_id", orgId);
//            taRaiseHouseQueryWrapper.eq("house_id", houseId);
//            taRaiseHouseQueryWrapper.eq("person_id", personId);
//            List<TaRaiseHouse> taRaiseHouses = taRaiseHouseMapper.selectList(taRaiseHouseQueryWrapper);
//            if (taRaiseHouses.size() > 0) {
//                throw new Exception("存在已经认筹过的房源！");
//            }
        }
    }

    @Override
    public TaRaiseRecord getUserInfo(Integer raiseRecordId, Integer orgId) {
        return taRaiseRecordMapper.getUserInfo(raiseRecordId, orgId);
    }

    @Override
    public Boolean addHouseNum(Integer raiseRecordId, Integer orgId, Integer userId) {

        String updateUser = "";

        // 获取用户信息
        QueryWrapper<TaUser> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("user_id", userId);
        userQueryWrapper.ne("status", -1);
        TaUser taUser = taUserService.getOne(userQueryWrapper);
        if (taUser != null) {
            updateUser = taUser.getUserName();
        }
        return taRaiseRecordMapper.addHouseNum(raiseRecordId, orgId, updateUser);
    }

    /**
     * 插入认筹单
     *
     * @param taRaiseRecord
     */
    private void saveRaiseRecord(TaRaiseRecord taRaiseRecord, Integer orgId, String personId, TaRaise taRaise) {
        List<Integer> houseList = taRaiseRecord.getHouseList();
        //销售批次信息
        TaSalesBatch taSalesBatch = taSalesBatchMapper.selectById(taRaiseRecord.getSalesBatchId());
        //获取用户信息

        taRaiseRecord.setOrgId(orgId);
        taRaiseRecord.setBuildingId(taSalesBatch.getBuildingId());
        taRaiseRecord.setPersonId(personId);
        taRaiseRecord.setHouseNum(houseList.size());
        taRaiseRecord.setHouseLockingStatus(CommConstant.HOUSE_LOCKING_STATUS_UNLOCKED);
//        if (taRaise.getHouseLockingType().equals(CommConstant.HOUSE_LOCKING_TYPE_AUTO)) {
//            taRaiseRecord.setHouseLockingStatus(CommConstant.HOUSE_LOCKING_STATUS_LOCKED);
//        }
        taRaiseRecord.setStatus(CommConstant.STATUS_NORMAL);
        taRaiseRecord.setPayStatus(CommConstant.PAY_STATUS_UNPAID);
        taRaiseRecord.setPayType(CommConstant.PAY_TYPE_ONLINE);
        taRaiseRecord.setCreateDate(LocalDateTime.now());
        taRaiseRecord.setUpdateDate(LocalDateTime.now());
        //插入认筹单信息
        taRaiseRecordMapper.insert(taRaiseRecord);

        //插入房源与认筹单关系表
        TaPerson taPerson = taPersonMapper.selectById(personId);
        houseList.forEach(e -> {
            TaRaiseHouse taRaiseHouse = new TaRaiseHouse();
            taRaiseHouse.setHouseId(e);
            taRaiseHouse.setCreateDate(LocalDateTime.now());
            taRaiseHouse.setOrgId(orgId);
            taRaiseHouse.setRaiseRecordId(taRaiseRecord.getRaiseRecordId());
            taRaiseHouseMapper.insert(taRaiseHouse);

            //更新房源的实际热度
            TaHousingResources taHousingResources = taHousingResourcesMapper.selectById(e);
            Integer raiseRealHeat = taHousingResources.getRaiseRealHeat();
            if (null == raiseRealHeat) {
                raiseRealHeat = 0;
            }
            taHousingResources.setRaiseRealHeat(raiseRealHeat + 1);
            taHousingResourcesMapper.updateById(taHousingResources);
        });

        //把idcard字断更新进person表
        if (StringUtil.isEmpty(taPerson.getIdcard())) {
            taPerson.setIdcard(taRaiseRecord.getIdcard());
        }
        if (StringUtil.isEmpty(taPerson.getName())) {
            taPerson.setName(taRaiseRecord.getName());
        }

        taPersonMapper.updateById(taPerson);
    }

    /**
     * 锁定房源
     *
     * @param taHousingResources
     */
    private synchronized void lockedHouseResources(TaHousingResources taHousingResources) {
        taHousingResources.setHouseLockingStatus(CommConstant.HOUSE_LOCKING_STATUS_LOCKED);
        taHousingResourcesMapper.updateById(taHousingResources);
    }


    /**
     * 发送认筹订阅消息
     *
     * @param raiseRecordId 认筹单ID
     * @param personId      用户ID
     * @param title         审核类型
     * @param result        审核结果
     * @param remark        失败原因
     * @param isSuccess     是否成功 true是(只有成功才发送短信)
     */
    @Override
    public void sendRaiseMsg(Integer raiseRecordId, String personId, String title, String result, String reason, String remark, Boolean isSuccess) {
        logger.info("sendSubscribeMsg 接收参数：houseId:{},checkType:{},result:{}，reason:{}, remark:{}",
                raiseRecordId, title, result, reason, remark);

        ExecutorService threadPool = Executors.newCachedThreadPool();
        threadPool.execute(() -> {
            logger.info("sendSubscribeMsg 开始");

            // 获取房源详情
            TaRaiseRecord taRaiseRecord = taRaiseRecordMapper.selectById(raiseRecordId);
            if (null == taRaiseRecord) {
                logger.info("sendSubscribeMsg 未找到认筹单。");
                return;
            }
            TaBuilding taBuilding = taBuildingMapper.selectById(taRaiseRecord.getBuildingId());
            // 获取用户信息
            TaPerson toUser = taPersonService.getById(personId);
            if (toUser == null) {
                return;
            }

            String link = String.format(CommConstant.RAISE_DETAIL_PATH, raiseRecordId);

            miniAppService.sendCheckMessage(toUser, link, title, result, taBuilding.getBuildingName(), reason, remark, LocalDateTime.now(), isSuccess);
            if(title.equals("电子合同")){
                miniAppService.sendContractMessage(toUser, link, title, result, taBuilding.getBuildingName(), reason, remark, LocalDateTime.now(), isSuccess);
            }
            logger.info("sendSubscribeMsg 结束");
        });
    }

    @Override
    public Boolean updateForSubtractRaiseHeat(Integer raiseRecordId) {
        logger.info("TaRaiseRecordServiceImpl.updateForSubtractRaiseHeat 接收参数:raiseRecordId:{}", raiseRecordId);
        return taHousingResourcesMapper.updateForSubtractRaiseHeat(raiseRecordId);
    }

    @Override
    public Boolean updateHouseLockingStatus(Integer raiseRecordId, String houseLockingStatus, String personId) {
        logger.info("TaRaiseRecordServiceImpl.updateHouseLockingStatus 接收参数:raiseRecordId:{},houseLockingStatus:{}", raiseRecordId, houseLockingStatus);
        return taHousingResourcesMapper.updateHouseLockingStatus(raiseRecordId, houseLockingStatus, personId);
    }

    @Override
    public ResponseBean wxGetRaiseRecordById(Integer raiseRecordId, String personId, Integer orgId) {
        ResponseBean responseBean = new ResponseBean();

        //获取认筹单信息
        TaRaiseRecord taRaiseRecord = getById(raiseRecordId);

        //认筹表数据
        TaRaise taRaise = taRaiseService.getById(taRaiseRecord.getRaiseId());
        taRaise.setRaisePrice(taRaise.getRaisePrice());
        //置业顾问信息
        TaUser consultantInfo = taUserService.getById(taRaiseRecord.getUserId());
        if (null != consultantInfo) {
            //职业顾问信息
            TaPerson consultantPerson = taPersonService.getOne(new QueryWrapper<TaPerson>().eq("user_id", taRaiseRecord.getUserId()));
            if (null != consultantPerson) {
                consultantInfo.setConsultantPersonId(consultantPerson.getPersonId());
            }
        }

        taRaiseRecord.setConsultantInfo(consultantInfo);
        //房源与认筹单关系图
        List<TaRaiseHouse> taRaiseHouseList = taRaiseHouseService.list(new QueryWrapper<TaRaiseHouse>().eq("raise_record_id", taRaiseRecord.getRaiseRecordId()));

        //房源信息
        List<TaHousingResources> houseList = (List<TaHousingResources>) taHousingResourcesService.listByIds(taRaiseHouseList.stream().map(TaRaiseHouse::getHouseId).collect(Collectors.toList()));

        //我的认筹和锁定
        houseList.forEach(e -> {
            taRaiseHouseList.forEach(r -> {
                //我的认筹
                if (e.getHouseId().equals(r.getHouseId()) && CommConstant.HOUSE_LOCKING_STATUS_LOCKED.equals(e.getHouseLockingStatus()) && personId.equals(e.getHouseLockingPerson())) {
                    e.setMineLocked("mine");
                }
            });

            //塞入户型信息
            if (!StringUtils.isEmpty(e.getApartmentId())) {
                TaBuildingApartment buildingApartment = taBuildingApartmentService.getById(e.getApartmentId());
                e.setApartmentName(buildingApartment.getApartmentName());
                e.setInsideArea(buildingApartment.getInsideArea());
                e.setBuildingArea(buildingApartment.getBuildingArea());
                //塞入户型图信息
                List<String> apartMentIds = new ArrayList<>();
                apartMentIds.add(e.getApartmentId());
                List<TaBuildingImg> apartMentList = taBuildingImgService.getAparemnetList(apartMentIds);
                e.setApartmentImgList(apartMentList);
            }
        });

        Map<String, Object> map = new HashMap<>();
        map.put("refundOrder", null);
        //订单信息
        TaOrder taOrder = taOrderService.getById(taRaiseRecord.getOrderId());
        if (null != taOrder) {
            //退费信息
            TaOrder refundOrder = taOrderService.getOne(new QueryWrapper<TaOrder>().eq("parent_order_id", taOrder.getOrderId()));
            map.put("refundOrder", refundOrder);
        }

        // 是否展示签署合同入口
        if (CommConstant.STATUS_NORMAL == taRaiseRecord.getStatus() && CommConstant.PAY_STATUS_PAID.equals(taRaiseRecord.getPayStatus())) {
            // 是否有认筹业务合同配置
            QueryWrapper<TaContractBusiness> taContractBusinessQueryWrapper = new QueryWrapper<>();
            taContractBusinessQueryWrapper.eq("target_id", taRaiseRecord.getRaiseId());
            taContractBusinessQueryWrapper.eq("org_id", orgId);
            taContractBusinessQueryWrapper.eq("status", CommConstant.STATUS_NORMAL);
            TaContractBusiness taContractBusiness = iTaContractBusinessService.getOne(taContractBusinessQueryWrapper);
            if (taContractBusiness != null) {
                // 是否有有关联的认筹合同
                QueryWrapper<TaContract> taContractQueryWrapper = new QueryWrapper<>();
                taContractQueryWrapper.eq("org_id", orgId);
                taContractQueryWrapper.eq("target_type", "raise");
                taContractQueryWrapper.eq("target_id", taRaiseRecord.getRaiseId());
                taContractQueryWrapper.eq("invoice_target_type", "raise_record");
                taContractQueryWrapper.eq("invoice_target_id", taRaiseRecord.getRaiseRecordId());
                taContractQueryWrapper.eq("company_id", taContractBusiness.getCompanyId());
                taContractQueryWrapper.eq("building_id", taRaiseRecord.getBuildingId());
                taContractQueryWrapper.eq("person_id", personId);
                TaContract taContract = iTaContractService.getOne(taContractQueryWrapper);
                if (taContract != null) {
                    // 合同状态正常
                    if (CommConstant.STATUS_NORMAL == taContract.getStatus()) {
                        taRaiseRecord.setShowContract(0);
                        map.put("taContract", taContract);
                    } else {
                        taRaiseRecord.setShowContract(1);
                    }
                } else {
                    taRaiseRecord.setShowContract(1);
                }
            } else {
                taRaiseRecord.setShowContract(0);
            }
        } else {
            taRaiseRecord.setShowContract(0);
        }

        map.put("taRaiseRecord", taRaiseRecord);
        map.put("taRaiseHouseList", taRaiseHouseList);
        map.put("houseList", houseList);
        map.put("taOrder", taOrder);
        map.put("taRaise", taRaise);
        responseBean.addSuccess(map);
        return responseBean;
    }
}
