package com.usky.fire.service.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.datascope.annotation.DataScope;
import com.ruoyi.common.datascope.context.DataScopeContextHolder;
import com.usky.common.core.bean.CommonPage;
import com.usky.common.core.exception.BusinessException;
import com.usky.common.core.util.BeanMapperUtils;
import com.usky.common.mybatis.core.AbstractCrudService;
import com.usky.common.security.utils.SecurityUtils;
import com.usky.fire.domain.*;
import com.usky.fire.mapper.PatrolInspectionSiteMapper;
import com.usky.fire.service.PatrolInspectionAreaService;
import com.usky.fire.service.PatrolInspectionSiteService;
import com.usky.fire.service.PatrolInspectionPlanSiteService;
import com.usky.fire.service.PatrolInspectionSiteContentService;
import com.usky.fire.service.util.OnlineMethod;
import com.usky.fire.service.vo.DataCountVo;
import com.usky.fire.service.vo.PatrolInspectionAreaVo;
import com.usky.fire.service.vo.PatrolInspectionSiteExportVo;
import com.usky.fire.service.vo.PatrolInspectionSiteImportVo;
import com.usky.system.model.LoginUser;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author JCB
 * @since 2022-07-13
 */
@Service
public class PatrolInspectionSiteServiceImpl extends AbstractCrudService<PatrolInspectionSiteMapper, PatrolInspectionSite> implements PatrolInspectionSiteService {

    @Autowired
    private PatrolInspectionAreaService patrolInspectionAreaService;

    @Autowired
    private PatrolInspectionSiteContentService siteContentService;

    @Autowired
    private PatrolInspectionPlanSiteService planSiteService;

    @Override
    @DataScope
    public List<PatrolInspectionAreaVo> areaLeftList() {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String userType = null;
        if (loginUser != null && !"".equals(loginUser)) {
            userType = loginUser.getUserType();
        }
        LambdaQueryWrapper<PatrolInspectionArea> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PatrolInspectionArea::getEnable, 1)
                .eq(PatrolInspectionArea::getTenantId, SecurityUtils.getTenantId())
                .apply(Objects.nonNull(DataScopeContextHolder.getDataScopeSql()),DataScopeContextHolder.getDataScopeSql());
        if ("00".equals(userType)) {
            queryWrapper.eq(PatrolInspectionArea::getCreator, SecurityUtils.getUsername());
        }
        List<PatrolInspectionArea> patrolInspectionAreaList = patrolInspectionAreaService.list(queryWrapper);
        LambdaQueryWrapper<PatrolInspectionSite> queryWrapperOne = Wrappers.lambdaQuery();
        queryWrapperOne.eq(PatrolInspectionSite::getEnable, 1)
                .eq(PatrolInspectionSite::getTenantId, SecurityUtils.getTenantId());
        if ("00".equals(userType)) {
            queryWrapperOne.eq(PatrolInspectionSite::getCreator, SecurityUtils.getUsername());
        }
        List<PatrolInspectionSite> list = this.list(queryWrapperOne);
        Map<Integer, List<PatrolInspectionSite>> grouypByAreaId = list.stream().collect(
                Collectors.groupingBy(o -> o.getAreaId())
        );
        List<DataCountVo> dataCountVoList = new ArrayList<>();
        grouypByAreaId.forEach((k, v) -> {
            DataCountVo dataCountVo = new DataCountVo();
            dataCountVo.setListCount(v.size());
            dataCountVo.setId(k);
            dataCountVoList.add(dataCountVo);
        });
        List<PatrolInspectionAreaVo> patrolInspectionAreaVoList = new ArrayList<>();
        if (patrolInspectionAreaList.size() > 0) {
            for (int i = 0; i < patrolInspectionAreaList.size(); i++) {
                PatrolInspectionAreaVo patrolInspectionAreaVo = new PatrolInspectionAreaVo();
                patrolInspectionAreaVo.setXh(i + 1);
                patrolInspectionAreaVo.setId(patrolInspectionAreaList.get(i).getId());
                patrolInspectionAreaVo.setAreaName(patrolInspectionAreaList.get(i).getAreaName());
                patrolInspectionAreaVo.setAreaFid(patrolInspectionAreaList.get(i).getAreaFid());
                patrolInspectionAreaVo.setDeptId(patrolInspectionAreaList.get(i).getDeptId());
                patrolInspectionAreaVo.setTenantId(patrolInspectionAreaList.get(i).getTenantId());
                patrolInspectionAreaVo.setCreator(patrolInspectionAreaList.get(i).getCreator());
                patrolInspectionAreaVo.setCreateTime(patrolInspectionAreaList.get(i).getCreateTime());
                patrolInspectionAreaVo.setEnable(patrolInspectionAreaList.get(i).getEnable());
                patrolInspectionAreaVo.setSiteCount(0);
                for (int j = 0; j < dataCountVoList.size(); j++) {
                    if (patrolInspectionAreaList.get(i).getId() == dataCountVoList.get(j).getId()) {
                        patrolInspectionAreaVo.setSiteCount(dataCountVoList.get(j).getListCount());
                    }
                }
                patrolInspectionAreaVoList.add(patrolInspectionAreaVo);
            }
        }
        List<PatrolInspectionAreaVo> patrolInspectionAreaVoListOne = new ArrayList<>();
        if (patrolInspectionAreaVoList.size() > 0) {
            patrolInspectionAreaVoListOne = OnlineMethod.getChildPerms(patrolInspectionAreaVoList, 0);
        }
        return patrolInspectionAreaVoListOne;
    }

    @Override
    public CommonPage<PatrolInspectionSite> patrolInspectionSiteList(Integer areaId, String siteName, Integer pageNum, Integer pageSize, Integer id) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String userType = null;
        if (loginUser != null && !"".equals(loginUser)) {
            userType = loginUser.getUserType();
        }
        LambdaQueryWrapper<PatrolInspectionSite> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PatrolInspectionSite::getEnable, 1)
                .eq(PatrolInspectionSite::getTenantId, SecurityUtils.getTenantId());
        if ("00".equals(userType)) {
            queryWrapper.eq(PatrolInspectionSite::getCreator, SecurityUtils.getUsername());
        }
        if (areaId != null) {
            queryWrapper.eq(PatrolInspectionSite::getAreaId, areaId);
        }
        if (id != null && id != 0) {
            queryWrapper.eq(PatrolInspectionSite::getId, id);
        }
        if (siteName != null && !"".equals(siteName)) {
            queryWrapper.like(PatrolInspectionSite::getSiteName, siteName);
        }


        Integer total = this.count(queryWrapper);
        queryWrapper.orderByDesc(PatrolInspectionSite::getId);
        if (pageNum != null && pageNum != 0 && pageSize != null && pageSize != 0) {
            Integer startFate = OnlineMethod.getStartFate(pageNum, pageSize);
            queryWrapper.last("limit " + startFate + ","+pageSize);
        }

        List<PatrolInspectionSite> patrolInspectionSiteList = this.list(queryWrapper);
//        List<PatrolInspectionSite> list = patrolInspectionSiteList.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
        return new CommonPage<>(patrolInspectionSiteList, total, pageNum, pageSize);
    }


    @Override
    @Transactional
    public void updatePatrolInspectionSiteList(List<PatrolInspectionSite> patrolInspectionSiteList) {
        for (int i = 0; i < patrolInspectionSiteList.size(); i++) {
            PatrolInspectionSite patrolInspectionSite = new PatrolInspectionSite();
            patrolInspectionSite.setId(patrolInspectionSiteList.get(i).getId());
            patrolInspectionSite.setAreaId(patrolInspectionSiteList.get(i).getAreaId());
            patrolInspectionSite.setPictureUrl(patrolInspectionSiteList.get(i).getPictureUrl());
            patrolInspectionSite.setDistanceRange(patrolInspectionSiteList.get(i).getDistanceRange());
            this.updateById(patrolInspectionSite);
        }
    }

    @Override
    public void updatePatrolInspectionSite(PatrolInspectionSite patrolInspectionSite) {
//        LambdaQueryWrapper<PatrolInspectionPlanSite> queryWrapperOne = Wrappers.lambdaQuery();
//        queryWrapperOne.eq(PatrolInspectionPlanSite::getSiteId, patrolInspectionSite.getId());
//        List<PatrolInspectionPlanSite> planSiteList = planSiteService.list(queryWrapperOne);
//        if (planSiteList.size() > 0) {
//            throw new BusinessException("巡检地点已绑定计划不可修改");
//        }
        this.updateById(patrolInspectionSite);
    }

    @Override
    public void delPatrolInspectionSite(Integer id) {
        LambdaQueryWrapper<PatrolInspectionPlanSite> queryWrapperOne = Wrappers.lambdaQuery();
        queryWrapperOne.eq(PatrolInspectionPlanSite::getSiteId, id);
        List<PatrolInspectionPlanSite> planSiteList = planSiteService.list(queryWrapperOne);
        if (planSiteList.size() > 0) {
            throw new BusinessException("巡检地点已绑定计划不可删除");
        }
        PatrolInspectionSite patrolInspectionSite = new PatrolInspectionSite();
        patrolInspectionSite.setId(id);
        patrolInspectionSite.setEnable(0);
        this.updateById(patrolInspectionSite);
    }


    @Override
    @Transactional
    public void addSiteContent(List<PatrolInspectionSiteContent> siteContentList) {
        List<Integer> list = new ArrayList<>();
        List<Integer> list2 = new ArrayList<>();
        if (siteContentList.size()>0){
            for (int i = 0; i < siteContentList.size(); i++) {
                list.add(siteContentList.get(i).getSiteId());
            }
            list2 = removeDuplicatesUsingHashSet(list);
            LambdaQueryWrapper<PatrolInspectionSiteContent> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.in(PatrolInspectionSiteContent::getSiteId, list2);
            List<PatrolInspectionSiteContent> siteContenListOne = siteContentService.list(queryWrapper);
            if (siteContenListOne.size() > 0) {
                for (int i = 0; i < siteContenListOne.size(); i++) {
                    siteContentService.removeById(siteContenListOne.get(i).getId());
                }
            }
            for (int i = 0; i < siteContentList.size(); i++) {
                siteContentService.save(siteContentList.get(i));
            }
        }
    }

    /**
     * 根据巡检地点ID查询巡检内容ID
     *
     * @param siteId 巡检地点ID
     * @return
     */
    @Override
    public Integer[] siteContentList(Integer siteId) {
        LambdaQueryWrapper<PatrolInspectionSiteContent> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PatrolInspectionSiteContent::getSiteId, siteId);
        List<PatrolInspectionSiteContent> siteContenList = siteContentService.list(queryWrapper);
        Integer[] contenIdList = new Integer[siteContenList.size()];
        if (siteContenList.size() > 0) {
            for (int i = 0; i < siteContenList.size(); i++) {
                contenIdList[i] = siteContenList.get(i).getContentId();
            }
        }
        return contenIdList;
    }


    @Override
    public List<PatrolInspectionSiteExportVo> patrolInspectionSiteListExport(Integer areaId, String siteName, String idList) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String userType = null;
        if (loginUser != null && !"".equals(loginUser)) {
            userType = loginUser.getUserType();
        }
        LambdaQueryWrapper<PatrolInspectionSite> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PatrolInspectionSite::getEnable, 1)
                .eq(PatrolInspectionSite::getTenantId, SecurityUtils.getTenantId());
        if ("00".equals(userType)) {
            queryWrapper.eq(PatrolInspectionSite::getCreator, SecurityUtils.getUsername());
        }
        if (areaId != null) {
            queryWrapper.eq(PatrolInspectionSite::getAreaId, areaId);
        }else{
            queryWrapper.ne(PatrolInspectionSite::getAreaId, 0);
        }
        if (StringUtils.isNotBlank(idList)) {
            List<Integer> siteidList = new ArrayList<>();
            String[] siteIdArray = idList.split(",");
            for (int i = 0; i < siteIdArray.length; i++) {
                siteidList.add(Integer.parseInt(siteIdArray[i]));
            }
            queryWrapper.in(PatrolInspectionSite::getId, siteidList);
        }
        if (StringUtils.isNotBlank(siteName)) {
            queryWrapper.like(PatrolInspectionSite::getSiteName, siteName);
        }
        queryWrapper.orderByDesc(PatrolInspectionSite::getId);
        List<PatrolInspectionSite> patrolInspectionSiteList = this.list(queryWrapper);
        List<PatrolInspectionSiteExportVo> list = new ArrayList<>();
        for (int i = 0; i < patrolInspectionSiteList.size(); i++) {
            PatrolInspectionSiteExportVo patrolInspectionSiteExportVo = new PatrolInspectionSiteExportVo();
            patrolInspectionSiteExportVo.setXh(i + 1);
            patrolInspectionSiteExportVo.setSiteName(patrolInspectionSiteList.get(i).getSiteName());
            patrolInspectionSiteExportVo.setSiteNubmber(patrolInspectionSiteList.get(i).getSiteNubmber());
            patrolInspectionSiteExportVo.setLatitude(patrolInspectionSiteList.get(i).getLatitude());
            patrolInspectionSiteExportVo.setLongitude(patrolInspectionSiteList.get(i).getLongitude());
            patrolInspectionSiteExportVo.setPictureUrl(patrolInspectionSiteList.get(i).getPictureUrl());
            patrolInspectionSiteExportVo.setCreateTime(patrolInspectionSiteList.get(i).getCreateTime().format(df));
            list.add(patrolInspectionSiteExportVo);
        }
        return list;
    }

    @Override
    public List<Integer> siteIdList(List<Integer> areaIdList){
        LambdaQueryWrapper<PatrolInspectionSite> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PatrolInspectionSite::getEnable, 1)
                .in(PatrolInspectionSite::getAreaId, areaIdList);
        List<PatrolInspectionSite> list = this.list(queryWrapper);
        List<Integer> siteIdList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            siteIdList.add(list.get(i).getId());
        }
        return siteIdList;
    }

    @Override
    public void patrolInspectionSiteImport(MultipartFile multipartFile) {
        ImportParams params = new ImportParams();
        params.setHeadRows(1);
        String err="文件导入失败";
        try {
            List<PatrolInspectionSiteImportVo> patrolInspectionSiteImportVos =
                    ExcelImportUtil.importExcel(multipartFile.getInputStream(),
                    PatrolInspectionSiteImportVo.class, params);
            if (CollectionUtils.isNotEmpty(patrolInspectionSiteImportVos)){
                int rot=0;
                for (PatrolInspectionSiteImportVo patrolInspectionSiteImportVo:patrolInspectionSiteImportVos) {
                    PatrolInspectionSite patrolInspectionSite = BeanMapperUtils.map(patrolInspectionSiteImportVo, PatrolInspectionSite.class);
                    patrolInspectionSite.setEnable(1);
                    patrolInspectionSite.setCreator(SecurityUtils.getUsername());
                    patrolInspectionSite.setCollector(SecurityUtils.getLoginUser().getSysUser().getNickName());
                    patrolInspectionSite.setCreateTime(LocalDateTime.now());
                    patrolInspectionSite.setTenantId(SecurityUtils.getTenantId());
                    patrolInspectionSite.setSiteType(2);
                    try{
                        this.save(patrolInspectionSite);
                    }catch (Exception e){
                        int h=rot+2;
                        err="文件导入失败，第"+h+"行数据导入失败";
                        throw  new BusinessException(err);
                    }
                    rot++;
                }
            }else {
                err="文件不能为空";
                throw new BusinessException(err);
            }
        }catch (Exception e){
            throw  new BusinessException(e.getMessage());
        }
    }
    public static <T> List<T> removeDuplicatesUsingHashSet(List<T> list) {
        Set<T> set = new HashSet<>(list);
        return new ArrayList<>(set);
    }

    @Override
    public int siteCount(List<Integer> ids){
        LambdaQueryWrapper<PatrolInspectionSite> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PatrolInspectionSite::getEnable, 1)
                .in(PatrolInspectionSite::getAreaId, ids);
        int siteCounts = this.count(queryWrapper);
        List<Integer> siteIdList = new ArrayList<>();
        return siteCounts;
    }
}
