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

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.sptg.common.core.beans.ResultBean;
import com.sptg.common.core.beans.ResultEnum;
import com.sptg.common.core.constant.OperationConstant;
import com.sptg.common.core.util.CommonUtil;
import com.sptg.common.core.util.JsonUtils;
import com.sptg.common.core.util.DateUtil;
import com.sptg.estate.api.dto.GuestAuthorizeDto;
import com.sptg.estate.api.entity.GuestAuthorize;
import com.sptg.estate.biz.mapper.GuestAuthorizeMapper;
import com.sptg.estate.biz.service.GuestAuthorizeServiceInterface;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
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.concurrent.TimeUnit;

/**
 * title: GuestAuthorizeServiceImpl
 * package: com.sptg.estate.biz.security.impl
 * description: 访客授权记录 服务层实现类
 *
 *
 *
 */
@Service
public class GuestAuthorizeServiceImpl extends ServiceImpl<GuestAuthorizeMapper, GuestAuthorize> implements GuestAuthorizeServiceInterface {

    private final RedisTemplate<String,String> redisTemplate;

    //密码访客授权的缓存名字
    private final static String GUEST_AUTHORIZE_FOR_PASSWORD = "sptg:guest:authorize:password:";

    @Autowired
    public GuestAuthorizeServiceImpl(RedisTemplate<String, String> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public Page<GuestAuthorize> showGuestAuthorizeList(GuestAuthorizeDto dto) {
        Wrapper<GuestAuthorize> wrapper = new EntityWrapper<>();
        //排序字段 id降序
        dto.getPage().setOrderByField("l_id");
        dto.getPage().setAsc(false);
        //根据机构
        if(StringUtils.isNotBlank(dto.getOrgPosition())) {
            wrapper.like("s_org_position", dto.getOrgPosition(), SqlLike.RIGHT);
        }
        //根据物业
        if(StringUtils.isNotBlank(dto.getEstatePosition())) {
            wrapper.like("s_estate_position", dto.getEstatePosition(), SqlLike.RIGHT);
        }
        //根据访客类型
        if(null != dto.getGuestType()){
            wrapper.eq("i_guest_type",dto.getGuestType());
        }
        //根据授权状态
        if(null != dto.getEnableType()){
            wrapper.eq("i_enable_type",dto.getEnableType());
        }
        //根据授权密码
        if(null != dto.getPassword()){
            wrapper.eq("i_password",dto.getPassword());
        }
        //根据访客姓名
        if(null != dto.getGuestName()) {
            wrapper.like("s_guest_name", dto.getGuestName());
        }
        //根据业主姓名
        if(null != dto.getUserName()) {
            wrapper.like("s_user_name", dto.getUserName());
        }
        //根据时间日期
        if(null != dto.getSelectBeginDate()) {
            wrapper.ge("t_create_date",dto.getSelectBeginDate());
        }
        if(null != dto.getSelectEndDate()) {
            wrapper.le("t_create_date",dto.getSelectEndDate());
        }
        /*//  根据过期时间查询
        if (null != dto.getSelectEndDate()) {
            wrapper.gt("t_end_date",dto.getSelectEndDate());
        }*/
        //  根据可用状态查询
        if (null != dto.getEnableType()){
            wrapper.eq("i_enable_type",dto.getEnableType());
        }
        //根据小区ID查询
        if(dto.getResidentialId() != null){
            wrapper.eq("l_residential_id",dto.getResidentialId());
        }
        //根据单元ID查询
        if(dto.getUnitId() != null){
            wrapper.eq("l_unit_id",dto.getUnitId());
        }
        //根据单元ID查询
        if(dto.getRoomId() != null){
            wrapper.eq("l_room_id",dto.getRoomId());
        }
        //  排序字段
        if (dto.getSortField() != null && dto.getSortOrder() != null){
            wrapper.orderBy(dto.getSortField(),dto.getSortOrder().equals("asc"));
        }else {
            //  排序字段 时间降序
            wrapper.orderBy("t_create_date",false);
        }
        return this.selectPage(dto.getPage(), wrapper);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<GuestAuthorize> addGuestAuthorize(GuestAuthorize guestAuthorize){
        Boolean result = this.insert(guestAuthorize);
        Integer password;
        if(result){
            boolean cycle = true;
            int cycleCount = 0;
            while(cycle){
                cycleCount++;
                //生成6位数的密码
                password =  CommonUtil.generateNumber(6);
                //构建查询条件--密码要在小区下面唯一
                Wrapper<GuestAuthorize> wrapper = new EntityWrapper<>();
                //密码
                wrapper.eq("i_password", password);
                //小区id
                wrapper.eq("l_residential_id", guestAuthorize.getResidentialId());
                //有效
                wrapper.eq("i_enable_type",OperationConstant.ZERO);
                //过滤已经失效的密码
                wrapper.le("t_end_date",new Date());
                int count = this.selectCount(wrapper);
                //密码重复--继续循环
                if(count>0){
                    cycle = true;
                }else{
                    cycle = false;
                    GuestAuthorize ga = new GuestAuthorize();
                    ga.setId(guestAuthorize.getId());
                    ga.setPassword(password);
                    guestAuthorize.setPassword(password);
                    result = this.updateById(ga);
                }
                //防止死循环
                if(cycleCount>50){
                    cycle = false;
                    result = false;
                }
            }
        }
        //把开门密码写进缓存里
        Long date = guestAuthorize.getEndDate().getTime() - new Date().getTime();
        ValueOperations<String, String> operations = this.redisTemplate.opsForValue();
        String key = GUEST_AUTHORIZE_FOR_PASSWORD + guestAuthorize.getId().toString();
        String json = JsonUtils.objectToJson(guestAuthorize);
        operations.set(key,json,date, TimeUnit.MILLISECONDS);
        return new ResultBean<GuestAuthorize>(ResultEnum.SUCCESS, guestAuthorize);
    }

    @Override
    public GuestAuthorize findGuestAuthorizeById(Long id) {
        Wrapper<GuestAuthorize> wrapper = new EntityWrapper<>();
        wrapper.eq("l_id",id);
//        wrapper.eq("i_enable_type",0);
        return this.selectOne(wrapper);
    }

    @Override
    public ResultBean<Boolean> updateGuestAuthorize(GuestAuthorize guestAuthorize) {
        return new ResultBean<>(ResultEnum.SUCCESS,this.updateById(guestAuthorize));
    }

    @Override
    public ResultBean<Boolean> deleteGuestAuthorize(GuestAuthorizeDto guestAuthorizeDto) {
        return null;
    }

    @Override
    public ResultBean<Boolean> updateGuestAuthorizeEnableType(GuestAuthorize guestAuthorize) {
        Boolean result = this.updateById(guestAuthorize);
        return new ResultBean<>(ResultEnum.SUCCESS,result );
    }

    @Override
    public long getGuestCount(GuestAuthorizeDto guestAuthorizeDto) {
        Wrapper<GuestAuthorize> wrapper = new EntityWrapper<>();
        wrapper.setSqlSelect("count(l_id)");

        //查询某月数据
        if(guestAuthorizeDto.getSelectMonth()!=null){
            SimpleDateFormat sdf=new SimpleDateFormat("yyyyMM");
            wrapper.eq("DATE_FORMAT(t_create_date,'%Y%m')",sdf.format(guestAuthorizeDto.getSelectMonth()));
        }
        //根据机构
        if(StringUtils.isNotBlank(guestAuthorizeDto.getOrgPosition())) {
            wrapper.like("s_org_position", guestAuthorizeDto.getOrgPosition(), SqlLike.RIGHT);
        }
        Long  guestCount =(Long)this.selectObj(wrapper);
        return guestCount==null?0L:guestCount;
    }

    @Override
    public ResultBean<GuestAuthorize> getListByUserId(List<Long> userIds) {
        //获取当前时间的前一个月的当天
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, -1);
        Date date = c.getTime();
        Wrapper<GuestAuthorize> wrapper = new EntityWrapper<>();
        wrapper.orderBy("l_id", false);
        wrapper.eq("i_enable_type",OperationConstant.ZERO);
        //只查询最近一个月内的密码
        wrapper.ge("t_create_date",date);
        //用户id
        wrapper.in("l_user_id", userIds);
        return new ResultBean<>(ResultEnum.SUCCESS,this.selectList(wrapper));
    }

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

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

    @Override
    public GuestAuthorize getByPasswordAndXqId(String password, Long xqId) {
        Wrapper<GuestAuthorize> wrapper = new EntityWrapper<>();
        wrapper.eq("i_password",password);
        wrapper.eq("l_residential_id",xqId);
        wrapper.eq("i_enable_type",0);
        wrapper.gt("t_end_date",new Date());
        return this.selectOne(wrapper);
    }

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

    @Override
    public GuestAuthorize getGuestAuthorizeByCondition(GuestAuthorize guestAuthorize){
        Wrapper<GuestAuthorize> wrapper = new EntityWrapper<>();
        if (null != guestAuthorize.getResidentialId()){
            wrapper.eq("l_residential_id",guestAuthorize.getResidentialId());
        }
        if (null != guestAuthorize.getPassword()){
            wrapper.eq("i_password",guestAuthorize.getPassword());
        }
        wrapper.eq("i_enable_type",OperationConstant.ZERO);
        return this.selectOne(wrapper);
    }

    @Override
    public Page<GuestAuthorize> showEffectiveGuestAuthorizeList(GuestAuthorizeDto dto) {
        Wrapper<GuestAuthorize> wrapper = new EntityWrapper<>();
        //排序字段 id降序
        dto.getPage().setOrderByField("l_id");
        dto.getPage().setAsc(false);
        //根据机构
        if(StringUtils.isNotBlank(dto.getOrgPosition())) {
            wrapper.like("s_org_position", dto.getOrgPosition(), SqlLike.RIGHT);
        }
        //根据物业
        if(StringUtils.isNotBlank(dto.getEstatePosition())) {
            wrapper.like("s_estate_position", dto.getEstatePosition(), SqlLike.RIGHT);
        }
        //根据访客类型
        if(null != dto.getGuestType()){
            wrapper.eq("i_guest_type",dto.getGuestType());
        }
        //根据授权密码
        if(null != dto.getPassword()){
            wrapper.eq("i_password",dto.getPassword());
        }
        //根据访客姓名
        if(null != dto.getGuestName()) {
            wrapper.like("s_guest_name", dto.getGuestName());
        }
        //根据业主姓名
        if(null != dto.getUserName()) {
            wrapper.like("s_user_name", dto.getUserName());
        }
        //根据时间日期
        if(null != dto.getSelectBeginDate()) {
            wrapper.ge("t_create_date",dto.getSelectBeginDate());
        }
        if(null != dto.getSelectEndDate()) {
            wrapper.le("t_create_date",dto.getSelectEndDate());
        }
        /*//  根据过期时间查询
        if (null != dto.getSelectEndDate()) {
            wrapper.gt("t_end_date",dto.getSelectEndDate());
        }*/

        //  根据可用状态查询
        wrapper.eq("i_enable_type", OperationConstant.ZERO);
        //  有效期内
        wrapper.gt("t_end_date", new Date());
        //根据小区ID查询
        if(dto.getResidentialId() != null){
            wrapper.eq("l_residential_id", dto.getResidentialId());
        }
        //根据单元ID查询
        if(dto.getUnitId() != null){
            wrapper.eq("l_unit_id",dto.getUnitId());
        }
        //根据单元ID查询
        if(dto.getRoomId() != null){
            wrapper.eq("l_room_id",dto.getRoomId());
        }
        //  排序字段
        if (dto.getSortField() != null && dto.getSortOrder() != null){
            wrapper.orderBy(dto.getSortField(),dto.getSortOrder().equals("asc"));
        }else {
            //  排序字段 时间降序
            wrapper.orderBy("t_create_date",false);
        }
        return this.selectPage(dto.getPage(), wrapper);
    }

}
