package com.usky.iot.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
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.bean.CommonPage;
import com.usky.common.security.utils.SecurityUtils;
import com.usky.iot.domain.BaseAppInfo;
import com.usky.iot.domain.BaseGgpFacility;
import com.usky.iot.mapper.BaseAppInfoMapper;
import com.usky.iot.service.BaseAppInfoService;
import com.usky.common.mybatis.core.AbstractCrudService;
import com.usky.iot.service.config.mqtt.MqttOutConfig;
import com.usky.iot.service.config.rabbitmq.RabbitMQConfig;
import com.usky.iot.service.vo.AppInfoRequest;
import com.usky.iot.service.vo.BaseGgpFacilityRequest;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
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 org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * APP用户心跳信息 服务实现类
 * </p>
 *
 * @author han
 * @since 2024-03-29
 */
@Service
public class BaseAppInfoServiceImpl extends AbstractCrudService<BaseAppInfoMapper, BaseAppInfo> implements BaseAppInfoService {

    @Autowired
    private RemotePatrolAgBoxService remotePatrolAgboxService;

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

//    @Resource
//    private RabbitTemplate rabbitTemplate;
//
//    @Autowired
//    private RabbitMQConfig rabbitMQConfig;
    @Resource
    private MqttOutConfig.MqttGateway mqttGateway;

    public String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    public static HttpServletRequest getHttpServletRequest() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if(requestAttributes == null){
            return null;
        }

        return ((ServletRequestAttributes) requestAttributes).getRequest();
    }

    @Override
    public void add(BaseAppInfo baseAppInfo){
//        JSONObject jsonObj = new JSONObject();
//        jsonObj.put("deviceId", baseAppInfo.getDeviceId());
//        baseAppInfo.setNetworkService(a.toJSONString());
        HttpServletRequest request = getHttpServletRequest();
        String accessIp = getIpAddress(request);
        baseAppInfo.setAccessIp(accessIp);
        baseAppInfo.setCreateBy(SecurityUtils.getUsername());
        baseAppInfo.setCreateTime(LocalDateTime.now());
        baseAppInfo.setTenantId(SecurityUtils.getTenantId());

        Map<String,Object> map = new HashMap<>();
        map.put("deviceId",baseAppInfo.getDeviceId());
        map.put("userName",baseAppInfo.getUserName());
        map.put("createTime",baseAppInfo.getCreateTime());
//        rabbitTemplate.convertAndSend(rabbitMQConfig.patrolEInfoExchange,SecurityUtils.getTenantId().toString(),JSONObject.toJSONString(map));
        mqttGateway.sendToMqtt("/patrolEInfo/"+SecurityUtils.getTenantId()+"/info",JSONObject.toJSONString(map));

        this.save(baseAppInfo);
//        if (pushFlag.equals(1)){
//            JSONObject a = remotePatrolAgboxService.updateHeart(jsonObj.toJSONString());
//        }
    }

    @Override
    public CommonPage<BaseAppInfo> page(AppInfoRequest appInfoRequest) {
        IPage<BaseAppInfo> page = new Page<>(appInfoRequest.getCurrent(), appInfoRequest.getSize());
        QueryWrapper<BaseAppInfo> queryWrapper = Wrappers.query();
        queryWrapper.eq(StringUtils.isNotBlank(appInfoRequest.getDeviceId()),"device_id",appInfoRequest.getDeviceId())
                .eq("tenant_id",SecurityUtils.getTenantId())
                .inSql("id","SELECT MAX(id) AS id FROM base_app_info GROUP BY device_id")
                .orderByDesc("id");
        page = this.page(page,queryWrapper);
        if (page.getRecords().size()>0){
            for (int i = 0; i < page.getRecords().size(); i++) {
                if (page.getRecords().get(i).getCheckStatus().equals(1)){
                    LocalDateTime endTime = LocalDateTime.now();
                    long seconds = ChronoUnit.SECONDS.between(page.getRecords().get(i).getUpdateTime(), endTime);
                    if (seconds>10){
                        page.getRecords().get(i).setDeviceStatus(1);
                    }
                }
            }
        }
        return new CommonPage<>(page.getRecords(),page.getTotal(),page.getCurrent(),page.getSize());
    }

    @Override
    public void selfCheck(String baseAppInfo){
        JSONObject eventVO = JSONObject.parseObject(baseAppInfo);
        BaseAppInfo baseAppInfo1 = new BaseAppInfo();
        Integer id = Integer.valueOf(eventVO.get("id").toString());
        baseAppInfo1.setId(id);
        baseAppInfo1.setCheckStatus(1);
        baseAppInfo1.setUpdateBy(SecurityUtils.getUsername());
        baseAppInfo1.setUpdateTime(LocalDateTime.now());
        this.updateById(baseAppInfo1);
    }
}
