package com.ruoyi.system.service.visit.impl;

import cn.hutool.core.lang.Validator;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.zqt.ZQTPageUtil;
import com.ruoyi.common.zqt.ZQTreeNode;
import com.ruoyi.system.domain.grid.GridRegion;
import com.ruoyi.system.domain.grid.GridRegionExample;
import com.ruoyi.system.domain.grid.GridRegionUser;
import com.ruoyi.system.domain.system.SysOtherappAttachment;
import com.ruoyi.system.domain.system.SysOtherappAttachmentExample;
import com.ruoyi.system.domain.system.enums.AttachEnums;
import com.ruoyi.system.domain.visit.*;
import com.ruoyi.system.domain.visit.ext.VisitFreePlanModelExt;
import com.ruoyi.system.domain.visit.vo.VisitPlanSearchParam;
import com.ruoyi.system.listener.MyBaseService;
import com.ruoyi.system.mapper.grid.GridHouseMapper;
import com.ruoyi.system.mapper.grid.GridPeopleMapper;
import com.ruoyi.system.mapper.system.SysOtherappAttachmentMapper;
import com.ruoyi.system.mapper.visit.VisitFreePlanModelMapper;
import com.ruoyi.system.service.BaseServiceImpl;
import com.ruoyi.system.service.grid.*;
import com.ruoyi.system.service.visit.VisitFreeInterviewService;
import com.ruoyi.system.service.visit.VisitFreePlanModelService;
import com.ruoyi.system.service.visit.VisitFreePlanService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

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

/**
 * VisitFreePlanModelService实现
 * Created by cesar.X on 2022/6/21.
 */
@Service
@MyBaseService
public class VisitFreePlanModelServiceImpl extends BaseServiceImpl<VisitFreePlanModelMapper, VisitFreePlanModel, VisitFreePlanModelExample> implements VisitFreePlanModelService {

    private static final Logger LOGGER = LoggerFactory.getLogger(VisitFreePlanModelServiceImpl.class);

    @Autowired
    VisitFreePlanModelMapper visitFreePlanModelMapper;

    @Autowired
    SysOtherappAttachmentMapper sysOtherappAttachmentMapper;

    @Autowired
    VisitFreePlanService visitFreePlanService;

    @Autowired
    VisitFreeInterviewService visitFreeInterviewService;

    @Autowired
    GridRegionService gridRegionService;

    @Autowired
    GridCompanyService gridCompanyService;

    @Autowired
    GridShopService gridShopService;

    @Autowired
    GridHouseService gridHouseService;

    @Autowired
    GridHouseMapper gridHouseMapper;

    @Autowired
    GridPeopleService gridPeopleService;

    @Autowired
    GridPeopleMapper gridPeopleMapper;

    @Autowired
    GridRegionUserService gridRegionUserService;

    @Autowired
    VisitAsyncServiceImpl asyncService;

    private static String comma = ",";


    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult addVisitFreePlanModel(VisitFreePlanModelExt visitFreePlanModel) {

        String id = UUID.randomUUID().toString();
        visitFreePlanModel.setId(id);

        //附件
        if (!CollectionUtils.isEmpty(visitFreePlanModel.getOtherappAttachments())) {
            for (SysOtherappAttachment attachment : visitFreePlanModel.getOtherappAttachments()) {
                attachment.setAttachType(AttachEnums.AttachType.FREE_PLAN.name());
                attachment.setBusinessId(id);
                sysOtherappAttachmentMapper.insertSelective(attachment);
            }
        }

        visitFreePlanModel.setUpdateTime(new Date());
        visitFreePlanModelMapper.insertSelective(visitFreePlanModel);

        if ("2".equals(visitFreePlanModel.getPlanStatus())) {
            if (StringUtils.isEmpty(visitFreePlanModel.getPlanWgCode()) ||
                    visitFreePlanModel.getPlanWgCode().split(comma).length <= 0) {
                visitFreePlanModel.setExceptionDesc("自由走访计划网格未传");
                visitFreePlanModel.setPlanStatus("5");
                visitFreePlanModelMapper.updateByPrimaryKeySelective(visitFreePlanModel);
                return AjaxResult.error(400, "自由走访计划网格未传");
            }
            visitFreePlanModel.setPlanStatus("3");
            visitFreePlanModelMapper.updateByPrimaryKeySelective(visitFreePlanModel);

            asyncService.dealFreePlan(visitFreePlanModel);
        }

        return AjaxResult.success(null);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public AjaxResult updateVisitFreePlanModel(VisitFreePlanModelExt visitFreePlanModel) {
        Validator.validateNotEmpty(visitFreePlanModel.getId(), "自由走访id未传");

        //附件
        if (!CollectionUtils.isEmpty(visitFreePlanModel.getOtherappAttachments())) {
            SysOtherappAttachmentExample example = new SysOtherappAttachmentExample();
            example.createCriteria().andBusinessIdEqualTo(visitFreePlanModel.getId())
                    .andAttachTypeEqualTo(AttachEnums.AttachType.FREE_PLAN.name());
            sysOtherappAttachmentMapper.deleteByExample(example);

            for (SysOtherappAttachment attachment : visitFreePlanModel.getOtherappAttachments()) {
                attachment.setAttachType(AttachEnums.AttachType.FREE_PLAN.name());
                attachment.setBusinessId(visitFreePlanModel.getId());
                sysOtherappAttachmentMapper.insertSelective(attachment);
            }
        }

        visitFreePlanModel.setUpdateTime(new Date());
        visitFreePlanModelMapper.updateByPrimaryKeySelective(visitFreePlanModel);

        if ("2".equals(visitFreePlanModel.getPlanStatus())) {
            if (StringUtils.isEmpty(visitFreePlanModel.getPlanWgCode()) ||
                    visitFreePlanModel.getPlanWgCode().split(comma).length <= 0) {
                visitFreePlanModel.setExceptionDesc("自由走访计划网格未传");
                visitFreePlanModel.setPlanStatus("5");
                visitFreePlanModelMapper.updateByPrimaryKeySelective(visitFreePlanModel);
                return AjaxResult.error(400, "自由走访计划网格未传");
            }

            asyncService.dealFreePlan(visitFreePlanModel);
        }

        return AjaxResult.success(null);
    }


    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void delete(String id) {
        Validator.validateNotEmpty(id, "自由走访id未传");

        SysOtherappAttachmentExample example = new SysOtherappAttachmentExample();
        example.createCriteria().andBusinessIdEqualTo(id)
                .andAttachTypeEqualTo(AttachEnums.AttachType.FREE_PLAN.name());

        SysOtherappAttachment attachment = new SysOtherappAttachment();
        attachment.setValid(Byte.valueOf("0"));
        sysOtherappAttachmentMapper.updateByExampleSelective(attachment, example);

        VisitFreePlanExample planExample = new VisitFreePlanExample();
        planExample.createCriteria().andPlanModelIdEqualTo(id);

        VisitFreePlan freePlan = new VisitFreePlan();
        freePlan.setIsValid("0");
        visitFreePlanService.updateByExampleSelective(freePlan, planExample);

        List<VisitFreePlan> plans = visitFreePlanService.selectByExample(planExample);

        if (!CollectionUtils.isEmpty(plans)) {
            List<String> planIds = plans.stream().map(VisitFreePlan::getId).collect(Collectors.toList());

            VisitFreeInterviewExample interviewExample = new VisitFreeInterviewExample();
            interviewExample.createCriteria().andPlanIdIn(planIds);

            VisitFreeInterview interview = new VisitFreeInterview();
            interview.setIsValid("0");
            visitFreeInterviewService.updateByExampleSelective(interview, interviewExample);
        }

        VisitFreePlanModel planModel = new VisitFreePlanModel();
        planModel.setId(id);
        planModel.setIsValid("0");
        planModel.setUpdateTime(new Date());
        visitFreePlanModelMapper.updateByPrimaryKeySelective(planModel);
    }

    @Override
    public VisitFreePlanModelExt info(String id) {
        Validator.validateNotEmpty(id, "自由走访id未传");

        VisitFreePlanModel planModel = visitFreePlanModelMapper.selectByPrimaryKey(id);

        VisitFreePlanModelExt planModelExt = new VisitFreePlanModelExt();
        BeanUtils.copyProperties(planModel, planModelExt);

        if (null != planModelExt) {
            SysOtherappAttachmentExample example = new SysOtherappAttachmentExample();
            example.createCriteria().andBusinessIdEqualTo(id)
                    .andAttachTypeEqualTo(AttachEnums.AttachType.FREE_PLAN.name());
            List<SysOtherappAttachment> attachmentList = sysOtherappAttachmentMapper.selectByExample(example);
            planModelExt.setOtherappAttachments(attachmentList);
        }

        return planModelExt;
    }

    @Override
    public ZQTreeNode freePlanTree(String planModelId) {

        Validator.validateNotEmpty(planModelId, "自由走访id未传");

        VisitFreePlanModel planModel = visitFreePlanModelMapper.selectByPrimaryKey(planModelId);

        if (null == planModel || StringUtils.isEmpty(planModel.getPlanWgCode())) {
            return null;
        }

        List<String> wgCodes = new ArrayList<>();
        for (String wgCode : planModel.getPlanWgCode().split(comma)) {
            wgCodes.add(wgCode);
        }

        GridRegionExample wgxxbExample = new GridRegionExample();
        wgxxbExample.createCriteria().andWgCodeIn(wgCodes);
        List<GridRegion> thirdWgList = gridRegionService.selectByExample(wgxxbExample);

        //二级网格
        List<String> secondCodeList = thirdWgList.stream().map(GridRegion::getWgParentId).collect(Collectors.toList());
        GridRegionExample secondWgExample = new GridRegionExample();
        secondWgExample.createCriteria().andWgCodeIn(secondCodeList).andLevelEqualTo("2");
        List<GridRegion> secondWgList = gridRegionService.selectByExample(secondWgExample);

        ZQTreeNode result = new ZQTreeNode();
        List<ZQTreeNode> secondResult = new ArrayList<>();

        for (GridRegion secondWg : secondWgList) {
            if (secondCodeList.contains(secondWg.getWgCode())) {
                ZQTreeNode map = new ZQTreeNode();
                map.setId(secondWg.getId());
                map.setCode(secondWg.getWgCode());
                map.setName(secondWg.getWgName());
                map.setParentId(secondWg.getWgParentId());
                map.setLevel(secondWg.getLevel());
                secondResult.add(map);
                List<ZQTreeNode> thirdResult = new ArrayList<>();

                for (GridRegion thirdWg : thirdWgList) {
                    ZQTreeNode thirdmap = new ZQTreeNode();
                    if (org.apache.commons.lang3.StringUtils.isNotEmpty(thirdWg.getWgParentId()) && thirdWg.getWgParentId().equals(secondWg.getWgCode())) {
                        thirdmap.setId(thirdWg.getId());
                        thirdmap.setCode(thirdWg.getWgCode());
                        thirdmap.setName(thirdWg.getWgName());
                        thirdmap.setParentId(thirdWg.getWgParentId());
                        thirdmap.setLevel(thirdWg.getLevel());
                        thirdResult.add(thirdmap);
                    }
                }
                map.setChild(thirdResult);
            }
        }

        GridRegionExample wgExample = new GridRegionExample();
        wgExample.createCriteria().andLevelEqualTo("1").andIsValidEqualTo("1");
        List<GridRegion> gridRegionList = gridRegionService.selectByExample(wgExample);
        result.setChild(secondResult);
        if (gridRegionList.size() > 0) {
            GridRegion gridRegion = gridRegionList.get(0);
            result.setLevel("1");
            result.setName(gridRegion.getWgName());
            result.setCode(gridRegion.getWgCode());
            result.setId(gridRegion.getId());
        }

        return result;
    }

    @Override
    public PageInfo<VisitFreePlanModelExt> freePlanModelPage(String visitType, int pageNum, int pageSize,
                                                             Long planAllNum, String startTime, String endTime, String planType, String planTitle, String planStatus, String wgCode) {
        VisitFreePlanModelExample example = new VisitFreePlanModelExample();
        VisitFreePlanModelExample.Criteria criteria = example.createCriteria();
        VisitFreePlanModelExample.Criteria criteria2 = example.createCriteria();
        VisitFreePlanModelExample.Criteria criteria3 = example.createCriteria();
        VisitFreePlanModelExample.Criteria criteria4 = example.createCriteria();

        criteria.andIsValidEqualTo("1");
        criteria2.andIsValidEqualTo("1");
        criteria3.andIsValidEqualTo("1");
        criteria4.andIsValidEqualTo("1");

        if (null != planAllNum) {
            criteria.andPlanAllNumEqualTo(planAllNum);
            criteria2.andPlanAllNumEqualTo(planAllNum);
            criteria3.andPlanAllNumEqualTo(planAllNum);
            criteria4.andPlanAllNumEqualTo(planAllNum);
        }
        if(org.apache.commons.lang3.StringUtils.isNotBlank(visitType)){
            criteria.andVisitTypeEqualTo(visitType);
            criteria2.andVisitTypeEqualTo(visitType);
            criteria3.andVisitTypeEqualTo(visitType);
            criteria4.andVisitTypeEqualTo(visitType);
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(startTime)
                && org.apache.commons.lang3.StringUtils.isNotBlank(endTime)) {
            // 1 2 2 1
            criteria.andStartTimeLessThanOrEqualTo(startTime);
            criteria.andEndTimeGreaterThanOrEqualTo(endTime);

            // 1 2 1 2
            criteria2.andStartTimeLessThanOrEqualTo(startTime);
            criteria2.andEndTimeGreaterThanOrEqualTo(startTime);
            criteria2.andEndTimeLessThanOrEqualTo(endTime);

            // 2 1 2 1
            criteria3.andStartTimeGreaterThanOrEqualTo(startTime);
            criteria3.andStartTimeLessThanOrEqualTo(endTime);
            criteria3.andEndTimeGreaterThanOrEqualTo(endTime);

            // 2 1 1 2
            criteria4.andStartTimeGreaterThanOrEqualTo(startTime);
            criteria4.andEndTimeLessThanOrEqualTo(endTime);
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(planType)) {
            criteria.andPlanTypeEqualTo(planType);
            criteria2.andPlanTypeEqualTo(planType);
            criteria3.andPlanTypeEqualTo(planType);
            criteria4.andPlanTypeEqualTo(planType);
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(planTitle)) {
            criteria.andPlanTitleLike("%" + planTitle + "%");
            criteria2.andPlanTitleLike("%" + planTitle + "%");
            criteria3.andPlanTitleLike("%" + planTitle + "%");
            criteria4.andPlanTitleLike("%" + planTitle + "%");
        }

        if (org.apache.commons.lang3.StringUtils.isNotBlank(planStatus)) {
            criteria.andPlanStatusEqualTo(planStatus);
            criteria2.andPlanStatusEqualTo(planStatus);
            criteria3.andPlanStatusEqualTo(planStatus);
            criteria4.andPlanStatusEqualTo(planStatus);
        }

        if (org.apache.commons.lang3.StringUtils.isNotBlank(wgCode)) {
            criteria.andPlanWgCodeLike("%" + wgCode + "%");
            criteria2.andPlanWgCodeLike("%" + wgCode + "%");
            criteria3.andPlanWgCodeLike("%" + wgCode + "%");
            criteria4.andPlanWgCodeLike("%" + wgCode + "%");
        }

        example.or(criteria2);
        example.or(criteria3);
        example.or(criteria4);
        example.setOrderByClause(" update_time desc");

        PageHelper.startPage(pageNum, pageSize);
        List<VisitFreePlanModel> visitFreePlanModels = visitFreePlanModelMapper.selectByExampleWithBLOBs(example);
        int count = (int) visitFreePlanModelMapper.countByExample(example);
        List<VisitFreePlanModelExt> modelExts = new ArrayList<>();
        if(count == 0){
            PageInfo<VisitFreePlanModelExt> pageInfo = new PageInfo<>(modelExts);
            return ZQTPageUtil.build(pageInfo, pageNum, pageSize, count);
        }

        List<String> modelIds = visitFreePlanModels.stream().map(VisitFreePlanModel::getId).collect(Collectors.toList());

        VisitFreePlanExample planExample = new VisitFreePlanExample();
        planExample.createCriteria().andPlanModelIdIn(modelIds).andIsValidEqualTo("1");
        List<VisitFreePlan> freePlans = visitFreePlanService.selectByExample(planExample);


        visitFreePlanModels.forEach(planModel -> {
            VisitFreePlanModelExt modelExt = new VisitFreePlanModelExt();
            BeanUtils.copyProperties(planModel, modelExt);
            Long doneNum = freePlans.stream().filter(o -> planModel.getId().equals(o.getPlanModelId()) && "4".equals(o.getHasDone())).count();
            modelExt.setDoneNum(doneNum);
            modelExts.add(modelExt);
        });

        PageInfo<VisitFreePlanModelExt> pageInfo = new PageInfo<>(modelExts);
        return ZQTPageUtil.build(pageInfo, pageNum, pageSize, count);
    }

    @Override
    public PageInfo<VisitFreePlan> freePlanPage(SysUser sysUser, String visitType, int pageNum, int pageSize,
                                                String wgCode, String hasDone, String planTitle) {
        //权限筛选
        List<SysRole> roleList = sysUser.getRoles();
        if(CollectionUtils.isEmpty(roleList)){
            throw new ServiceException("无网格权限查看！");
        }
        List<String> roleKeys = roleList.stream().map(SysRole::getRoleKey).distinct().collect(Collectors.toList());
        List<String> permissionWgCodes = new ArrayList<>();
        if(roleKeys.contains("admin") || roleKeys.contains("onegrid") || roleKeys.contains("centerman")){
            //可以查看所有
        }else if(roleKeys.contains("twogrid") || roleKeys.contains("threegird")){
            List<GridRegionUser> list = gridRegionUserService.getPermissionWgCodes(sysUser.getUserId());
            if(com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(list)) {
                throw new ServiceException("未绑定网格！");
            }
            permissionWgCodes = list.stream().map(GridRegionUser::getWgId).collect(Collectors.toList());
        }else{
            throw new ServiceException("无网格权限查看！");
        }
        VisitPlanSearchParam param = new VisitPlanSearchParam();
        param.setVisitType(visitType);
        param.setHasDone(hasDone);
        param.setPlanTitle(planTitle);
        //选中了某个网格
        if(org.apache.commons.lang3.StringUtils.isNotBlank(wgCode)){
            param.setWgCodeLikes(Lists.newArrayList(wgCode));
        }else{
            //否则按权限查
            param.setWgCodeLikes(permissionWgCodes);
        }
        PageHelper.startPage(pageNum, pageSize);
        List<VisitFreePlan> visitFreePlanModels = visitFreePlanService.listByParams(param);
        PageInfo<VisitFreePlan> pageInfo = new PageInfo<>(visitFreePlanModels);
        if(!CollectionUtils.isEmpty(pageInfo.getList())){
            for(VisitFreePlan freePlan : pageInfo.getList()){
                freePlan.setWgName(gridRegionService.getWgName(freePlan.getWgCode()));
            }
        }
        return pageInfo;
    }
}