package com.multictrl.modules.business.handler;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.multictrl.common.config.DJIConfig;
import com.multictrl.common.config.MinioConfig;
import com.multictrl.common.constant.BusinessConstant;
import com.multictrl.common.utils.CacheUtils;
import com.multictrl.common.utils.JsonUtils;
import com.multictrl.modules.business.dao.DeviceDicDao;
import com.multictrl.modules.business.dao.DockDeviceDao;
import com.multictrl.modules.business.dto.flight.FlightTaskPrepare;
import com.multictrl.modules.business.entity.DeviceDicEntity;
import com.multictrl.modules.business.entity.DockDeviceEntity;
import com.multictrl.modules.business.service.MinioService;
import com.multictrl.modules.business.service.MqttPushService;
import io.minio.credentials.Credentials;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * requests消息处理器
 *
 * @author Sdy
 * @since 1.0.0 2026/4/22
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class RequestsHandler implements MessageHandler {
    private final DJIConfig djiConfig;
    private final MqttPushService mqttPushService;
    private final DockDeviceDao dockDeviceDao;
    private final DeviceDicDao deviceDicDao;
    private final MinioService minioService;
    private final MinioConfig minioConfig;

    @Override
    public void handleMessage(String topic, String payload, String gateway) {
//        log.debug("requests --> topic: {}, payload: {}", topic, payload);
        JSONObject message = JsonUtils.parseObject(payload, JSONObject.class);
        if (message != null) {
            String method = message.getStr(BusinessConstant.METHOD);
//            String dockSn = message.getStr(BusinessConstant.GATEWAY);
            JSONObject data = message.getJSONObject(BusinessConstant.DATA);
            if (BusinessConstant.CONFIG.equals(method)) {//第一步 配置更新
                data.set("app_id", djiConfig.getAppId());
                data.set("app_key", djiConfig.getAppKey());
                data.set("app_license", djiConfig.getAppLicense());
                data.set("ntp_server_host", djiConfig.getNtpServerHost());
                data.set("ntp_server_port", djiConfig.getNtpServerPort());
                mqttPushService.pushMessageByClient1(topic + BusinessConstant._REPLY, message.toString());
                log.debug("requests step1--> 设备配置发送成功");
            } else if (BusinessConstant.AIRPORT_BIND_STATUS.equals(method)) {//第二步 获取设备绑定信息
                JSONArray devices = data.getJSONArray("devices");
                if (!devices.isEmpty()) {
                    JSONObject output = new JSONObject();
                    JSONArray bindStatus = new JSONArray();
                    //判断sn是否存在
                    for (Object device : devices) {
                        JSONObject deviceJson = (JSONObject) device;
                        if (!deviceJson.containsKey("sn") || StrUtil.isBlank(deviceJson.getStr("sn"))) {
                            data.set("result", 1);
                            mqttPushService.pushMessageByClient1(topic + BusinessConstant._REPLY, message.toString());
                            log.debug("requests step2--> 获取设备绑定信息失败，设备sn为空");
                            return;
                        }
                        String sn = deviceJson.getStr("sn");
                        DockDeviceEntity dockDevice = dockDeviceDao.selectOne(new QueryWrapper<DockDeviceEntity>().eq("sn", sn));
                        if (dockDevice == null) {
                            data.set("result", 1);
                            mqttPushService.pushMessageByClient1(topic + BusinessConstant._REPLY, message.toString());
                            log.debug("requests step2--> 获取设备绑定信息失败，设备未绑定");
                            return;
                        }
                        deviceJson.set("device_callsign", System.currentTimeMillis());
                        deviceJson.set("is_device_bind_organization", true);
                        deviceJson.set("organization_id", djiConfig.getOrganizationId());
                        deviceJson.set("organization_name", djiConfig.getOrganizationName());
                        bindStatus.add(deviceJson);
                    }
                    output.set("bind_status", bindStatus);
                    data.set("result", 0);
                    data.set("output", output);
                    mqttPushService.pushMessageByClient1(topic + BusinessConstant._REPLY, message.toString());
                    log.debug("requests step2--> 获取设备绑定信息成功");
                } else {
                    data.set("result", 1);
                    mqttPushService.pushMessageByClient1(topic + BusinessConstant._REPLY, message.toString());
                    log.debug("requests step2--> 获取设备绑定信息失败，设备数量为空");
                }
            } else if (BusinessConstant.AIRPORT_ORGANIZATION_GET.equals(method)) {//第三步 查询设备绑定对应的组织信息
                String deviceBindingCode = data.getStr("device_binding_code");
                String organizationId = data.getStr("organization_id");
                if (!djiConfig.getDeviceBindCode().equals(deviceBindingCode) || !djiConfig.getOrganizationId().equals(organizationId)) {
                    data.set("result", 2);
                    mqttPushService.pushMessageByClient1(topic + BusinessConstant._REPLY, message.toString());
                    log.debug("requests step3--> 查询设备绑定对应的组织信息失败，设备绑定码或组织id不匹配");
                    return;
                }
                JSONObject output = new JSONObject();
                output.set("organization_name", djiConfig.getOrganizationName());
                data.set("result", 0);
                data.set("output", output);
                mqttPushService.pushMessageByClient1(topic + BusinessConstant._REPLY, message.toString());
                log.debug("requests step3--> 查询设备绑定对应的组织信息成功");
            } else if (BusinessConstant.AIRPORT_ORGANIZATION_BIND.equals(method)) {//第四步 设备绑定组织信息
                JSONArray bindDevices = data.getJSONArray("bind_devices");
                if (bindDevices.size() == 2) {
                    List<DockDeviceEntity> bindDeviceList = new ArrayList<>();
                    for (Object bindDevice : bindDevices) {
                        JSONObject deviceJson = (JSONObject) bindDevice;
                        if (!deviceJson.containsKey("sn") || StrUtil.isBlank(deviceJson.getStr("sn"))) {
                            data.set("result", 3);
                            mqttPushService.pushMessageByClient1(topic + BusinessConstant._REPLY, message.toString());
                            log.debug("requests step4--> 设备绑定组织信息失败，设备sn为空");
                            return;
                        }
                        String sn = deviceJson.getStr("sn");
                        DockDeviceEntity device = new DockDeviceEntity();
                        device.setSn(sn);
                        device.setDeviceBindingCode(deviceJson.getStr("device_binding_code"));
                        device.setDeviceCallsign(deviceJson.getStr("device_callsign"));
                        device.setDeviceModelKey(deviceJson.getStr("device_model_key"));
                        device.setOrganizationId(deviceJson.getStr("organization_id"));
                        if (!sn.equals(gateway)) {
                            device.setParentSn(gateway);
                        }
                        Date date = new Date();
                        device.setBindDate(date);
                        device.setUpdateDate(date);
                        String deviceModelKey = deviceJson.getStr("device_model_key");
                        String[] split = deviceModelKey.split("-");
                        device.setDomain(Integer.parseInt(split[0]));
                        device.setDeviceType(Integer.parseInt(split[1]));
                        device.setSubType(Integer.parseInt(split[2]));
                        DeviceDicEntity deviceDicEntity = deviceDicDao.selectOne(new QueryWrapper<DeviceDicEntity>()
                                .eq("domain", device.getDomain())
                                .eq("device_type", device.getDeviceType())
                                .eq("sub_type", device.getSubType()));
                        device.setDeviceName(deviceDicEntity != null ? deviceDicEntity.getDeviceName() : "unknown");
                        bindDeviceList.add(device);
                    }
                    if (CollUtil.isEmpty(bindDeviceList) || bindDeviceList.size() != 2) {
                        data.set("result", 3);
                        mqttPushService.pushMessageByClient1(topic + BusinessConstant._REPLY, message.toString());
                        log.debug("requests step4--> 设备绑定组织信息失败，设备绑定数量不为2");
                        return;
                    }
                    dockDeviceDao.delete(new QueryWrapper<DockDeviceEntity>().eq("sn", gateway).or()
                            .eq("parent_sn", gateway));
                    dockDeviceDao.insert(bindDeviceList);
                    data.set("result", 0);
                    mqttPushService.pushMessageByClient1(topic + BusinessConstant._REPLY, message.toString());
                    log.debug("requests step4--> 设备绑定组织信息成功，设备绑定数量为{}", bindDeviceList.size());
                } else {
                    data.set("result", 3);
                    mqttPushService.pushMessageByClient1(topic + BusinessConstant._REPLY, message.toString());
                    log.debug("requests step4--> 设备绑定组织信息失败，设备数量不为2");
                }
            } else if (BusinessConstant.FLIGHT_TASK_RESOURCE_GET.equals(method)) {
                Object object = CacheUtils.get(BusinessConstant.FLIGHT_TASK_KMZ_FILE_INFO + gateway);
                log.debug("requests flighttask_resource_get--> 任务资源获取:{}", object);
                if (object != null) {
                    FlightTaskPrepare.FileInfo fileInfo = (FlightTaskPrepare.FileInfo) object;
                    data.clear();
                    JSONObject output = new JSONObject();
                    JSONObject file = new JSONObject();
                    file.set("url", fileInfo.getUrl());
                    file.set("fingerprint", fileInfo.getFingerprint());
                    output.set("file", file);
                    data.set("output", output);
                    data.set("result", 0);
                    message.set("timestamp", System.currentTimeMillis());
                    mqttPushService.pushMessageByClient1(topic + BusinessConstant._REPLY, message.toString());
                    log.debug("requests flighttask_resource_get--> 任务资源获取成功");
                }
            } else if (BusinessConstant.STORAGE_CONFIG_GET.equals(method)) {
                data.clear();
                data.set("result", 0);
                JSONObject output = new JSONObject();
                minioService.createBucket(BusinessConstant.DOCK_MEDIA_BUCKET);
                output.set("bucket", BusinessConstant.DOCK_MEDIA_BUCKET);
                JSONObject credentials = new JSONObject();
                credentials.set("expire", 3600);
                Credentials cds = minioService.getCredentials();
                if (cds != null) {
                    credentials.set("access_key_id", cds.accessKey());
                    credentials.set("access_key_secret", cds.secretKey());
                    credentials.set("security_token", cds.sessionToken());
                }
                output.set("credentials", credentials);
                output.set("endpoint", minioConfig.getEndpoint());
                output.set("object_key_prefix", gateway);
                output.set("provider", "minio");
                output.set("region", "us-east-1");
                data.set("output", output);
                message.set("timestamp", System.currentTimeMillis());
                message.remove("need_reply");
                message.remove("gateway");
                mqttPushService.pushMessageByClient1(topic + BusinessConstant._REPLY, message.toString());
                log.debug("requests storage_config_get--> 存储配置获取成功");
            }
        } else {
            log.debug("requests --> payload解析失败，解析后为null");
        }
    }
}
