package com.huiju.estateagents.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.huiju.estateagents.base.ResponseBean;
import com.huiju.estateagents.bo.request.PresecretRecordRequestBO;
import com.huiju.estateagents.common.CommConstant;
import com.huiju.estateagents.common.DateUtils;
import com.huiju.estateagents.entity.*;
import com.huiju.estateagents.mapper.TaApartmentImgMapper;
import com.huiju.estateagents.mapper.TaBuildingImgMapper;
import com.huiju.estateagents.mapper.TaHousingResourcesMapper;
import com.huiju.estateagents.mapper.TaPreselectionRecordMapper;
import com.huiju.estateagents.po.TaHousingResourcesPO;
import com.huiju.estateagents.po.TaPreselectionRecordPO;
import com.huiju.estateagents.service.ITaBuildingApartmentService;
import com.huiju.estateagents.service.ITaHousingResourcesService;
import com.huiju.estateagents.service.ITaPreselectionRecordService;
import org.apache.commons.collections.CollectionUtils;
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 org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * <p>
 * 预选记录表  服务实现类
 * </p>
 *
 * @author jobob
 * @since 2020-02-10
 */
@Service
public class TaPreselectionRecordServiceImpl extends ServiceImpl<TaPreselectionRecordMapper, TaPreselectionRecord> implements ITaPreselectionRecordService {

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

    @Autowired
    private TaPreselectionRecordMapper taPreselectionRecordMapper;

    @Autowired
    private TaHousingResourcesMapper taHousingResourcesMapper;

    @Autowired
    TaBuildingImgMapper taBuildingImgMapper;

    @Autowired
    TaApartmentImgMapper taApartmentImgMapper;

    @Autowired
    private MiniAppServiceImpl miniAppService;

    @Autowired
    private TaPersonServiceImpl taPersonService;

    @Autowired
    private ITaHousingResourcesService taHousingResourcesService;

    @Autowired
    public ITaBuildingApartmentService taBuildingApartmentService;


    @Override
    public IPage<TaPreselectionRecordPO> listPreselectionRecord(Integer pageNum, Integer pageSize, Integer orgId, String personId, String buildingId,
                                                                Integer salesBatchId, String apartmentId, String houseLockingStatus, String customerLocked,
                                                                String source) {
        logger.info("listPreselectionRecord 接收参数：pageNum：{}，pageSize：{}，orgId：{}，personId：{},source:{}", pageNum, pageSize, orgId, personId, source);

        IPage<TaPreselectionRecordPO> iPage = new Page<>(pageNum, pageSize);
        iPage = taPreselectionRecordMapper.listPreselectionRecord(iPage, orgId, personId, buildingId, salesBatchId, apartmentId, houseLockingStatus, customerLocked, source);

        List<TaPreselectionRecordPO> poList = iPage.getRecords();
        if (CollectionUtils.isEmpty(poList)) {
            return iPage;
        }

        List<TaPreselectionRecordPO> resultList = new ArrayList<>();
        List<TaBuildingImg> taBuildingImgList;
        List<TaApartmentImg> buildingImg;
        QueryWrapper<TaApartmentImg> apartmentImgQueryWrapper;
        QueryWrapper<TaBuildingImg> buildingImgQueryWrapper;
        for (TaPreselectionRecordPO po : poList) {
            apartmentImgQueryWrapper = new QueryWrapper<>();
            apartmentImgQueryWrapper.eq("apartment_id", po.getApartmentId());
            buildingImg = taApartmentImgMapper.selectList(apartmentImgQueryWrapper);
            for (TaApartmentImg apartmentImg : buildingImg) {
                buildingImgQueryWrapper = new QueryWrapper<>();
                buildingImgQueryWrapper.eq("img_id", apartmentImg.getImgId());
                buildingImgQueryWrapper.eq("img_type", CommConstant.BUILDING_IMG_APARMENT);
                buildingImgQueryWrapper.orderByAsc("order_no");
                taBuildingImgList = taBuildingImgMapper.selectList(buildingImgQueryWrapper);
                po.setBuildingImgList(taBuildingImgList);
            }
            resultList.add(po);
        }

        // 获取房源信息
        resultList.stream().forEach(record -> {
            QueryWrapper<TaHousingResources> housingQueryWrapper = new QueryWrapper<>();
            housingQueryWrapper.eq("org_id", record.getOrgId());
            housingQueryWrapper.eq("house_id", record.getHouseId());
            housingQueryWrapper.ne("status", -1);
            TaHousingResources housingResources = taHousingResourcesService.getOne(housingQueryWrapper);
            //户型图name
            if (null != housingResources){
                TaBuildingApartment buildingApartment = taBuildingApartmentService.getById(housingResources.getApartmentId());
                if (null != buildingApartment){
                    housingResources.setApartmentName(buildingApartment.getApartmentName());
                    housingResources.setBuildingArea(buildingApartment.getBuildingArea());
                    housingResources.setInsideArea(buildingApartment.getInsideArea());
                }
            }

            record.setHousingInfo(housingResources);
        });

        iPage.setRecords(resultList);
        return iPage;
    }

    @Override
    @Transactional
    public ResponseBean taPreselectionRecordAdd(TaPreselectionRecord taPreselectionRecord) {
        logger.info("listPreselectionRecord 接收参数：taPreselectionRecord:{}", JSONObject.toJSONString(taPreselectionRecord));

        ResponseBean responseBean = new ResponseBean();
        String tip;
        String checkType = "预选";

        Integer houseId = taPreselectionRecord.getHouseId();
        String personId = taPreselectionRecord.getPersonId();

        // 校验用户是否已经预选房源
        TaPreselectionRecord record = taPreselectionRecordMapper.getRecordByPersonIdAndHouseId(personId, houseId);
        if (record != null) {
            tip = "已预选过此房源。";
            sendSubscribeMsg(houseId, personId, checkType, "失败", tip, false);
            responseBean.addError(tip);
            return responseBean;
        }

        TaHousingResourcesPO resourcesPO = taHousingResourcesMapper.getHousingDetailById(taPreselectionRecord.getHouseId(), "0");
        if (resourcesPO == null) {
            tip = "当前房源已临时取消发布。";
            sendSubscribeMsg(houseId, personId, checkType, "失败", tip, false);
            responseBean.addError(tip);
            return responseBean;
        }

        // 校验当前批次状态是否为已发布
        if (resourcesPO.getSaleBatchStatus() != 1) {
            tip = "当前销售批次已临时取消发布。";
            sendSubscribeMsg(houseId, personId, checkType, "失败", tip, false);
            responseBean.addError(tip);
            return responseBean;
        }

        // 校验当前房源状态是否为已发布
        if (1 != resourcesPO.getStatus()) {
            tip = "当前房源已临时取消发布。";
            sendSubscribeMsg(houseId, personId, checkType, "失败", tip, false);
            responseBean.addError(tip);
            return responseBean;
        }

        // 校验预选操作时间是否在规定范围内
        if (!DateUtils.checkTimeRange(resourcesPO.getPreselectionStartTime(), resourcesPO.getPreselectionEndTime(), null)) {
            tip = "当前时间不在预选时间范围内。";
            sendSubscribeMsg(houseId, personId, checkType, "失败", tip, false);
            responseBean.addError(tip);
            return responseBean;
        }

        // 添加预选记录
        taPreselectionRecord.setSalesBatchId(resourcesPO.getSalesBatchId());
        taPreselectionRecord.setStatus(1);
        taPreselectionRecord.setCreateDate(LocalDateTime.now());
        taPreselectionRecord.setUpdateDate(LocalDateTime.now());
        save(taPreselectionRecord);

        // 更新房源表热度
        Boolean result = taHousingResourcesMapper.updateForAddHeat(taPreselectionRecord.getHouseId());
        if (result) {
            sendSubscribeMsg(houseId, personId, checkType, "成功", "无", true);
            responseBean.addSuccess(taPreselectionRecord);
            return responseBean;
        }
        tip = "未知原因失败，请联系置业顾问。";
        sendSubscribeMsg(houseId, personId, checkType, "失败", tip, false);
        responseBean.addError(tip);
        return responseBean;
    }

    @Override
    @Transactional
    public ResponseBean taPreselectionRecordCancel(String personId, Integer houseId) {
        logger.info("taPreselectionRecordCancel 接收参数：personId：{}，houseId：{}", personId, houseId);

        ResponseBean responseBean = new ResponseBean<>();

        // 校验是否已经取消
        TaPreselectionRecord preselectionRecord = taPreselectionRecordMapper.getRecordByPersonIdAndHouseId(personId, houseId);
        if (preselectionRecord == null) {
            responseBean.addError("未预选过此房源，或已取消预选此房源");
            return responseBean;
        }

        TaHousingResourcesPO resourcesPO = taHousingResourcesMapper.getHousingDetailById(houseId, "0");
        if (resourcesPO == null || 1 != resourcesPO.getStatus()) {
            responseBean.addError("当前房源已临时取消发布，请稍后再试或联系置业顾问了解详情。");
            return responseBean;
        }

        // 校验当前批次状态是否为已发布
        if (resourcesPO.getSaleBatchStatus() != 1) {
            responseBean.addError("当前销售批次已临时取消发布，请稍后再试或联系置业顾问了解详情。");
            return responseBean;
        }

        // 更新预选记录
        TaPreselectionRecord record = new TaPreselectionRecord();
        record.setPreselectionRecordId(preselectionRecord.getPreselectionRecordId());
        record.setStatus(0);
        record.setUpdateDate(LocalDateTime.now());
        updateById(record);

        // 更新房源表热度
        Boolean result = taHousingResourcesMapper.updateForSubtractHeat(houseId);
        if (result) {
            responseBean.addSuccess(result);
            return responseBean;
        }
        responseBean.addError("未知原因失败，请联系置业顾问。");
        return responseBean;
    }

    @Override
    public ResponseBean selectPreSelectRecordList(PresecretRecordRequestBO recordRequestBO, Integer pageNum, Integer pageSize) {
        Page page = new Page(pageNum, pageSize);
        // 分页查询
        List<TaPreselectionRecordPO> list = taPreselectionRecordMapper.selectPreSelectRecordList(page, recordRequestBO);
        page.setRecords(list);
        return ResponseBean.success(page);
    }

    @Override
    public ResponseBean batchDeletePreselectRecord(List<TaPreselectionRecord> preselectionRecordList, Integer orgId, Integer userId) {
        ResponseBean responseBean = new ResponseBean();

        // 更新房源表热度信息
        for (TaPreselectionRecord tp : preselectionRecordList) {
            taHousingResourcesMapper.updateForSubtractHeat(tp.getHouseId());
        }

        taPreselectionRecordMapper.batchDeletePreselectRecord(preselectionRecordList, orgId, userId);
        responseBean.addSuccess("success");
        return responseBean;
    }

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

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

            // 获取房源详情
            TaHousingResourcesPO po = taHousingResourcesMapper.getHousingDetailById(houseId, "1");
            if (po == null) {
                logger.info("sendSubscribeMsg 未找到房源信息。");
                return;
            }

            // 获取用户信息
            TaPerson toUser = taPersonService.getById(personId);
            if (toUser == null) {
                return;
            }

            String link = String.format(CommConstant.HOUSE_DETAIL_PATH, houseId);
            String progranName = StringUtils.isBlank(po.getBuildingName()) ? "无" : po.getBuildingName();
            String remark = progranName;
            miniAppService.sendCheckMessage(toUser, link, checkType, result, progranName, failReason, remark, LocalDateTime.now(), isSuccess);
            logger.info("sendSubscribeMsg 结束");
        });
    }
}
