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

import com.github.pagehelper.PageInfo;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.grid.*;
import com.ruoyi.system.domain.grid.ext.GridCompanyExt;
import com.ruoyi.system.domain.grid.GridCompanySafeCheck;
import com.ruoyi.system.domain.lawcase.vo.CaseSafeCheckCountBean;
import com.ruoyi.system.domain.grid.vo.GridCompanySafeCheckExt;
import com.ruoyi.system.domain.grid.vo.GridCompanySafeCheckParam;
import com.ruoyi.system.mapper.grid.GridCompanyExtMapper;
import com.ruoyi.system.mapper.grid.GridCompanySafeCheckExtMapper;
import com.ruoyi.system.mapper.grid.GridCompanySafeCheckMapper;
import com.ruoyi.system.service.BaseServiceImpl;
import com.ruoyi.system.service.grid.GridCompanyService;
import com.ruoyi.system.service.grid.GridRegionService;
import com.ruoyi.system.service.grid.GridCompanySafeCheckAttachmentService;
import com.ruoyi.system.service.grid.GridCompanySafeCheckService;
import com.ruoyi.system.service.other.BsCommonService;
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.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils;

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

/**
 * @author Cesar
 * @date ${cTime}
 * @desc CaseSafeCheckService实现
 */
@Service
public class GridCompanySafeCheckServiceImpl extends BaseServiceImpl<GridCompanySafeCheckMapper, GridCompanySafeCheck, GridCompanySafeCheckExample> implements GridCompanySafeCheckService {

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

    @Autowired
    GridCompanySafeCheckMapper GridCompanySafeCheckMapper;
    @Autowired
    GridCompanySafeCheckExtMapper GridCompanySafeCheckExtMapper;
    @Autowired
    GridCompanySafeCheckAttachmentService GridCompanySafeCheckAttachmentService;
    @Autowired
    GridCompanyService wsCompanyService;
    @Autowired
    GridRegionService bsWgxxbService;
    @Autowired
    TransactionTemplate transactionTemplate;
    @Autowired
    BsCommonService bsCommonService;
    @Autowired
    GridCompanyExtMapper wsCompanyExtMapper;

    @Override
    public PageInfo pageInfos(GridCompanySafeCheckParam check, Integer pageNo, Integer pageSize) {
        PageInfo<GridCompanySafeCheckExt> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(pageNo);
        pageInfo.setPageSize(pageSize);
        if (StringUtils.isBlank(check.getIsValid())) {
            check.setIsValid("1");
        }
        int currIndex = (pageNo - 1) * pageSize;
        if (StringUtils.isNotBlank(check.getWgCode())) {
            GridRegionExample ex = new GridRegionExample();
            GridRegionExample.Criteria ca = ex.createCriteria();
            ca.andWgCodeEqualTo(check.getWgCode());
            ca.andWgTypeEqualTo("1");
            ca.andIsValidEqualTo("1");
            GridRegion bsWgxxb = bsWgxxbService.selectFirstByExample(ex);
            if (bsWgxxb == null) {
                throw new RuntimeException("查询失败：找不到对应的网格");
            }
            if (!"1".equals(bsWgxxb.getLevel())) {
                List<String> companyIds = getWgChildIds(bsWgxxb);
                if (CollectionUtils.isEmpty(companyIds)) {
                    return pageInfo;
                }
                check.setCompanyIds(companyIds);
            }
        }
        int totalIndex = (int) GridCompanySafeCheckExtMapper.countByExample(check);
        check.setCurrIndex(currIndex);
        check.setPageSize(pageSize);
        pageInfo.setTotal(totalIndex);
        if (totalIndex == 0) {
            pageInfo.setList(new ArrayList<>());
            return pageInfo;
        }
        List<GridCompanySafeCheckExt> checkExts = GridCompanySafeCheckExtMapper.selectByExample(check);
        if (!CollectionUtils.isEmpty(checkExts)) {
            for (GridCompanySafeCheckExt ext : checkExts) {
                List<GridCompanySafeCheckAttachment> attachments = GridCompanySafeCheckAttachmentService.listAttachments(ext.getId());
                ext.setAttachmentList(attachments);
            }
        }
        pageInfo.setList(checkExts);
        return pageInfo;
    }

    @Override
    public GridCompanySafeCheckExt detail(String id) {
        GridCompanySafeCheck GridCompanySafeCheck = GridCompanySafeCheckMapper.selectByPrimaryKey(id);
        if (GridCompanySafeCheck == null) {
            throw new RuntimeException("查询失败：未找到对应数据");
        }
        GridCompanySafeCheckExt check = new GridCompanySafeCheckExt();
        BeanUtils.copyProperties(GridCompanySafeCheck, check);
        GridCompany company = wsCompanyService.selectByPrimaryKey(check.getCompanyId());
        if (company != null) {
            check.setCompanyName(company.getCompanyName());
            check.setCompanyType(company.getQylxCode());
            check.setCompanyTypeName(bsCommonService.getName(company.getQylxCode()));
            check.setWgCode(company.getWgCode());
            GridRegionExample ex = new GridRegionExample();
            GridRegionExample.Criteria ca = ex.createCriteria();
            ca.andWgCodeEqualTo(company.getWgCode());
            ca.andIsValidEqualTo("1");
            GridRegion bsWgxxb = bsWgxxbService.selectFirstByExample(ex);
            check.setWgName(bsWgxxb == null ? "" : bsWgxxb.getWgName());
        }
        check.setCheckStatusName(bsCommonService.getName(check.getCheckStatus()));
        check.setCheckTypeName(bsCommonService.getName(check.getCheckType()));
        List<GridCompanySafeCheckAttachment> attachments = GridCompanySafeCheckAttachmentService.listAttachments(id);
        check.setAttachmentList(attachments);
        return check;
    }

    @Override
    public void save(GridCompanySafeCheckExt check) {
        if (StringUtils.isBlank(check.getCompanyId())
                || StringUtils.isBlank(check.getCheckUserId())
                || StringUtils.isBlank(check.getCheckUserName())
                || StringUtils.isBlank(check.getCheckStatus())
                || StringUtils.isBlank(check.getCheckTime())
                || StringUtils.isBlank(check.getCheckFeedback())
                || CollectionUtils.isEmpty(check.getAttachmentList())
                || StringUtils.isBlank(check.getClockLatitude())
                || StringUtils.isBlank(check.getClockLongitude())
                || StringUtils.isBlank(check.getCheckType())) {
            throw new RuntimeException("保存失败：缺少必要参数");
        }
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                GridCompanySafeCheck GridCompanySafeCheck = new GridCompanySafeCheck();
                BeanUtils.copyProperties(check, GridCompanySafeCheck);
                GridCompanySafeCheck.setIsValid("1");
                GridCompanySafeCheck.setId(UUID.randomUUID().toString());
                GridCompanySafeCheck.setCreateTime(DateUtils.getTime());
                GridCompanySafeCheckMapper.insert(GridCompanySafeCheck);
                GridCompanySafeCheckAttachmentService.saveAttachments(check.getAttachmentList(), GridCompanySafeCheck.getId());
            }
        });
    }

    @Override
    public void update(GridCompanySafeCheckExt check) {
        if (StringUtils.isBlank(check.getId())
                || StringUtils.isBlank(check.getCheckUserId())
                || StringUtils.isBlank(check.getCheckUserName())
                || StringUtils.isBlank(check.getCheckStatus())
                || StringUtils.isBlank(check.getCheckTime())
                || StringUtils.isBlank(check.getCheckFeedback())
                || CollectionUtils.isEmpty(check.getAttachmentList())
                || StringUtils.isBlank(check.getClockLatitude())
                || StringUtils.isBlank(check.getClockLongitude())
                || StringUtils.isBlank(check.getCheckType())) {
            throw new RuntimeException("复查失败：缺少必要参数");
        }
        GridCompanySafeCheck GridCompanySafeCheck = GridCompanySafeCheckMapper.selectByPrimaryKey(check.getId());
        if (GridCompanySafeCheck == null) {
            throw new RuntimeException("复查失败：未找到对应的安监检查记录");
        }
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                GridCompanySafeCheck.setCheckUserId(check.getCheckUserId());
                GridCompanySafeCheck.setCheckUserName(check.getCheckUserName());
                GridCompanySafeCheck.setCheckStatus(check.getCheckStatus());
                GridCompanySafeCheck.setCheckTime(check.getCheckTime());
                GridCompanySafeCheck.setCheckFeedback(check.getCheckFeedback());
                GridCompanySafeCheck.setClockLatitude(check.getClockLatitude());
                GridCompanySafeCheck.setClockLongitude(check.getClockLongitude());
                GridCompanySafeCheck.setCheckType(check.getCheckType());
                GridCompanySafeCheckMapper.updateByPrimaryKey(GridCompanySafeCheck);
                GridCompanySafeCheckAttachmentService.saveAttachments(check.getAttachmentList(), check.getId());
            }
        });
    }

    @Override
    public void delete(String id) {
        GridCompanySafeCheck check = GridCompanySafeCheckMapper.selectByPrimaryKey(id);
        if (check == null) {
            throw new RuntimeException("删除失败：未找到对应的安监检查记录");
        }
        check.setIsValid("0");
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                GridCompanySafeCheckMapper.updateByPrimaryKey(check);
                GridCompanySafeCheckAttachmentService.saveAttachments(null, id);
            }
        });
    }

    @Override
    public long countThirthNum(String companyId) {
        String thirthDay = DateUtils.getAddDate(DateUtils.getTime(), -30);
        GridCompanySafeCheckExample example = new GridCompanySafeCheckExample();
        example.createCriteria().andCompanyIdEqualTo(companyId).andCheckTimeGreaterThanOrEqualTo(thirthDay);
        return GridCompanySafeCheckMapper.countByExample(example);
    }

    @Override
    public Map countSafeCheckInfo(String wgCode) {
        Map<String, Object> result = new HashMap<>();
        result.put("checkAllNum", 0);
        result.put("checkCompanyNum", 0);
        result.put("checkUnHgNum", 0);
        result.put("checkMonthNum", 0);
        result.put("checkWeekNum", 0);
        result.put("checkDayNum", 0);
        GridCompanySafeCheckExample allCheckExample = new GridCompanySafeCheckExample();
        GridCompanySafeCheckExample.Criteria criteria = allCheckExample.createCriteria();
        criteria.andIsValidEqualTo("1");
        // 不传和传了最高的网格id效果一样
        // 获取传了网格id
        if (StringUtils.isNotBlank(wgCode)) {
            GridRegion bsWgxxb = bsWgxxbService.loadDetailByCode(wgCode);
            if (bsWgxxb == null) {
                throw new RuntimeException("查询失败：找不到对应的网格");
            }
            if (!"1".equals(bsWgxxb.getLevel())) {
                List<String> companyIds = getWgChildIds(bsWgxxb);
                if (CollectionUtils.isEmpty(companyIds)) {
                    return result;
                }
                criteria.andCompanyIdIn(companyIds);
            }
        }
        List<GridCompanySafeCheck> safeChecks = this.selectByExample(allCheckExample);
        if (CollectionUtils.isEmpty(safeChecks)) {
            return result;
        }
        String monthFirstDayStr = DateUtils.getCurrentMonthBeginDay();
        String weekFirstDayStr = DateUtils.getCurrentWeekBeginDay();
        String currentDayStr = DateUtils.getDate();
        Date monthFirstDay = DateUtils.getPastDate(monthFirstDayStr, DateUtils.YYYY_MM_DD);
        Date weekFirstDay = DateUtils.getPastDate(weekFirstDayStr, DateUtils.YYYY_MM_DD);
        Date currentDay = DateUtils.getPastDate(currentDayStr, DateUtils.YYYY_MM_DD);
        Set<String> companyIdSet = new HashSet<>();
        Set<String> unHgCompanyIdSet = new HashSet<>();
        int checkMonthNum = 0;
        int checkWeekNum = 0;
        int checkDayNum = 0;
        for (GridCompanySafeCheck safeCheck : safeChecks) {
            companyIdSet.add(safeCheck.getCompanyId());
            if ("bhg".equals(safeCheck.getCheckStatus()) || "fjbhg".equals(safeCheck.getCheckStatus())) {
                unHgCompanyIdSet.add(safeCheck.getCompanyId());
            }
            long checkTime = DateUtils.getPastDate(safeCheck.getCheckTime(), DateUtils.YYYY_MM_DD).getTime();
            if (checkTime >= monthFirstDay.getTime()) {
                checkMonthNum++;
            }
            if (checkTime >= weekFirstDay.getTime()) {
                checkWeekNum++;
            }
            if (checkTime >= currentDay.getTime()) {
                checkDayNum++;
            }
        }
        result.put("checkAllNum", safeChecks.size());
        result.put("checkCompanyNum", companyIdSet.size());
        result.put("checkUnHgNum", unHgCompanyIdSet.size());
        result.put("checkMonthNum", checkMonthNum);
        result.put("checkWeekNum", checkWeekNum);
        result.put("checkDayNum", checkDayNum);
        return result;
    }

    @Override
    public Map countCompanyCheckInfo(String wgCode) {
        Map<String, Object> result = new HashMap<>();
        result.put("hg", 0);
        result.put("bhg", 0);
        result.put("fjhg", 0);
        result.put("fjbhg", 0);
        GridCompanySafeCheckExample allCheckExample = new GridCompanySafeCheckExample();
        GridCompanySafeCheckExample.Criteria criteria = allCheckExample.createCriteria();
        criteria.andIsValidEqualTo("1");
        if (StringUtils.isNotBlank(wgCode)) {
            GridRegion bsWgxxb = bsWgxxbService.loadDetailByCode(wgCode);
            if (bsWgxxb == null) {
                throw new RuntimeException("查询失败：找不到对应的网格");
            }
            if (!"1".equals(bsWgxxb.getLevel())) {
                List<String> companyIds = getWgChildIds(bsWgxxb);
                if (CollectionUtils.isEmpty(companyIds)) {
                    return result;
                }
                criteria.andCompanyIdIn(companyIds);
            }
        }
        List<GridCompanySafeCheck> safeChecks = this.selectByExample(allCheckExample);
        if (CollectionUtils.isEmpty(safeChecks)) {
            return result;
        }
        Map<String, List<GridCompanySafeCheck>> safeCheckMap = safeChecks.stream().collect(Collectors.groupingBy(GridCompanySafeCheck::getCheckStatus));
        int hgNum = 0;
        int bhgNum = 0;
        int fjhgNum = 0;
        int fjbhgNum = 0;
        if (safeCheckMap.containsKey("hg")) {
            Set<String> companyIds = new HashSet<>();
            for (GridCompanySafeCheck safeCheck : safeCheckMap.get("hg")) {
                companyIds.add(safeCheck.getCompanyId());
            }
            hgNum = companyIds.size();
        }
        if (safeCheckMap.containsKey("bhg")) {
            Set<String> companyIds = new HashSet<>();
            for (GridCompanySafeCheck safeCheck : safeCheckMap.get("bhg")) {
                companyIds.add(safeCheck.getCompanyId());
            }
            bhgNum = companyIds.size();
        }
        if (safeCheckMap.containsKey("fjbhg")) {
            Set<String> companyIds = new HashSet<>();
            for (GridCompanySafeCheck safeCheck : safeCheckMap.get("fjbhg")) {
                companyIds.add(safeCheck.getCompanyId());
            }
            fjbhgNum = companyIds.size();
        }
        if (safeCheckMap.containsKey("fjhg")) {
            Set<String> companyIds = new HashSet<>();
            for (GridCompanySafeCheck safeCheck : safeCheckMap.get("fjhg")) {
                companyIds.add(safeCheck.getCompanyId());
            }
            fjhgNum = companyIds.size();
        }
        result.put("hg", hgNum);
        result.put("bhg", bhgNum);
        result.put("fjhg", fjhgNum);
        result.put("fjbhg", fjbhgNum);
        return result;
    }

    @Override
    public List<CaseSafeCheckCountBean> countCountryCheckInfo(String wgCode) {
        if (StringUtils.isBlank(wgCode)) {
            return GridCompanySafeCheckExtMapper.countCountryCheck(null, null);
        }
        GridRegion bsWgxxb = bsWgxxbService.loadDetailByCode(wgCode);
        if (bsWgxxb == null) {
            throw new RuntimeException("查询失败：找不到对应的网格");
        }
        if ("1".equals(bsWgxxb.getLevel())) {
            return GridCompanySafeCheckExtMapper.countCountryCheck(null, null);
        }
        return GridCompanySafeCheckExtMapper.countCountryCheck(bsWgxxb.getLevel(), bsWgxxb.getWgCode());
    }

    @Override
    public List<Map<String, Object>> countSevenDayCheckInfo(String wgCode) {
        List<Map<String, Object>> result = new ArrayList<>();
        List<String> days = DateUtils.getDateStrsBetween(DateUtils.addDate(new Date(), -7), new Date());
        for (String day : days) {
            Map<String, Object> map = new HashMap<>();
            map.put("day", day);
            map.put("num", 0);
            result.add(map);
        }
        GridCompanySafeCheckExample allCheckExample = new GridCompanySafeCheckExample();
        GridCompanySafeCheckExample.Criteria criteria = allCheckExample.createCriteria();
        criteria.andIsValidEqualTo("1").andCheckTimeGreaterThanOrEqualTo(days.get(0));
        if (StringUtils.isNotBlank(wgCode)) {
            GridRegion bsWgxxb = bsWgxxbService.loadDetailByCode(wgCode);
            if (bsWgxxb == null) {
                throw new RuntimeException("查询失败：找不到对应的网格");
            }
            if (!"1".equals(bsWgxxb.getLevel())) {
                List<String> companyIds = getWgChildIds(bsWgxxb);
                if (CollectionUtils.isEmpty(companyIds)) {
                    return result;
                }
                criteria.andCompanyIdIn(companyIds);
            }
        }
        List<GridCompanySafeCheck> safeChecks = this.selectByExample(allCheckExample);
        if (CollectionUtils.isEmpty(safeChecks)) {
            return result;
        }
        Map<String, List<GridCompanySafeCheck>> safeCheckMap = safeChecks.stream().collect(Collectors.groupingBy(GridCompanySafeCheck::getCheckTime));
        for (Map<String, Object> map : result) {
            String day = map.get("day").toString();
            if (safeCheckMap.containsKey(day)) {
                map.put("num", safeCheckMap.get(day).size());
            }
        }
        return result;
    }

    @Override
    public PageInfo countPageInfo(GridCompanySafeCheckParam check, Integer pageNo, Integer pageSize) {
        PageInfo<GridCompanySafeCheckExt> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(pageNo);
        pageInfo.setPageSize(pageSize);
        if (StringUtils.isNotBlank(check.getWgId())) {
            GridRegion bsWgxxb = bsWgxxbService.loadDetailByCode(check.getWgId());
            if (bsWgxxb == null) {
                throw new RuntimeException("查询失败：找不到对应的网格");
            }
            if (!"1".equals(bsWgxxb.getLevel())) {
                List<String> companyIds = getWgChildIds(bsWgxxb);
                if (CollectionUtils.isEmpty(companyIds)) {
                    return pageInfo;
                }
                check.setCompanyIds(companyIds);
            }
        }
        if (StringUtils.isBlank(check.getIsValid())) {
            check.setIsValid("1");
        }
        int currIndex = (pageNo - 1) * pageSize;
        int totalIndex = (int) GridCompanySafeCheckExtMapper.countCompanyList(check);
        check.setCurrIndex(currIndex);
        check.setPageSize(pageSize);
        pageInfo.setTotal(totalIndex);
        if (totalIndex == 0) {
            pageInfo.setList(new ArrayList<>());
            return pageInfo;
        }
        List<GridCompanySafeCheckExt> checkExts = GridCompanySafeCheckExtMapper.selectCompanyList(check);
        pageInfo.setList(checkExts);
        return pageInfo;
    }

    @Override
    public PageInfo countPointPageInfo(GridCompanySafeCheckParam check, Integer pageNo, Integer pageSize) {
        PageInfo<GridCompanySafeCheckExt> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(pageNo);
        pageInfo.setPageSize(pageSize);
        int currIndex = (pageNo - 1) * pageSize;
        int totalIndex = (int) GridCompanySafeCheckExtMapper.countCompanyList(check);
        check.setCurrIndex(currIndex);
        check.setPageSize(pageSize);
        pageInfo.setTotal(totalIndex);
        if (totalIndex == 0) {
            pageInfo.setList(new ArrayList<>());
            return pageInfo;
        }
        List<GridCompanySafeCheckExt> checkExts = GridCompanySafeCheckExtMapper.selectCompanyList(check);
        if (!CollectionUtils.isEmpty(checkExts)) {
            for (GridCompanySafeCheckExt ext : checkExts) {
                List<GridCompanySafeCheckAttachment> attachments = GridCompanySafeCheckAttachmentService.listAttachments(ext.getId());
                ext.setAttachmentList(attachments);
            }
        }
        pageInfo.setList(checkExts);
        return pageInfo;
    }

    // 根据网格获取网格下的所有关联企业
    private List<String> getWgChildIds(GridRegion rootWg) {
        List<GridCompany> wsCompanies = new ArrayList<>();
        List<String> companyIds = new ArrayList<>();
        GridCompanyExt extParam = new GridCompanyExt();
        extParam.setWgCode(rootWg.getWgCode());
        extParam.setWgValue(rootWg.getWgType());
        extParam.setIsValid((byte) 1);
        if ("2".equals(rootWg.getLevel())) {
            wsCompanies = wsCompanyExtMapper.selectCompanyBySecondLevel(extParam);
        } else if ("3".equals(rootWg.getLevel())) {
            wsCompanies = wsCompanyExtMapper.selectCompanyByThirdLevel(extParam);
        } else if ("4".equals(rootWg.getLevel())) {
            wsCompanies = wsCompanyExtMapper.selectCompanyByForthLevel(extParam);
        }
        if (CollectionUtils.isEmpty(wsCompanies)) {
            return null;
        }
        for (GridCompany wsCompany : wsCompanies) {
            companyIds.add(wsCompany.getId());
        }
        return companyIds;
    }


}
