package com.aiotagro.cattletrade.business.service.impl;

import com.aiotagro.cattletrade.business.entity.DeliveryDevice;
import com.aiotagro.cattletrade.business.entity.XqClient;
import com.aiotagro.cattletrade.business.mapper.DeliveryDeviceMapper;
import com.aiotagro.cattletrade.business.mapper.XqClientMapper;
import com.aiotagro.cattletrade.business.service.IXqClientService;
import com.aiotagro.common.core.web.domain.AjaxResult;
import com.aiotagro.common.core.web.domain.PageResultResponse;
import com.aiotagro.common.core.utils.LngLonUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import com.aiotagro.common.core.utils.StringUtils;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 项圈客户端服务实现
 *
 * @author System
 * @date 2025-01-16
 */
@Service
public class XqClientServiceImpl extends ServiceImpl<XqClientMapper, XqClient> implements IXqClientService {

    @Resource
    private XqClientMapper xqClientMapper;
    
    @Resource
    private DeliveryDeviceMapper deliveryDeviceMapper;

    @Override
    public PageResultResponse xqList(Map<String, Object> params) {
        Integer pageNum = params.get("pageNum") != null ? (Integer) params.get("pageNum") : 1;
        Integer pageSize = params.get("pageSize") != null ? (Integer) params.get("pageSize") : 10;
        String sn = (String) params.get("sn");
        String startNo = (String) params.get("startNo");
        String endNo = (String) params.get("endNo");
        Boolean unassignedOnly = (Boolean) params.get("unassignedOnly");

        Page<Map<String, Object>> result = PageHelper.startPage(pageNum, pageSize);
        
        try {
            List<Map<String, Object>> list;
            if (unassignedOnly != null && unassignedOnly) {
                // 查询未分配的智能项圈
                list = xqClientMapper.selectUnassignedXqClientList(sn, startNo, endNo);
            } else {
                // 使用关联查询获取完整信息
                list = xqClientMapper.selectXqClientListWithRelations(sn, startNo, endNo);
            }
            
            return new PageResultResponse(result.getTotal(), list);
        } catch (Exception e) {
            e.printStackTrace();
            return new PageResultResponse(0L, new ArrayList<>());
        }
    }

    @Override
    public AjaxResult getDevicesByDeliveryId(Integer deliveryId, Integer deviceType) {
        
        if (deliveryId == null) {
            return AjaxResult.error("运送清单ID不能为空");
        }
        
        // 查询运送清单关联的设备
        LambdaQueryWrapper<DeliveryDevice> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DeliveryDevice::getDeliveryId, deliveryId);
        wrapper.eq(DeliveryDevice::getDeviceType, deviceType);
        List<DeliveryDevice> deliveryDevices = deliveryDeviceMapper.selectList(wrapper);
        
        if (!deliveryDevices.isEmpty()) {
        }
        
        if (deliveryDevices.isEmpty()) {
            return AjaxResult.success(new ArrayList<>());
        }
        
        // 获取设备ID列表
        List<String> deviceIds = deliveryDevices.stream()
                .map(DeliveryDevice::getDeviceId)
                .collect(Collectors.toList());
        
        // 查询设备详细信息
        LambdaQueryWrapper<XqClient> deviceWrapper = new LambdaQueryWrapper<>();
        if (deviceType != null && deviceType == 3) {
            // 项圈：历史上有的存 deviceId，有的存 sn，需要兼容两种字段
            deviceWrapper.and(w -> w.in(XqClient::getDeviceId, deviceIds)
                                    .or()
                                    .in(XqClient::getSn, deviceIds));
        } else {
            // 耳标：部分库没有扩展字段（delivery_number、license_plate），避免 select * 触发未知列错误
            deviceWrapper.in(XqClient::getDeviceId, deviceIds)
                         .select(XqClient::getId,
                                 XqClient::getDeviceId,
                                 XqClient::getSn,
                                 XqClient::getState,
                                 XqClient::getLongitude,
                                 XqClient::getLatitude,
                                 XqClient::getAltitude,
                                 XqClient::getGpsState,
                                 XqClient::getNsat,
                                 XqClient::getRsrp,
                                 XqClient::getBattery,
                                 XqClient::getTemperature,
                                 XqClient::getSteps,
                                 XqClient::getAccX,
                                 XqClient::getAccY,
                                 XqClient::getAccZ,
                                 XqClient::getBandgeStatus,
                                 XqClient::getVer,
                                 XqClient::getTime,
                                 XqClient::getUptime,
                                 XqClient::getYSteps,
                                 XqClient::getIsWear,
                                 XqClient::getIsTemperature,
                                 XqClient::getSourceId,
                                 XqClient::getLoctime,
                                 XqClient::getSubType,
                                 XqClient::getFrequency,
                                 XqClient::getVehicleId,
                                 XqClient::getEveningFrequency,
                                 XqClient::getTenantId,
                                 XqClient::getDeliveryId,
                                 XqClient::getDeliveryNumber,
                                 XqClient::getLicensePlate);
        }
        List<XqClient> devices = xqClientMapper.selectList(deviceWrapper);
        
        for (XqClient device : devices) {
        }
        
        // 返回分页格式数据
        Map<String, Object> result = new HashMap<>();
        result.put("rows", devices);
        result.put("total", devices.size());
        
        return AjaxResult.success(result);
    }
    
    @Override
    public AjaxResult getCollarLocation(String deliveryId, String xqDeviceId) {
        if (StringUtils.isEmpty(xqDeviceId)) {
            return AjaxResult.error("项圈设备ID不能为空");
        }
        
        // 查询项圈设备信息 - 使用selectList避免TooManyResultsException
        LambdaQueryWrapper<XqClient> wrapper = new LambdaQueryWrapper<>();
        // 兼容老数据：有的记录存 deviceId，有的使用 sn 作为设备唯一编号
        wrapper.and(w -> w.eq(XqClient::getDeviceId, xqDeviceId)
                          .or()
                          .eq(XqClient::getSn, xqDeviceId));
        wrapper.orderByDesc(XqClient::getUptime); // 按更新时间倒序，取最新的记录
        List<XqClient> collars = xqClientMapper.selectList(wrapper);
        
        if (collars.isEmpty()) {
            return AjaxResult.error("未找到对应的项圈设备信息");
        }
        
        // 取第一条记录（最新的）
        XqClient collar = collars.get(0);
        
        // 获取设备的经纬度
        String latitude = collar.getLatitude();
        String longitude = collar.getLongitude();
        
        // 判断经纬度是否为空或为0
        if (isInvalidLocation(latitude, longitude)) {
            return AjaxResult.error("暂无定位信息");
        }
        
        // 转换为百度经纬度
        double lat = Double.parseDouble(latitude);
        double lon = Double.parseDouble(longitude);
        double[] baiduLocation = LngLonUtil.gps84_To_bd09(lat, lon);
        
        // 构建返回数据
        Map<String, Object> locationData = new java.util.HashMap<>();
        locationData.put("deviceId", xqDeviceId);
        locationData.put("latitude", String.valueOf(baiduLocation[0]));
        locationData.put("longitude", String.valueOf(baiduLocation[1]));
        locationData.put("altitude", collar.getAltitude());
        locationData.put("battery", collar.getBattery());
        locationData.put("temperature", collar.getTemperature());
        locationData.put("updateTime", collar.getUptime());
        locationData.put("gpsState", collar.getGpsState());
        locationData.put("nsat", collar.getNsat());
        
        return AjaxResult.success(locationData);
    }
    
    @Override
    public AjaxResult getCollarTrack(String deliveryId, String xqDeviceId, String trackTime, String trackEndTime) {
        if (StringUtils.isEmpty(xqDeviceId)) {
            return AjaxResult.error("项圈设备ID不能为空");
        }
        
        try {
            // 构建查询条件
            LambdaQueryWrapper<XqClient> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(XqClient::getDeviceId, xqDeviceId);
            wrapper.orderByAsc(XqClient::getUptime); // 按时间正序排列
            
            // 添加时间范围条件
            if (StringUtils.isNotEmpty(trackTime) && StringUtils.isNotEmpty(trackEndTime)) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date startTime = sdf.parse(trackTime);
                Date endTime = sdf.parse(trackEndTime);
                wrapper.between(XqClient::getUptime, startTime, endTime);
            }
            
            // 查询轨迹数据
            List<XqClient> trackData = xqClientMapper.selectList(wrapper);
            
            if (trackData.isEmpty()) {
                return AjaxResult.error("暂无轨迹数据");
            }
            
            // 构建返回数据
            List<Map<String, Object>> trackList = new ArrayList<>();
            for (XqClient collar : trackData) {
                if (!isInvalidLocation(collar.getLatitude(), collar.getLongitude())) {
                    // 转换为百度经纬度
                    double lat = Double.parseDouble(collar.getLatitude());
                    double lon = Double.parseDouble(collar.getLongitude());
                    double[] baiduLocation = LngLonUtil.gps84_To_bd09(lat, lon);
                    
                    Map<String, Object> trackPoint = new java.util.HashMap<>();
                    trackPoint.put("longitude", String.valueOf(baiduLocation[1]));
                    trackPoint.put("latitude", String.valueOf(baiduLocation[0]));
                    trackPoint.put("altitude", collar.getAltitude());
                    trackPoint.put("updateTime", collar.getUptime());
                    trackPoint.put("battery", collar.getBattery());
                    trackPoint.put("temperature", collar.getTemperature());
                    trackList.add(trackPoint);
                }
            }
            
            if (trackList.isEmpty()) {
                return AjaxResult.error("暂无有效轨迹数据");
            }
            
            return AjaxResult.success(trackList);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("查询轨迹失败: " + e.getMessage());
        }
    }
    
    @Override
    public AjaxResult getCollarDeviceTrack(String deliveryId, String xqDeviceId, String trackTime, String trackEndTime) {
        // 设备轨迹查询逻辑与项圈轨迹相同
        return getCollarTrack(deliveryId, xqDeviceId, trackTime, trackEndTime);
    }
    
    /**
     * 判断位置信息是否无效
     */
    private boolean isInvalidLocation(String latitude, String longitude) {
        if (StringUtils.isEmpty(latitude) || StringUtils.isEmpty(longitude)) {
            return true;
        }
        
        try {
            double lat = Double.parseDouble(latitude);
            double lon = Double.parseDouble(longitude);
            return lat == 0.0 && lon == 0.0;
        } catch (NumberFormatException e) {
            return true;
        }
    }
}


