package com.xinyilu.system.service.applogmanagestatistics.impl;

import com.xinyilu.common.constant.Constants;
import com.xinyilu.common.core.domain.AjaxResult;
import com.xinyilu.common.core.domain.entity.SysRole;
import com.xinyilu.common.core.page.TableDataInfo;
import com.xinyilu.common.enums.LogTypeEnum;
import com.xinyilu.common.utils.AgeUtil;
import com.xinyilu.common.utils.PageServiceUtil;
import com.xinyilu.common.utils.SecurityUtils;
import com.xinyilu.system.domain.applet.AppletClassInfo;
import com.xinyilu.system.domain.applet.AppletParentAndStudentInfo;
import com.xinyilu.system.domain.applet.AppletStudentInfo;
import com.xinyilu.system.domain.applet.ParentAndStudentInfo;
import com.xinyilu.system.domain.applogkindergarteninfo.AppLogKindergartenInfo;
import com.xinyilu.system.domain.dto.AppLogManageStatisticsDTO;
import com.xinyilu.system.domain.organize.OrganizeInfo;
import com.xinyilu.system.domain.systemarea.SysArea;
import com.xinyilu.system.domain.vo.OrganizeInfoVO;
import com.xinyilu.system.domain.vo.SysUserVO;
import com.xinyilu.system.domain.vo.applogmanagestatistics.AppLogManageStatisticsVO;
import com.xinyilu.system.mapper.SysUserMapper;
import com.xinyilu.system.mapper.applet.AppletMapper;
import com.xinyilu.system.mapper.apploginfo.AppLogInfoMapper;
import com.xinyilu.system.mapper.applogkindergarteninfo.AppLogKindergartenInfoMapper;
import com.xinyilu.system.mapper.classinfo.ClassInfoMapper;
import com.xinyilu.system.mapper.organize.OrganizeInfoMapper;
import com.xinyilu.system.mapper.systemarea.SysAreaMapper;
import com.xinyilu.system.service.applogmanagestatistics.AppLogManageStatisticsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Description PC端家长小程序登录日志统计业务层实现类
 * @Author 纪寒
 * @Date 2023-04-14 14:21:48
 * @Version 1.0
 */
@Slf4j
@Service
public class AppLogManageStatisticsServiceImpl implements AppLogManageStatisticsService {

    @Resource
    private AppLogInfoMapper appLogInfoMapper;
    @Resource
    private AppletMapper appletMapper;
    @Resource
    private PageServiceUtil pageServiceUtil;
    @Resource
    private ClassInfoMapper classInfoMapper;
    @Resource
    private OrganizeInfoMapper organizeInfoMapper;
    @Resource
    private SysAreaMapper sysAreaMapper;
    @Resource
    private AppLogKindergartenInfoMapper appLogKindergartenInfoMapper;
    @Resource
    private SysUserMapper userMapper;

    public final static Integer LEVEL = 3;

    /**
     * 小程序访问日志统计
     *
     * @param logManageStatistics 检索条件
     * @return 统计结果
     */
    @Override
    public List<AppLogManageStatisticsVO> appletVisitRecord(AppLogManageStatisticsDTO logManageStatistics) {
        return appLogInfoMapper.appletVisitRecord(logManageStatistics);
    }

    /**
     * 小程序日志-按个人统计
     *
     * @param logManageStatistics 检索条件
     * @return 统计结果
     */
    @Override
    public TableDataInfo appletPersonCount(AppLogManageStatisticsDTO logManageStatistics) {
        //判断当前用户角色，根据不同的角色显示不同的家长信息
        List<String> roleKeys = SecurityUtils.getLoginUser().getUser().getRoles()
                .stream().filter(Objects::nonNull)
                .filter(item -> StringUtils.isNotBlank(item.getRoleKey()))
                .map(SysRole::getRoleKey).collect(Collectors.toList());
        //当前系统用户id
        Long userId = SecurityUtils.getUserId();
        if (roleKeys.contains(Constants.ADMIN_ROLE)) {
            //角色为管理员，查询所有的家长信息
            return getAppLogManagePerson(logManageStatistics);
        } else if (roleKeys.contains(Constants.CITY)) {
            //角色为市级角色，查询该区域下所有幼儿园下得所有班级中的家长的信息 市级
            long areaId = Objects.isNull(SecurityUtils.getLoginUser().getUser().getAreaId()) ? 0 : SecurityUtils.getLoginUser().getUser().getAreaId();
            SysArea sysArea = new SysArea();
            sysArea.setParentId(areaId);
            List<Long> sysAreaIdList = sysAreaMapper.selectSysAreaList(sysArea).stream().filter(Objects::nonNull).filter(sysAreaId -> Objects.nonNull(sysAreaId.getId())).map(SysArea::getId).collect(Collectors.toList());
            List<Long> kindergartenIdList = Lists.newArrayList();
            if (CollectionUtils.isNotEmpty(sysAreaIdList)) {
                //获取该区域下的所有幼儿园信息
                kindergartenIdList = classInfoMapper.getKindergartenInfoByAreaId(sysAreaIdList, null);
            }
            if (CollectionUtils.isEmpty(kindergartenIdList)) {
                return null;
            }
            logManageStatistics.setKindergartenIdList(kindergartenIdList);
            return getAppLogManagePerson(logManageStatistics);
        } else if (roleKeys.contains(Constants.REGION_ROLE)) {
            //角色为区域角色，查询该区域下所有幼儿园下得所有班级中的家长的信息 市级
            long areaId = Objects.isNull(SecurityUtils.getLoginUser().getUser().getAreaId()) ? 0 : SecurityUtils.getLoginUser().getUser().getAreaId();
            List<Long> kindergartenIdList = Lists.newArrayList();
            List<Long> sysAreaIdList = new ArrayList<>();
            sysAreaIdList.add(areaId);
            if (CollectionUtils.isNotEmpty(sysAreaIdList)) {
                //获取该区域下的所有幼儿园信息
                kindergartenIdList = classInfoMapper.getKindergartenInfoByAreaId(sysAreaIdList, 3L);
            }
            if (CollectionUtils.isEmpty(kindergartenIdList)) {
                return null;
            }
            logManageStatistics.setKindergartenIdList(kindergartenIdList);
            return getAppLogManagePerson(logManageStatistics);
        } else if (roleKeys.contains(Constants.ENCHOU_ROLE)) {
            //角色为园长，查询当前幼儿园下的所有家长信息
            Long kindergartenId = classInfoMapper.getKindergartenIdByPrincipalId(userId);
            if (Objects.nonNull(kindergartenId) && kindergartenId != 0L) {
                List<Long> kindergartenIdList = Lists.newArrayList();
                kindergartenIdList.add(kindergartenId);
                logManageStatistics.setKindergartenIdList(kindergartenIdList);
            }else {
                return null;
            }
            return getAppLogManagePerson(logManageStatistics);
        } else if (roleKeys.contains(Constants.HEALTHCARE_ROLE)) {
            //角色是：保健师，查找出其所属的幼儿园信息、
            SysUserVO sysUserVO = userMapper.selectUserById(userId);
            if (Objects.isNull(sysUserVO) || Objects.isNull(sysUserVO.getKindergartenId())) {
                return null;
            }
            List<Long> kindergartenIdList = Lists.newArrayList();
            kindergartenIdList.add(sysUserVO.getKindergartenId());
            logManageStatistics.setKindergartenIdList(kindergartenIdList);
            return getAppLogManagePerson(logManageStatistics);
        }
        return null;
    }

    /**
     * 家长访问小程序日志个人统计
     *
     * @param logManageStatistics 检索条件
     * @return com.xinyilu.common.core.page.TableDataInfo
     **/
    private TableDataInfo getAppLogManagePerson(AppLogManageStatisticsDTO logManageStatistics) {
        pageServiceUtil.startPage();
        List<AppLogManageStatisticsVO> appLogManageStatisticsVO = appLogInfoMapper.appletPersonCount(logManageStatistics);
        return pageServiceUtil.getDataTable(appLogManageStatisticsVO);
    }

    /**
     * 小程序访问日志-按园所统计
     *
     * @param logManageStatistics 检索条件
     * @return 统计结果
     */
    @Override
    public TableDataInfo appletKindergartenCount(AppLogManageStatisticsDTO logManageStatistics) {
        //判断当前用户所属角色，根据角色显示对应数据信息
        List<String> roleKeys = SecurityUtils.getLoginUser().getUser().getRoles()
                .stream().filter(Objects::nonNull)
                .filter(item -> StringUtils.isNotBlank(item.getRoleKey()))
                .map(SysRole::getRoleKey).collect(Collectors.toList());
        //当前系统用户id
        Long userId = SecurityUtils.getUserId();
        if (roleKeys.contains(Constants.ADMIN_ROLE)) {
            //角色为管理员，查询所有幼儿园信息
            return getAppLogManageKindergarten(logManageStatistics);
        } else if (roleKeys.contains(Constants.CITY)) {
            //角色为市级角色，查询该区域内的所有幼儿园的信息
            long areaId = Objects.isNull(SecurityUtils.getLoginUser().getUser().getAreaId()) ? 0 : SecurityUtils.getLoginUser().getUser().getAreaId();
            if (areaId == 0) {
                return null;
            }
            SysArea sysArea = new SysArea();
            sysArea.setParentId(areaId);
            List<Long> sysAreaIdList = sysAreaMapper.selectSysAreaList(sysArea).stream().filter(Objects::nonNull).filter(sysAreaId -> Objects.nonNull(sysAreaId.getId())).map(SysArea::getId).collect(Collectors.toList());
            List<Long> kindergartenIdList = Lists.newArrayList();
            List<Long> organizeIdList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(sysAreaIdList)) {
                //获取该区域下的所有幼儿园信息
                kindergartenIdList = classInfoMapper.getKindergartenInfoByAreaId(sysAreaIdList, null);
            }
            if (CollectionUtils.isNotEmpty(kindergartenIdList)) {
                organizeIdList = organizeInfoMapper.selectOrganizeByKindergartenId(kindergartenIdList).stream().filter(Objects::nonNull).filter(organId -> Objects.nonNull(organId.getOrganizeId())).map(AppLogKindergartenInfo::getOrganizeId).collect(Collectors.toList());
            }
            if (CollectionUtils.isEmpty(organizeIdList)) {
                return null;
            }
            logManageStatistics.setOrganizeIdList(organizeIdList);
            return getAppLogManageKindergarten(logManageStatistics);
        } else if (roleKeys.contains(Constants.REGION_ROLE)) {
            //角色为区域角色，查询该区域内的所有幼儿园的信息 区县级
            long areaId = Objects.isNull(SecurityUtils.getLoginUser().getUser().getAreaId()) ? 0 : SecurityUtils.getLoginUser().getUser().getAreaId();
            List<Long> organizeIdList = Lists.newArrayList();
            if (areaId != 0) {
                //获取该区域下的所有组织信息
                OrganizeInfoVO organizeInfo = new OrganizeInfoVO();
                organizeInfo.setAreaId(areaId);
                organizeInfo.setLevel(3L);
                organizeIdList = organizeInfoMapper.selectOrganizeInfoList(organizeInfo).stream().filter(Objects::nonNull).map(OrganizeInfo::getId).collect(Collectors.toList());
            }
            if (CollectionUtils.isEmpty(organizeIdList)) {
                return null;
            }
            logManageStatistics.setOrganizeIdList(organizeIdList);
            return getAppLogManageKindergarten(logManageStatistics);
        } else if (roleKeys.contains(Constants.ENCHOU_ROLE)) {
            //角色是：园所，查询自己幼儿园的信息
            Long kindergartenId = classInfoMapper.getKindergartenIdByPrincipalId(userId);
            logManageStatistics.setKindergartenId(kindergartenId);
            return getAppLogManageKindergarten(logManageStatistics);
        } else if (roleKeys.contains(Constants.HEALTHCARE_ROLE)) {
            //角色是：保健师，查找出其所属的幼儿园信息
            SysUserVO sysUserVO = userMapper.selectUserById(userId);
            if (Objects.isNull(sysUserVO) || Objects.isNull(sysUserVO.getKindergartenId())) {
                return null;
            }
            Long kindergartenIds = Objects.isNull(sysUserVO.getKindergartenId()) ? 0 : sysUserVO.getKindergartenId();
            logManageStatistics.setKindergartenId(kindergartenIds);
            return getAppLogManageKindergarten(logManageStatistics);
        }
        return null;
    }

    /**
     * 访问小程序日志园所统计
     *
     * @param logManageStatistics 检索条件
     * @return com.xinyilu.common.core.page.TableDataInfo
     **/
    private TableDataInfo getAppLogManageKindergarten(AppLogManageStatisticsDTO logManageStatistics) {
        pageServiceUtil.startPage();
        List<AppLogManageStatisticsVO> appLogManageStatisticsVO = appLogInfoMapper.appletKindergartenCount(logManageStatistics);
        return pageServiceUtil.getDataTable(appLogManageStatisticsVO);
    }

    /**
     * 查看家长所属的孩子、班级、以及幼儿园的信息
     *
     * @param parentInfoId 家长信息id
     * @return 家长信息集合
     */
    @Override
    public AjaxResult getParentAndStudentInfo(Long parentInfoId) {
        List<ParentAndStudentInfo> parentAndStudentInfo = appletMapper.getParentAndStudentInfo(parentInfoId);
        AppletParentAndStudentInfo appletInfo = new AppletParentAndStudentInfo();
        //家长的孩子数量
        long studentCount = parentAndStudentInfo.stream().filter(Objects::nonNull).filter(student -> Objects.nonNull(student.getStudentId())).count();
        appletInfo.setChildrenCount(studentCount);
        //学生信息
        List<AppletStudentInfo> studentInfoList = parentAndStudentInfo.stream().filter(item -> Objects.nonNull(item.getStudentId())).map(item -> {
            AppletStudentInfo appletStudentInfo = new AppletStudentInfo();
            try {
                appletStudentInfo.setStudentId(Objects.isNull(item.getStudentId()) ? 0L : item.getStudentId());
                appletStudentInfo.setStudentName(StringUtils.isBlank(item.getStudentName()) ? "" : item.getStudentName());
                appletStudentInfo.setStudentSex(StringUtils.isBlank(item.getStudentSex()) ? "" : item.getStudentSex());
                appletStudentInfo.setStudentAge(AgeUtil.getStudentAgeMonth(Objects.isNull(item.getBirthDate()) ? LocalDate.now().toString() : item.getBirthDate().toString()));
                appletStudentInfo.setClassId(Objects.isNull(item.getClassId()) ? 0L : item.getClassId());
                appletStudentInfo.setClassName(StringUtils.isBlank(item.getClassName()) ? "" : item.getClassName());
                appletStudentInfo.setClassTeacher(StringUtils.isBlank(item.getClassTeacher()) ? "" : item.getClassTeacher());
                appletStudentInfo.setClassPhone(StringUtils.isBlank(item.getPhone()) ? "" : item.getPhone());
                appletStudentInfo.setKindergartenName(StringUtils.isBlank(item.getKindergartenName()) ? "" : item.getKindergartenName());
                appletStudentInfo.setKindergartenId(Objects.isNull(item.getKindergartenId()) ? 0L : item.getKindergartenId());
            } catch (Exception e) {
                log.warn("计算年龄失败，异常信息:[{}]", e.getMessage());
            }
            return appletStudentInfo;
        }).collect(Collectors.toList());
        appletInfo.setStudentInfoList(studentInfoList);
        //幼儿园信息
        List<AppletClassInfo> classInfoList = parentAndStudentInfo.stream().filter(Objects::nonNull).map(item ->
                {
                    AppletClassInfo appletClassInfo = new AppletClassInfo();
                    appletClassInfo.setKindergartenId(Objects.isNull(item.getKindergartenId()) ? null : item.getKindergartenId());
                    appletClassInfo.setKindergartenName(StringUtils.isBlank(item.getKindergartenName()) ? "" : item.getKindergartenName());
                    appletClassInfo.setKindergartenAddress(StringUtils.isBlank(item.getKindergartenAddress()) ? "" : item.getKindergartenAddress());
                    appletClassInfo.setKindergartenType(StringUtils.isBlank(item.getKindergartenType()) ? "" : item.getKindergartenType());
                    appletClassInfo.setPrincipalId(Objects.isNull(item.getPrincipalId()) ? null : item.getPrincipalId());
                    appletClassInfo.setPrincipalName(StringUtils.isBlank(item.getPrincipalName()) ? null : item.getPrincipalName());
                    appletClassInfo.setKindergartenPhone(StringUtils.isBlank(item.getKindergartenPhone()) ? "" : item.getKindergartenPhone());
                    return appletClassInfo;
                }
        ).collect(Collectors.toList());
        //去除重复
        List<AppletClassInfo> distinctClassInfoList = classInfoList.stream().distinct().collect(Collectors.toList());
        appletInfo.setKindergartenInfoList(distinctClassInfoList);
        return AjaxResult.success(appletInfo);
    }

    /**
     * 区县日志统计
     *
     * @param logManageStatistic 检索条件
     * @return 统计结果
     */
    @Override
    public TableDataInfo selectCountyStatistic(AppLogManageStatisticsDTO logManageStatistic) {
        //所有信息为空
        if (Objects.isNull(logManageStatistic) || (Objects.isNull(logManageStatistic.getAreaId()) && Objects.isNull(logManageStatistic.getStartDate()) && Objects.isNull(logManageStatistic.getEndDate()))) {
            pageServiceUtil.startPage();
            List<AppLogManageStatisticsVO> appLogManageStatistics = appLogKindergartenInfoMapper.selectAppLogKindergartenCounts(null, null, null);
            return pageServiceUtil.getDataTable(appLogManageStatistics);
        }
        //区域信息为空
        if (Objects.isNull(logManageStatistic.getAreaId()) && Objects.nonNull(logManageStatistic.getEndDate()) && Objects.nonNull(logManageStatistic.getStartDate())) {
            pageServiceUtil.startPage();
            List<AppLogManageStatisticsVO> appLogManageStatistics = appLogKindergartenInfoMapper.selectAppLogKindergartenCounts(null, logManageStatistic.getStartDate(), logManageStatistic.getEndDate());
            return pageServiceUtil.getDataTable(appLogManageStatistics);
        }
        SysArea sysArea = sysAreaMapper.selectSysAreaById(logManageStatistic.getAreaId());
        if (Objects.isNull(sysArea) || Objects.isNull(sysArea.getLevel())) {
            return pageServiceUtil.getDataTable(new ArrayList<>());
        }
        if (LEVEL.equals(sysArea.getLevel())) {
            return pageServiceUtil.getDataTable(appLogKindergartenInfoMapper.selectAppLogKindergartenCount(logManageStatistic));
        }
        List<Long> sysAreaIdList = sysAreaMapper.getSysAreaIdList(logManageStatistic.getAreaId());
        if (CollectionUtils.isEmpty(sysAreaIdList)) {
            List<AppLogManageStatisticsVO> list = appLogKindergartenInfoMapper.selectAppLogKindergartenCount(logManageStatistic);
            return pageServiceUtil.getDataTable(list);
        }
        sysAreaIdList.add(logManageStatistic.getAreaId());
        pageServiceUtil.startPage();
        List<AppLogManageStatisticsVO> appLogManageStatistics = appLogKindergartenInfoMapper.selectAppLogKindergartenCounts(sysAreaIdList, logManageStatistic.getStartDate(), logManageStatistic.getEndDate());
        return pageServiceUtil.getDataTable(appLogManageStatistics);
    }

    /**
     * 家长打卡日志统计
     *
     * @param logManageStatistic 检索条件
     * @return 统计结果
     */
    @Override
    public List<AppLogManageStatisticsVO> selectClockStatistics(AppLogManageStatisticsDTO logManageStatistic) {
        return appLogInfoMapper.selectClockStatistic(logManageStatistic);
    }

    /**
     * 家长打卡日历展示
     *
     * @param appLogManageStatistic 家长id
     * @return 统计结果
     */
    @Override
    public AppLogManageStatisticsVO selectCalendarStatistics(AppLogManageStatisticsDTO appLogManageStatistic) {
        LocalDate startDate = appLogManageStatistic.getStartDate().with(TemporalAdjusters.firstDayOfYear());
        LocalDate endDate = appLogManageStatistic.getStartDate().with(TemporalAdjusters.lastDayOfYear());
        appLogManageStatistic.setStartDate(startDate);
        appLogManageStatistic.setEndDate(endDate);
        appLogManageStatistic.setLoginType(LogTypeEnum.LOGIN.getLogType());
        return appLogInfoMapper.selectCalendarStatistics(appLogManageStatistic);
    }
}
