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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import cn.hutool.core.util.StrUtil;
import com.multictrl.common.annotation.DataFilter;
import com.multictrl.common.constant.BusinessConstant;
import com.multictrl.common.constant.DJIImage;
import com.multictrl.common.constant.DockMode;
import com.multictrl.common.page.PageData;
import com.multictrl.common.service.impl.CrudServiceImpl;
import com.multictrl.common.utils.ConvertUtils;
import com.multictrl.modules.business.dao.DeviceDicDao;
import com.multictrl.modules.business.dao.DockDao;
import com.multictrl.modules.business.dao.DockDeviceDao;
import com.multictrl.modules.business.dto.DockDTO;
import com.multictrl.modules.business.entity.DeviceDicEntity;
import com.multictrl.modules.business.entity.DockDeviceEntity;
import com.multictrl.modules.business.entity.DockEntity;
import com.multictrl.modules.business.service.DJIBaseService;
import com.multictrl.modules.business.service.DockService;
import com.multictrl.modules.security.service.ShiroService;
import com.multictrl.modules.sys.dao.SysDictDataDao;
import com.multictrl.modules.sys.entity.SysDictDataEntity;
import com.multictrl.modules.sys.service.SysDictDataService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 机库信息表
 *
 * @author Sdy
 * @since 1.0.0 2026-04-17
 */
@Service
@RequiredArgsConstructor
public class DockServiceImpl extends CrudServiceImpl<DockDao, DockEntity, DockDTO> implements DockService {
    private final DJIBaseService djiBaseService;
    private final DockDeviceDao dockDeviceDao;
    private final DeviceDicDao deviceDicDao;
    private final ShiroService shiroService;
    private final SysDictDataDao dictDataDao;

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

        QueryWrapper<DockEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StrUtil.isNotBlank(id), "id", id);
        wrapper.and(StrUtil.isNotBlank(key), qw ->
                qw.like("dock_name", key).or().eq("dock_sn", key));
        wrapper.orderByDesc("update_date");

        return wrapper;
    }

    @Override
    public void updateDockLocation(String dockSn, JSONObject data) {
        DockEntity dockEntity = baseDao.selectOne(new QueryWrapper<DockEntity>().eq("dock_sn", dockSn));
        if (dockEntity == null) {
            return;
        }
        Double latitude = data.getDouble("latitude");
        Double longitude = data.getDouble("longitude");
        Double height = data.getDouble("height");
        dockEntity.setDockLatitude(latitude);
        dockEntity.setDockLongitude(longitude);
        dockEntity.setDockHeight(height);
        JSONObject alternateLandPoint = data.getJSONObject("alternate_land_point");
        if (alternateLandPoint != null) {
            dockEntity.setDeputyLatitude(alternateLandPoint.getDouble("latitude"));
            dockEntity.setDeputyLongitude(alternateLandPoint.getDouble("longitude"));
            dockEntity.setDeputyHeight(alternateLandPoint.getDouble("height"));
        }
        baseDao.updateById(dockEntity);
    }

    @Override
    @DataFilter
    public PageData<DockDTO> pageList(Map<String, Object> params) {
        PageData<DockDTO> page = page(params);
        for (DockDTO dockDTO : page.getList()) {
            Integer dockModeCode = djiBaseService.getDockModeCode(dockDTO.getDockSn());
            dockDTO.setDockMode(DockMode.getDescByCode(dockModeCode));
            dockDTO.setOnline(djiBaseService.isDockOnline(dockDTO.getDockSn()));
            List<DockDeviceEntity> deviceEntityList = dockDeviceDao.selectList(new QueryWrapper<DockDeviceEntity>().eq("parent_sn", dockDTO.getDockSn()));
            for (DockDeviceEntity dockDevice : deviceEntityList) {
                String deviceModelKey = dockDevice.getDeviceModelKey();
                if (deviceModelKey.startsWith("0")) {
                    List<DeviceDicEntity> list = deviceDicDao.selectList(new QueryWrapper<DeviceDicEntity>()
                            .eq("domain", dockDevice.getDomain())
                            .eq("device_type", dockDevice.getDeviceType())
                            .eq("sub_type", dockDevice.getSubType()));
                    if (!list.isEmpty()) {
                        dockDTO.setUavModel(list.get(0).getDeviceName());
                    }
                }
            }
            String dockType = dockDTO.getDockType();
            if (BusinessConstant.DJI_SIGN.equals(dockType)) {
                DockDeviceEntity dockDevice = dockDeviceDao.selectOne(new QueryWrapper<DockDeviceEntity>().eq("sn", dockDTO.getDockSn()));
                if (dockDevice != null) {
                    dockDTO.setImgUrl(BusinessConstant.IMAGE_PATH + DJIImage.getImageUrlByName(dockDevice.getDeviceName()));
                    dockDTO.setDockModel(dockDevice.getDeviceName());
                }
            } else {
                String dockMode = dockDTO.getDockMode();
                List<SysDictDataEntity> list = dictDataDao.selectList(new QueryWrapper<SysDictDataEntity>()
                        .eq("dict_value", dockMode).orderByAsc("create_date"));
                if (list != null) {
                    dockDTO.setImgUrl(BusinessConstant.IMAGE_PATH + list.get(0).getImageUrl());
                }
            }
        }
        return page;
    }

    @Override
    public List<DockDTO> getUserDockList(Long userId) {
        List<Long> dataScopeList = shiroService.getDataScopeList(userId);
        List<DockEntity> list = new ArrayList<>();
        if (CollUtil.isNotEmpty(dataScopeList)) {
            list = baseDao.selectList(new QueryWrapper<DockEntity>().in("dept_id", dataScopeList));
        }

        return ConvertUtils.sourceToTarget(list, DockDTO.class);
    }

    @Override
    public DockDao getDao() {

        return baseDao;
    }
}