package com.sptg.estate.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.codingapi.txlcn.tc.annotation.LcnTransaction;
import com.sptg.common.core.beans.ResultBean;
import com.sptg.common.core.beans.ResultEnum;
import com.sptg.common.core.constant.OperationConstant;
import com.sptg.estate.api.dto.AccessRecordsDto;
import com.sptg.estate.api.entity.AccessRecords;
import com.sptg.estate.api.entity.MemberAndUser;
import com.sptg.estate.api.feigns.MemberAndUserFeign;
import com.sptg.estate.biz.mapper.AccessRecordsMapper;
import com.sptg.estate.biz.service.AccessRecordsServiceInterface;
import com.sptg.statistics.api.entity.StatisticsCount;
import com.sptg.statistics.api.feigns.StatisticsCountFeign;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * title: AccessRecordsServiceImpl
 * package: com.sptg.estate.biz.security.impl
 * description: 出入记录 服务层实现类
 *
 *
 *
 */
@Service
@RequiredArgsConstructor
public class AccessRecordsServiceImpl extends ServiceImpl<AccessRecordsMapper, AccessRecords> implements AccessRecordsServiceInterface {

    private final StatisticsCountFeign statisticsCountFeign;
    private final MemberAndUserFeign memberAndUserFeign;

    @Override
    public ResultBean<Page<AccessRecords>> showAccessRecordsList(AccessRecordsDto accessRecordsDto) {
        Wrapper<AccessRecords> wrapper = new EntityWrapper<>();
        //根据机构
        if(StringUtils.isNotBlank(accessRecordsDto.getOrgPosition())) {
            wrapper.like("s_org_position", accessRecordsDto.getOrgPosition(), SqlLike.RIGHT);
        }
        //根据物业
        if(StringUtils.isNotBlank(accessRecordsDto.getEstatePosition())) {
            wrapper.like("s_estate_position", accessRecordsDto.getEstatePosition(), SqlLike.RIGHT);
        }
        //根据开门方式
        if(null != accessRecordsDto.getOpenDoorType()) {
            wrapper.eq("i_open_door_type", accessRecordsDto.getOpenDoorType());
        }
        //根据时间日期
        if(null != accessRecordsDto.getBeginDate()) {
            wrapper.ge("t_access_date",accessRecordsDto.getBeginDate());
        }
        if(null != accessRecordsDto.getEndDate()) {
            wrapper.le("t_access_date",accessRecordsDto.getEndDate());
        }
        //根据开门卡号
        if(StringUtils.isNotBlank(accessRecordsDto.getAccessCardNo())){
            wrapper.eq("i_open_door_type",OperationConstant.TWO);
            wrapper.like("s_access_card_no",accessRecordsDto.getAccessCardNo());
        }
        //根据开门住户名字查询
        if(StringUtils.isNotBlank(accessRecordsDto.getOpenUserName())){
            wrapper.like("s_open_user_name",accessRecordsDto.getOpenUserName());
        }
        //根据开门住户手机查询
        if(StringUtils.isNotBlank(accessRecordsDto.getOpenUserTel())){
            wrapper.like("s_open_user_tel",accessRecordsDto.getOpenUserTel());
        }
        //根据设备名称
        if(StringUtils.isNotBlank(accessRecordsDto.getDeviceName())){
            wrapper.like("s_device_name",accessRecordsDto.getDeviceName());
        }
        //根据设备安装位置
        if(StringUtils.isNotBlank(accessRecordsDto.getInstallPath())){
            wrapper.like("s_install_path",accessRecordsDto.getInstallPath());
        }
        //根据小区
        if(accessRecordsDto.getResidentialId()!=null){
            wrapper.eq("l_residential_id",accessRecordsDto.getResidentialId());
        }
        //  排序字段
        if(StringUtils.isNotBlank(accessRecordsDto.getSortField()) && StringUtils.isNotBlank(accessRecordsDto.getSortOrder())){
            wrapper.orderBy(accessRecordsDto.getSortField(),accessRecordsDto.getSortOrder().equals("asc"));
        }else {
            //  排序字段 时间降序
            wrapper.orderBy("t_create_date",false);
        }
        return new ResultBean<>(ResultEnum.SUCCESS,this.selectPage(accessRecordsDto.getPage(), wrapper));
    }

    @Override
    public ResultBean<Page<AccessRecords>> accessRecordsList(AccessRecordsDto accessRecordsDto) {
        AccessRecords accessRecords = new AccessRecords();
        BeanUtil.copyProperties(accessRecordsDto,accessRecords);
        return new ResultBean(ResultEnum.SUCCESS,baseMapper.selectPage(accessRecordsDto.getPage(),new EntityWrapper<>()));
    }

    @Override
    public AccessRecords findAccessRecordsById(Long id) {
        return this.selectById(id);
    }

    @Override
    public ResultBean<Boolean> updateAccessRecords(AccessRecordsDto accessRecordsDto) {
        return null;
    }

    @Override
    public ResultBean<Boolean> deleteAccessRecords(AccessRecordsDto accessRecordsDto) {
        return null;
    }

    @Override
    public List<Map<String, Object>> accessCountListForGroupType(AccessRecordsDto accessRecordsDto){
        List<Map<String,Object>> statisticsAdWatchMap=null;
        EntityWrapper<AccessRecords> wrapper=new EntityWrapper<AccessRecords>();
        String sqlSelect="COUNT(l_id)AS accessCount,DATE_FORMAT(t_access_date,'%H') AS hour";
        //分组类型 0 按时(默认)  1按日 2按周  3按月
        Integer groupType = accessRecordsDto.getGroupType();
        if(groupType!=null){
            if(groupType==OperationConstant.ONE){
                sqlSelect="COUNT(l_id)AS accessCount,DATE_FORMAT(t_access_date,'%d') AS day";
            }else if(groupType==OperationConstant.TWO){
                sqlSelect="COUNT(l_id)AS accessCount,DATE_FORMAT(t_access_date,'%w') AS weekday";
            }else if(groupType==OperationConstant.THREE){
                sqlSelect="COUNT(l_id)AS accessCount,DATE_FORMAT(t_access_date,'%c') AS month";
            }
        }
        wrapper.setSqlSelect(sqlSelect);
        //按时间查
        Date selectDate = accessRecordsDto.getSelectDate();
        if(selectDate==null) {
            return null;
        }
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
        String selectDateFormat=simpleDateFormat.format(selectDate);
        if(groupType!=null){
            if(groupType==OperationConstant.ONE){
                //按月查询
                selectDateFormat=selectDateFormat.substring(0,selectDateFormat.lastIndexOf("-"));
                wrapper.eq("DATE_FORMAT(t_access_date,'%Y-%m')",selectDateFormat );
                //按日分组
                wrapper.groupBy("day");
            }else if(groupType==OperationConstant.TWO){
                //按周查询
                wrapper.where("YEARWEEK(DATE_FORMAT(t_access_date,'%Y-%m-%d'),1) = YEARWEEK('"+selectDateFormat+"',1)");
                //按周分组
                wrapper.groupBy("weekDay");
            }else if(groupType==OperationConstant.THREE){
                //按年查询
                selectDateFormat=selectDateFormat.substring(0,selectDateFormat.indexOf("-"));
                wrapper.eq("DATE_FORMAT(t_access_date,'%Y')", selectDateFormat);
                //按月分组
                wrapper.groupBy("month");
            }else{
                //按日查询
                wrapper.eq("DATE_FORMAT(t_access_date,'%Y-%m-%d')", selectDateFormat);
                //按小时分组
                wrapper.groupBy("hour");
            }
        }else{
            //按日查询
            wrapper.eq("DATE_FORMAT(t_access_date,'%Y-%m-%d')", selectDateFormat);
            //按小时分组
            wrapper.groupBy("hour");
        }

        //机构位置
        String orgPosition=accessRecordsDto.getOrgPosition();
        //根据机构
        if(StringUtils.isNotBlank(orgPosition)) {
            wrapper.like("s_org_position", orgPosition, SqlLike.RIGHT);
        }
        statisticsAdWatchMap=this.selectMaps(wrapper);
        return statisticsAdWatchMap;
    }

    @Override
    public Map<String, Object> accessCountForOpenWay(AccessRecordsDto accessRecordsDto){
        EntityWrapper<AccessRecords> wrapper=new EntityWrapper<AccessRecords>();
        //人脸,密码,刷卡的开门次数
        String sqlSelect="sum(case  when i_open_door_type=0 then 1 ELSE 0 end) faceOpenCount," +
                "sum(case  when i_open_door_type=1 then 1 ELSE 0 end) passWordOpenCount," +
                "sum(case  when i_open_door_type=2 then 1 ELSE 0 end) cardOpenCount,"+
                "sum(case  when i_open_door_type=3 then 1 ELSE 0 end) telnetOpenCount";
        wrapper.setSqlSelect(sqlSelect);

        //查询时间
        Date selectDate = accessRecordsDto.getSelectDate();
        //查询时间类型
        Integer selectDateType = accessRecordsDto.getSelectDateType();
        if(selectDateType!=null&&selectDate!=null){
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
            String selectDateStr = sdf.format(selectDate);
            //按日查询
            if(OperationConstant.ZERO == accessRecordsDto.getSelectDateType()){
                wrapper.eq("DATE_FORMAT(t_access_date,'%Y-%m-%d')",selectDateStr);
            }else if(OperationConstant.ONE ==  accessRecordsDto.getSelectDateType()){
                //按周查询
                wrapper.where("YEARWEEK(date_format(t_access_date,'%Y-%m-%d'),1) = YEARWEEK('"+selectDateStr+"',1)");
            }else if(OperationConstant.TWO ==  accessRecordsDto.getSelectDateType()){
                //按月查询
                selectDateStr=selectDateStr.substring(0,selectDateStr.lastIndexOf("-"));
                wrapper.eq("DATE_FORMAT(t_access_date,'%Y-%m')",selectDateStr);
            }else if(OperationConstant.THREE ==  accessRecordsDto.getSelectDateType()){
                //按年查询
                selectDateStr=selectDateStr.substring(0,selectDateStr.indexOf("-"));
                wrapper.eq("DATE_FORMAT(t_access_date,'%Y')",selectDateStr);
            }
        }
        //机构位置
        String orgPosition=accessRecordsDto.getOrgPosition();
        //根据机构
        if(StringUtils.isNotBlank(orgPosition)) {
            wrapper.like("s_org_position", orgPosition, SqlLike.RIGHT);
        }
        return this.selectMap(wrapper);
    }

    @Override
    public Long getAccessRecordsCount(AccessRecordsDto accessRecordsDto){
        EntityWrapper<AccessRecords> wrapper=new EntityWrapper<AccessRecords>();
        wrapper.setSqlSelect("COUNT(l_id)");

        //查询某月数据
        if(accessRecordsDto.getSelectMonth()!=null){
            SimpleDateFormat sdf=new SimpleDateFormat("yyyyMM");
            wrapper.eq("DATE_FORMAT(t_create_date,'%Y%m')",sdf.format(accessRecordsDto.getSelectMonth()));
        }

        //机构位置
        String orgPosition=accessRecordsDto.getOrgPosition();
        //根据机构
        if(StringUtils.isNotBlank(orgPosition)) {
            wrapper.like("s_org_position", orgPosition, SqlLike.RIGHT);
        }
        return (Long) this.selectObj(wrapper);
    }

    @Override
    public ResultBean<AccessRecords> getListByUserId(List<Long> userIds) {
        Wrapper<AccessRecords> wrapper = new EntityWrapper<>();
        wrapper.orderBy("l_id", false);
        // userid
        wrapper.in("l_open_user_id", userIds);
        //开门类型 0- 人脸 1-密码 2-刷卡
        wrapper.eq("i_open_door_type", OperationConstant.ONE);
        //只查询最近一个月内的密码
        //获取当前时间的前一个月的当天
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, -1);
        Date date = c.getTime();
        wrapper.ge("t_create_date",date);
        return new ResultBean<>(ResultEnum.SUCCESS,this.selectList(wrapper));
    }

    @Override
    public int getAccessRecordsCountByDay(AccessRecordsDto accessRecordsDto) {
        EntityWrapper<AccessRecords> wrapper=new EntityWrapper<>();
        wrapper.where("DATE_FORMAT(t_create_date,'%Y%m%d')=DATE_FORMAT(NOW(),'%Y%m%d')");
        //小区
        wrapper.eq("l_residential_id",  accessRecordsDto.getResidentialId());
        return this.selectCount(wrapper);
    }

    @Override
    public Page<Map<String, Object>> getDeviceOpenCountList(AccessRecordsDto accessRecordsDto){
        String sqlSelect="s_device_name AS deviceName,s_install_path AS installPath,count(1) AS openCount";
        EntityWrapper<AccessRecords> wrapper=new EntityWrapper<AccessRecords>();
        wrapper.setSqlSelect(sqlSelect);
        //查询时间
        Date selectDate = accessRecordsDto.getSelectDate();
        Page<AccessRecords> page = accessRecordsDto.getPage();
        //查询时间类型
        Integer selectDateType = accessRecordsDto.getSelectDateType();
        if(selectDateType!=null&&selectDate!=null){
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
            String selectDateStr = sdf.format(selectDate);
            //按日查询
            if(OperationConstant.ZERO == accessRecordsDto.getSelectDateType()){
                wrapper.eq("DATE_FORMAT(t_access_date,'%Y-%m-%d')",selectDateStr);
            }else if(OperationConstant.ONE ==  accessRecordsDto.getSelectDateType()){
                //按周查询
                wrapper.where("YEARWEEK(date_format(t_access_date,'%Y-%m-%d'),1) = YEARWEEK('"+selectDateStr+"',1)");
            }else if(OperationConstant.THREE ==  accessRecordsDto.getSelectDateType()){
                //按年查询
                selectDateStr=selectDateStr.substring(0,selectDateStr.indexOf("-"));
                wrapper.eq("DATE_FORMAT(t_access_date,'%Y')",selectDateStr);
            }else if(OperationConstant.TWO ==  accessRecordsDto.getSelectDateType()){
                //按月查询
                selectDateStr=selectDateStr.substring(0,selectDateStr.lastIndexOf("-"));
                wrapper.eq("DATE_FORMAT(t_access_date,'%Y-%m')",selectDateStr);
            }
        }
        //机构位置
        String orgPosition=accessRecordsDto.getOrgPosition();
        //根据机构
        if(StringUtils.isNotBlank(orgPosition)) {
            wrapper.like("s_org_position", orgPosition, SqlLike.RIGHT);
        }
        //按设备分组
        wrapper.groupBy("l_device_id");
        wrapper.orderBy("openCount",false);
        return this.selectMapsPage(page,wrapper);
    }

    @LcnTransaction
    @Transactional(rollbackFor=Exception.class)
    @Override
    public boolean insert(AccessRecords accessRecords){
        boolean result = super.insert(accessRecords);
        if(result){
            //分布式事务
            StatisticsCount statisticsCount=new StatisticsCount();
            Integer openDoorType=accessRecords.getOpenDoorType();
            statisticsCount.setAccessRecordCount(OperationConstant.ONE);
            //0- 人脸 1-密码 2-刷卡 3-远程
            if(openDoorType==0){
                statisticsCount.setAccessRecordFaceCount(OperationConstant.ONE);
            }else if(openDoorType==1){
                statisticsCount.setAccessRecordPasswordCount(OperationConstant.ONE);
            }else if(openDoorType==2){
                statisticsCount.setAccessRecordCardCount(OperationConstant.ONE);
            }else if(openDoorType==3){
                statisticsCount.setAccessRecordTelnetCount(OperationConstant.ONE);
            }
            statisticsCount.setOrgPosition(accessRecords.getOrgPosition());
            statisticsCount.setRootOrgId(accessRecords.getRootOrgId());
            ResultBean<Boolean> resultBean = statisticsCountFeign.addCountLcn(statisticsCount);
            //当统计组件没启动时，需要处理
            if(!ResultEnum.SUCCESS.getCode().equals(resultBean.getCode())){
                throw new RuntimeException("服务调用失败");
            }
        }
        return result;
    }

    @Override
    public ResultBean<Page<AccessRecords>> getAccessRecordsList(AccessRecordsDto accessRecordsDto) {
        Wrapper<AccessRecords> wrapper = new EntityWrapper<>();
        if (null != accessRecordsDto.getOpenDoorType()){
            wrapper.eq("i_open_door_type",accessRecordsDto.getOpenDoorType());
        }
        if (StringUtils.isNotEmpty(accessRecordsDto.getAccessCardNo())){
            wrapper.eq("s_access_card_no",accessRecordsDto.getAccessCardNo());
        }
        if (null != accessRecordsDto.getResidentialId()){
            wrapper.eq("l_residential_id",accessRecordsDto.getResidentialId());
        }
        if(null != accessRecordsDto.getBeginDate()) {
            wrapper.ge("t_access_date",accessRecordsDto.getBeginDate());
        }
        if(null != accessRecordsDto.getEndDate()) {
            wrapper.le("t_access_date",accessRecordsDto.getEndDate());
        }
        return new ResultBean<>(ResultEnum.SUCCESS,this.selectPage(accessRecordsDto.getPage(), wrapper));
    }

    @Override
    public AccessRecords findByOldId(String oldId) {
        Wrapper<AccessRecords> wrapper = new EntityWrapper<>();
        wrapper.eq("l_old_id",oldId);
        return this.selectOne(wrapper);
    }

    @Override
    public int addAccessRecordsSync(AccessRecords accessRecords) {
        if(this.baseMapper.insert(accessRecords)>0){
            return 1;
        }
        return 0;
    }

    @Override
    public int updateAccessRecordsSync(AccessRecords accessRecords) {
        if(this.updateById(accessRecords)){
            return 1;
        }
        return 0;
    }

    @Override
    public ResultBean<Page<AccessRecords>> getListByMemberId(AccessRecordsDto accessRecordsDto) {
        MemberAndUser memberAndUser = new MemberAndUser();
        memberAndUser.setMemberId(accessRecordsDto.getMemberId());
        List<Long> userList = memberAndUserFeign.getByCondition(memberAndUser)
                .stream().map(MemberAndUser::getUserId).collect(Collectors.toList());
        if(userList.size()==0){
            return new ResultBean<>(ResultEnum.SUCCESS,accessRecordsDto.getPage());
        }
        Page<AccessRecords> accessRecordsPage = this.selectPage(accessRecordsDto.getPage(), new EntityWrapper<AccessRecords>(accessRecordsDto).in("l_open_user_id",userList));
        return new ResultBean<>(ResultEnum.SUCCESS,accessRecordsPage);
    }

    @Override
    public List<AccessRecords> getListByCondition(AccessRecordsDto accessRecordsDto) {
        Wrapper<AccessRecords> wrapper = new EntityWrapper<>();
        //根据机构
        if(StringUtils.isNotBlank(accessRecordsDto.getOrgPosition())) {
            wrapper.like("s_org_position", accessRecordsDto.getOrgPosition(), SqlLike.RIGHT);
        }
        //根据物业
        if(StringUtils.isNotBlank(accessRecordsDto.getEstatePosition())) {
            wrapper.like("s_estate_position", accessRecordsDto.getEstatePosition(), SqlLike.RIGHT);
        }
        //根据开门方式
        if(null != accessRecordsDto.getOpenDoorType()) {
            wrapper.eq("i_open_door_type", accessRecordsDto.getOpenDoorType());
        }
        //根据时间日期
        if(null != accessRecordsDto.getBeginDate()) {
            wrapper.ge("t_access_date",accessRecordsDto.getBeginDate());
        }
        if(null != accessRecordsDto.getEndDate()) {
            wrapper.le("t_access_date",accessRecordsDto.getEndDate());
        }
        //根据开门卡号
        if(StringUtils.isNotBlank(accessRecordsDto.getAccessCardNo())){
            wrapper.eq("i_open_door_type",OperationConstant.TWO);
            wrapper.like("s_access_card_no",accessRecordsDto.getAccessCardNo());
        }
        //根据开门住户名字查询
        if(StringUtils.isNotBlank(accessRecordsDto.getOpenUserName())){
            wrapper.like("s_open_user_name",accessRecordsDto.getOpenUserName());
        }
        //根据开门住户手机查询
        if(StringUtils.isNotBlank(accessRecordsDto.getOpenUserTel())){
            wrapper.like("s_open_user_tel",accessRecordsDto.getOpenUserTel());
        }
        //根据设备名称
        if(StringUtils.isNotBlank(accessRecordsDto.getDeviceName())){
            wrapper.like("s_device_name",accessRecordsDto.getDeviceName());
        }
        //根据设备安装位置
        if(StringUtils.isNotBlank(accessRecordsDto.getInstallPath())){
            wrapper.like("s_install_path",accessRecordsDto.getInstallPath());
        }
        //根据小区
        if(accessRecordsDto.getResidentialId()!=null){
            wrapper.eq("l_residential_id",accessRecordsDto.getResidentialId());
        }
        return this.selectList(wrapper);
    }
}