package com.multictrl.modules.business.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Maps;
import com.multictrl.common.constant.BusinessConstant;
import com.multictrl.common.constant.FlightTaskStatus;
import com.multictrl.common.service.impl.CrudServiceImpl;
import cn.hutool.core.util.StrUtil;
import com.multictrl.common.utils.CacheUtils;
import com.multictrl.common.utils.DateUtils;
import com.multictrl.common.utils.Spatial4jUtils;
import com.multictrl.modules.business.dao.DockDeviceDao;
import com.multictrl.modules.business.dao.FlightTaskDao;
import com.multictrl.modules.business.dto.FlightTaskDTO;
import com.multictrl.modules.business.dto.RouteDTO;
import com.multictrl.modules.business.entity.DockDeviceEntity;
import com.multictrl.modules.business.entity.DockEntity;
import com.multictrl.modules.business.entity.FlightTaskEntity;
import com.multictrl.modules.business.entity.MediaFileEntity;
import com.multictrl.modules.business.influxdb.UavReport;
import com.multictrl.modules.business.service.*;
import com.multictrl.modules.security.user.SecurityUser;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 飞行架次
 *
 * @author Sdy
 * @since 1.0.0 2026-05-02
 */
@Service
@RequiredArgsConstructor
public class FlightTaskServiceImpl extends CrudServiceImpl<FlightTaskDao, FlightTaskEntity, FlightTaskDTO> implements FlightTaskService {
    private final DockService dockService;
    private final RouteService routeService;
    private final InfluxService influxService;
    private final MediaFileService mediaFileService;
    private final DockDeviceDao dockDeviceDao;

    @Override
    public QueryWrapper<FlightTaskEntity> getWrapper(Map<String, Object> params) {
        String id = (String) params.get("id");

        QueryWrapper<FlightTaskEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StrUtil.isNotBlank(id), "id", id);

        return wrapper;
    }

    @Override
    public void addRouteTask(String taskId, String dockSn, Long routeId) {
        FlightTaskEntity entity = new FlightTaskEntity();
        entity.setTaskId(taskId);
        entity.setTaskType(1);
        addDockInfo(entity, dockSn);
        entity.setRouteId(routeId);
        RouteDTO route = routeService.getRoute(routeId);
        entity.setRouteName(route.getRouteName());
        entity.setRouteType(route.getTemplateType());
        entity.setRouteDistance(route.getTotalDistance());
        entity.setWaypointNum(route.getRouteWaypointList().size());
        entity.setDeptId(SecurityUser.getDeptId());
        entity.setTaskStatus(FlightTaskStatus.IN_PROGRESS.getCode());
        entity.setCreateName(SecurityUser.getUser().getRealName());
        baseDao.insert(entity);
    }

    @Override
    public void addTakeoffTask(String taskId, String dockSn) {
        FlightTaskEntity entity = new FlightTaskEntity();
        entity.setTaskId(taskId);
        entity.setTaskType(2);
        addDockInfo(entity, dockSn);
        entity.setRouteName("一键起飞");
        entity.setDeptId(SecurityUser.getDeptId());
        entity.setTaskStatus(FlightTaskStatus.IN_PROGRESS.getCode());
        entity.setCreateName(SecurityUser.getUser().getRealName());
        baseDao.insert(entity);
    }

    @Override
    public void updateTaskComplete(String dockSn) {
        String taskId = (String) CacheUtils.get(BusinessConstant.WORKING_TASK_ID + dockSn);
        if (StrUtil.isBlank(taskId)) {
            log.debug("dockSn:{} 没有正在执行的任务，无法更新架次表");
            return;
        }
        FlightTaskEntity entity = selectById(taskId);
        entity.setTaskStatus(FlightTaskStatus.FINISHED.getCode());
        entity.setInboundDate(new Date());
        //更新飞行距离、飞行时长
        HashMap<String, Object> condition = Maps.newHashMap();
        condition.put("dockSn", dockSn);
        List<UavReport> flyList = influxService.queryData(DateUtils.format(entity.getOutboundDate(), DateUtils.DATE_TIME_PATTERN),
                DateUtils.format(entity.getInboundDate(), DateUtils.DATE_TIME_PATTERN), "uav_osd", condition, UavReport.class,
                "longitude", "latitude", "elevation", "_time");
        double total = 0;
        UavReport start = null;
        UavReport end = null;
        for (int i = 0; i < flyList.size() - 1; i++) {
            UavReport p1 = flyList.get(i);
            UavReport p2 = flyList.get(i + 1);
            total += Spatial4jUtils.distance(p1.getLatitude(), p1.getLongitude(), p2.getLatitude(), p2.getLongitude());
            //过滤出起飞和降落的记录，当飞机和机场的相对高度大于0，则认为飞机在飞行中，开始计算飞行时长
            if (flyList.get(i).getElevation() > 0) {
                end = flyList.get(i);
                if (start == null) {
                    start = flyList.get(i);
                }
            }
        }
        entity.setFlightDistance(total);
        String flightDurationText = "0秒";
        long flightDuration = 0L;
        if (start != null && end != null) {
            DateTime startDate = DateUtil.parseDateTime(start.getTimeStr());
            DateTime endDate = DateUtil.parseDateTime(end.getTimeStr());
            flightDurationText = DateUtils.formatDifference(startDate, endDate);
            flightDuration = Math.abs((endDate.getTime() - startDate.getTime()) / 1000);
        }
        entity.setFlightDurationText(flightDurationText);
        entity.setFlightDuration(flightDuration);
        //更新媒体数量 -- 媒体上传 机库是分段式的，机场空闲了，媒体文件还没上传，所以该值不准确可能为0
        Long count = mediaFileService.getDao().selectCount(new QueryWrapper<MediaFileEntity>()
                .eq("task_id", taskId).eq("dock_sn", dockSn));
        entity.setMediaNum(count.intValue());
        updateById(entity);
    }

    @Override
    public void updateTaskStart(String dockSn) {
        String taskId = (String) CacheUtils.get(BusinessConstant.WORKING_TASK_ID + dockSn);
        if (StrUtil.isBlank(taskId)) {
            log.debug("dockSn:{} 没有正在执行的任务，无法更新架次表");
            return;
        }
        FlightTaskEntity entity = selectById(taskId);
        entity.setTaskStatus(FlightTaskStatus.IN_PROGRESS.getCode());
        entity.setOutboundDate(new Date());
        List<DockDeviceEntity> deviceEntityList = dockDeviceDao.selectList(new QueryWrapper<DockDeviceEntity>().eq("parent_sn", dockSn));
        for (DockDeviceEntity dockDevice : deviceEntityList) {
            String deviceModelKey = dockDevice.getDeviceModelKey();
            if (deviceModelKey.startsWith("0")) {
                entity.setUavSn(dockDevice.getSn());
            }
        }
        updateById(entity);
    }

    //添加dock信息
    private void addDockInfo(FlightTaskEntity entity, String dockSn) {
        entity.setDockSn(dockSn);
        DockEntity dockEntity = dockService.getDao().selectOne(new QueryWrapper<DockEntity>().eq("dock_sn", dockSn));
        if (dockEntity != null) {
            entity.setDockName(dockEntity.getDockName());
            entity.setDockType(dockEntity.getDockType());
            entity.setDockModel(dockEntity.getDockModel());
        }
    }
}