package com.usky.fire.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.usky.agbox.RemotePatrolAgBoxService;
import com.usky.common.core.exception.BusinessException;
import com.usky.common.core.util.StringUtils;
import com.usky.common.security.utils.SecurityUtils;
import com.usky.fire.domain.PatrolInspectionAttendance;
import com.usky.fire.domain.PatrolInspectionPersonnel;
import com.usky.fire.mapper.PatrolInspectionAttendanceMapper;
import com.usky.fire.mapper.PatrolInspectionPersonnelMapper;
import com.usky.fire.service.PatrolInspectionAttendanceService;
import com.usky.common.mybatis.core.AbstractCrudService;
import com.usky.fire.service.PatrolInspectionPersonnelService;
import com.usky.fire.service.PatrolInspectionTypeService;

import com.usky.fire.service.config.mqtt.MqttOutConfig;
import com.usky.fire.service.config.rabbitmq.RabbitMQConfig;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.usky.system.RemoteDeptService;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;


/**
 * <p>
 * 签到、签退信息记录表 服务实现类
 * </p>
 *
 * @author fu
 * @since 2024-02-05
 */
@Service
public class PatrolInspectionAttendanceServiceImpl extends AbstractCrudService<PatrolInspectionAttendanceMapper, PatrolInspectionAttendance> implements PatrolInspectionAttendanceService {
    @Autowired
    private PatrolInspectionTypeService patrolInspectionTypeService;

    @Autowired
    private RemoteDeptService remoteDeptService;

    @Autowired
    private PatrolInspectionPersonnelService patrolInspectionPersonnelService;

    @Autowired
    private PatrolInspectionPersonnelMapper patrolInspectionPersonnelMapper;

    @Autowired
    private RemotePatrolAgBoxService remotePatrolAgboxService;

    @Value("${agBox.push}")
    private Integer pushFlag;

//    @Resource
//    private RabbitTemplate rabbitTemplate;
//
//    @Autowired
//    private RabbitMQConfig rabbitMQConfig;

    @Resource
    private MqttOutConfig.MqttGateway mqttGateway;

    @Override
    public IPage<Map<String, Object>> pageList(Integer pageNum, Integer pageSize, String operateCode, String operator, LocalDateTime startTime, LocalDateTime endTime) {
        IPage<PatrolInspectionAttendance> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<PatrolInspectionAttendance> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PatrolInspectionAttendance::getTenantId, SecurityUtils.getTenantId());

        if (StringUtils.isNotBlank(operateCode)) {
            queryWrapper.eq(PatrolInspectionAttendance::getOperateCode, operateCode);
        }

        if (StringUtils.isNotBlank(operator)) {
            queryWrapper.eq(PatrolInspectionAttendance::getOperator, operator);
        }

        if (startTime != null) {
            queryWrapper.between(endTime != null, PatrolInspectionAttendance::getOperateDate, startTime, endTime);
        } else {
            queryWrapper.le(endTime != null, PatrolInspectionAttendance::getOperateDate, endTime);
        }

        queryWrapper.orderByDesc(PatrolInspectionAttendance::getId);

        IPage<PatrolInspectionAttendance> attendancePage = baseMapper.selectPage(page, queryWrapper);

        List<Map<String, Object>> resultList = new ArrayList<>();

        List<Long> userIdList = new ArrayList<>();

        for (PatrolInspectionAttendance attendance : attendancePage.getRecords()) {
            userIdList.add(attendance.getOperatorId());
        }
        LambdaQueryWrapper<PatrolInspectionPersonnel> queryWrapper1 = Wrappers.lambdaQuery();
        queryWrapper1.in(!userIdList.isEmpty(),PatrolInspectionPersonnel::getUserId,userIdList);
        List<PatrolInspectionPersonnel> personnelList = patrolInspectionPersonnelService.list(queryWrapper1);
        for (PatrolInspectionAttendance attendance : attendancePage.getRecords()) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", attendance.getId());
            Long deptId = attendance.getDeptId();
            String deptName = deptId != null ? getDeptName(Math.toIntExact(deptId)) : "";
            map.put("deptName", deptName);
            map.put("tenantId", attendance.getTenantId());
            map.put("operator", attendance.getOperator());
            map.put("operatorId", attendance.getOperatorId());
            map.put("operateDate", attendance.getOperateDate());
            map.put("signInType", attendance.getSignInType());
            map.put("operateName", patrolInspectionTypeService.getName(attendance.getOperateCode()));
            map.put("deviceCode", attendance.getDeviceCode());
            map.put("imagePath", attendance.getImagePath());
            map.put("longitude", attendance.getLongitude());
            map.put("latitude", attendance.getLatitude());
            map.put("remarks", attendance.getRemarks());
            map.put("identificationNumber", attendance.getIdentificationNumber());
            Integer attendanceIn = attendance.getOperatorId().intValue();
            if (CollectionUtils.isNotEmpty(personnelList)){
                for (PatrolInspectionPersonnel personnel : personnelList) {
                    if (attendanceIn.equals(personnel.getUserId())){
                        map.put("dispatchCompany", personnel.getDispatchCompany());
                        map.put("securityCompany", personnel.getSecurityCompany());
                    }
                }
            }
            resultList.add(map);
        }
        IPage<Map<String, Object>> resultPage = new Page<>();
        resultPage.setRecords(resultList);
        resultPage.setTotal(attendancePage.getTotal());
        resultPage.setCurrent(attendancePage.getCurrent());
        resultPage.setSize(attendancePage.getSize());
        return resultPage;
    }

    @Override
    public void add(PatrolInspectionAttendance patrolInspectionAttendance) {
        LambdaQueryWrapper<PatrolInspectionPersonnel> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(PatrolInspectionPersonnel::getUserId, SecurityUtils.getUserId());
        List<PatrolInspectionPersonnel> personnelList = patrolInspectionPersonnelMapper.selectList(wrapper);
        if (personnelList.isEmpty()) {
            throw new BusinessException("您不是巡检人员，不可进行此操作");
        }
        patrolInspectionAttendance.setTenantId(SecurityUtils.getTenantId());
        patrolInspectionAttendance.setOperator(SecurityUtils.getUsername());
        patrolInspectionAttendance.setOperatorId(SecurityUtils.getUserId());
        patrolInspectionAttendance.setDeptId(SecurityUtils.getLoginUser().getSysUser().getDeptId());
        patrolInspectionAttendance.setOperateDate(LocalDateTime.now());
        patrolInspectionAttendance.setRemarks(patrolInspectionAttendance.getRemarks());
        patrolInspectionAttendance.setSignInType(patrolInspectionAttendance.getSignInType());
        patrolInspectionAttendance.setOperateCode(patrolInspectionAttendance.getOperateCode());
        patrolInspectionAttendance.setImagePath(patrolInspectionAttendance.getImagePath());
        patrolInspectionAttendance.setLatitude(patrolInspectionAttendance.getLatitude());
        patrolInspectionAttendance.setLongitude(patrolInspectionAttendance.getLongitude());
        patrolInspectionAttendance.setIdentificationNumber(SecurityUtils.getLoginUser().getSysUser().getPhonenumber());
        patrolInspectionAttendance.setDeviceCode(patrolInspectionAttendance.getDeviceCode());
        baseMapper.insert(patrolInspectionAttendance);
        patrolInspectionPersonnelService.updateSignStatus(patrolInspectionAttendance.getSignInType());
        JSONObject jsonObj = new JSONObject();
        jsonObj.put("deviceId", patrolInspectionAttendance.getDeviceCode());
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formattedTime = now.format(formatter);
        jsonObj.put("triggerTime", formattedTime);
        Integer eventCode = 17;
        if (patrolInspectionAttendance.getSignInType().equals(0)) {
            eventCode = 31;
        } else {
            eventCode = 32;
        }
        jsonObj.put("eventType", eventCode);
        jsonObj.put("name", SecurityUtils.getUsername());
        jsonObj.put("certifiedNo", patrolInspectionAttendance.getIdentificationNumber());

//        rabbitTemplate.convertAndSend(rabbitMQConfig.patrolEventExchange, SecurityUtils.getTenantId().toString(), jsonObj.toJSONString());
        mqttGateway.sendToMqtt("/patrolEEvent/"+SecurityUtils.getTenantId()+"/event", jsonObj.toJSONString());

//        if (pushFlag.equals(1)){
//            JSONObject a = remotePatrolAgboxService.addEvent(jsonObj.toJSONString());
//        }
    }

    /**
     * 获取部门名
     *
     * @param id
     * @return
     */
    @Override
    public String getDeptName(Integer id) {
        String name = "";
        List<Map<String, Object>> deptList = remoteDeptService.getDeptList(SecurityUtils.getTenantId());
        for (int i = 0; i < deptList.size(); i++) {
            if (id.equals(deptList.get(i).get("dept_id"))) {
                name = deptList.get(i).get("dept_name").toString();
            }
        }
        return name;
    }

    public Map<String, Integer> securityStatistics() {
        Map<String, Integer> countMap = new HashMap<>();
        int countOut, countIn;
        countOut = baseMapper.signOut(SecurityUtils.getTenantId());
        countIn = baseMapper.signIn(SecurityUtils.getTenantId());
        if (countOut != 0 && countIn == 0) {
            countMap.put("signIn", 0);
            countMap.put("signOut", countOut);
        } else if (countOut == 0 && countIn != 0) {
            countMap.put("signIn", countIn);
            countMap.put("signOut", 0);
        } else if (countOut == 0 && countIn == 0) {
            countMap.put("signIn", 0);
            countMap.put("signOut", 0);
        }else {
            countMap.put("signIn", countIn);
            countMap.put("signOut", countOut);
        }
        return countMap;
    }

}

