#pragma once


#include "../External_Database/export.h"

#include <map>
#include <memory>
#include <optional>
#include <string>

#include "SSR/Aircraft_Info.h"

class Aircraft : public SSR::Aircraft_Info {
public:
    explicit Aircraft(const std::string& icao);

    // 静态信息按 ICAO24 加载一次；航线信息仅在 callsign 变化时重新加载。
    // map 的键是外部数据源名称。
    std::map<std::string, std::shared_ptr<External_Database_Row>> external_database_info;
    std::map<std::string, std::shared_ptr<External_Database_Row>> callsign_external_database_info;
    bool external_database_info_loaded{};
    std::optional<std::string> last_external_database_callsign;

    [[nodiscard]] std::shared_ptr<External_Database_Row> external_database_row(
        const std::string& resource_name) const {
        const auto callsign_iter = callsign_external_database_info.find(resource_name);
        if (callsign_iter != callsign_external_database_info.end()) {
            return callsign_iter->second;
        }
        const auto iter = external_database_info.find(resource_name);
        return iter == external_database_info.end() ? nullptr : iter->second;
    }

    void refresh_external_database_info();

    Psc::JSON toJson() {
        refresh_external_database_info();
        Psc::JSON ret = Psc::JSON::object();
        Ret_J(icao)
        ret.append({"每秒位置数", get_pest()});
        ret.append({"飞机位置轨迹点数", air_pos_track_list.size()});
        ret.append({"地面位置轨迹点数", surface_pos_track_list.size()});
        ret.append({"信号强度", signal_level});
        auto opt_pos = air_pos_track_list.last();
        ret.append({"当前位置消息", opt_pos.has_value() ? opt_pos->to_json() : ""});

        auto cpr_state_opt = BDS05_airborne_position.value;
        ret.append({"cpr解码器状态",
                    cpr_state_opt.has_value()
                        ? cpr_state_opt.value().current_state_json()
                        : ""});
        ret.append({"时间", Psc::utc_2_local_time(timestamp)});
        ret.append({"多点定位数据源", mlat});

        auto external_info = Psc::JSON::object();
        for (const auto& [resource_key, row] : external_database_info) {
            external_info.append({resource_key, row->to_json()});
        }
        for (const auto& [resource_key, row] : callsign_external_database_info) {
            external_info.append({resource_key, row->to_json()});
        }
        ret.append({"external_database_info", external_info});

        push_all_bds_info(ret);
        return ret;
    }

#ifdef Cache_Some_Mode_S
    std::list<std::shared_ptr<Mode_S_Msg>> cache;
    size_t total_num = 0;
    void add_msg_limit(const std::shared_ptr<Mode_S_Msg>& msg) {
        if (cache.size() > Cache_Some_Mode_S_Num) {
            cache.pop_front();
        }
        cache.emplace_back(msg);
        total_num++;
    }
#endif
};
