#include "MLAT.h"

#include "Global.h"

#include <fstream>

time_t datetime_to_timestamp(const std::string& datetime) {
    std::tm tm = {};
    std::istringstream ss(datetime);
    ss >> std::get_time(&tm, "%Y-%m-%d %H:%M:%S");
    if (ss.fail()) {
        throw std::runtime_error("时间格式错误");
    }
    // std::mktime按本地时区转换
    return std::mktime(&tm);
}

std::multimap<std::string, Base_MLAT_Data> hex_mlat_map;
std::vector<MLAT_Data> read_lines() {
    Base_Logger_Manager::instance()->init();

    std::multimap<size_t, Base_MLAT_Data> ordered_multimap;
    std::ifstream fin("C:/wyc/CLionProjects/plantSunCat/mainProjects/Radarcape/data/0701/info.txt");
    if (!fin) {
        std::cerr << "无法打开文件！" << std::endl;
        return {};
    }
    std::string line;
    while (std::getline(fin, line)) {
        if (line.empty()) continue;

        std::vector<std::string> fields;
        std::stringstream ss(line);
        std::string item;
        while (std::getline(ss, item, ';')) {
            fields.push_back(item);
        }
        // 检查字段数
        if (fields.size() < 9) continue;
        // 2025-07-03 10:16:21;VG_MSDW;28069B;2025-06-27 08:00:14;A800103FFF9CCB27FFFCA89DE0D3;121.691398;37.344925;8000;;0000;2_1_3
        // 按 1-base 提取
        std::string icao = fields[2];
        icao.resize(6, '_');
        std::string msg = fields[4];
        std::string lon = fields[5];
        std::string lat = fields[6];



        std::string time = fields[3];
        std::string hex = fields[4];
        // 输出（或者你可以存到 vector 里）
        // std::cout << icao << " " << lat << " " << lon << " " << alt << std::endl;

        Base_MLAT_Data b;
        //cur.icao = icao;
        b.mlat_data.lon = stod(lon);
        b.mlat_data.lat = stod(lat);
        b.msg = line;
        b.hex = hex;
        b.icao = icao;
        strncpy(b.mlat_data.icao, icao.c_str(), 6);
        //std::cout << cur.lat << "  " << cur.lon << std::endl;
        // if (35 < cur.lat && cur.lat < 37
        //     &&
        //     120 < cur.lon && cur.lon < 122
        // ) {
        //
        //     pure_log("@/logs/mlat_.log", line + "\n");
        // }
        ordered_multimap.insert({datetime_to_timestamp(time), b});

    }
    std::vector<MLAT_Data> list;
    for (auto it : ordered_multimap) {
        Base_MLAT_Data& b = it.second;
        list.push_back(b.mlat_data);
        auto icao = std::string(b.mlat_data.icao, 6);
        // if (icao == "78139F") {
        //     pure_log("@/logs/icao/" +  icao + "_mlat_result.log", b.msg + "\n");
        // }
        hex_mlat_map.insert({b.hex, b});
    }
    return list;
}
std::vector<MLAT_Data> all;

void read(MLAT_Data* buf, std::uint16_t* len) {
    if (all.empty()) {
        all = read_lines();
    }
    static size_t pos = 0; // 上一次拷贝结束后的位置
    const size_t BATCH = 100;
    size_t total = all.size();
    size_t n = std::min(BATCH, total - pos); // 本次实际要拷贝多少

    for (size_t i = 0; i < n; ++i) {
        buf[i] = all[pos + i];
    }
    *len = static_cast<std::uint16_t>(n);

    pos += n;
    if (pos >= total) {
        pos = 0; // 如果需要循环一轮后归零，否则你可以不归零
    }
}


MLAT_Config::MLAT_Config() {}
void MLAT_Config::init(const Psc::JSON * that_json)  {
    enable = that_json->get_bool("enable");
    merge = that_json->get_bool("merge");
    library_path = that_json->get_string("library_path");
    function_name = that_json->get_string("function_name");
    if (enable) {
        {
            auto r = Psc::try_load_library(Psc::get_abs_path(library_path));
            if (!r) {
                Psc::fail_fast();
            }
            lib = r.value();
        }
        {
            auto r = Psc::try_load_function(lib, function_name);
            if (!r) {
                Psc::fail_fast();
            }
            read_func_ptr = (Func_Type)r.value();
        }


        all = read_lines();
        read_func_ptr = read;
    }
}


void MLAT_Config::refresh()  {
    std::lock_guard guard(mtx);
    std::uint16_t len{};
    if (read_func_ptr) read_func_ptr(buf, &len);
    auto list = Global::instance()->mode_acs.data_source_config.map.list();
    for (std::uint16_t i = 0; i < len; i++) {
        MLAT_Data& cur = buf[i];
        std::string icao = std::string(cur.icao, 6);

        for (const auto& li : list) {
            //auto air = li->get_aircraft(icao);
            auto air = li->get_aircraft(icao);
            if (air) {
                // air->mlat = true;
                // air->air_pos_track_list.push(CPR::Position{cur.lat, cur.lon});
            }
        }

        auto& t = update_map[icao];
        if (t.d.lat != cur.lat || t.d.lon != cur.lon) {
            t.d = cur;
        }
    }
}


void MLAT_Config::server(Global* g) {
    auto& svr = g->svr;
    auto& api = g->api;
    svr.Post(api + "get_mlat_list", [this](HTTP_Param) {
         res->setBody(warp(get_reset()).to_json_string());
    });

    // svr.Post(api + "get_mlat_server_config", [this](HTTP_Param) {
    //      res->setBody(warp(to_json()).to_json_string());
    //  });
    // svr.Post(api + "/set_mlat_server_config", [this, g](HTTP_Param) {
    //     CHECK_JSON_PARAM
    //     MLAT_Server_Config t;
    //     t.init(&o_params.value());
    //     bool ok = check_ipv4(t.ip) && check_port(t.port);
    //     if (!ok)
    //     {
    //         server_logger->error("", {}, LOG_POS + "  ip port! " + t.ip + ":" + std::to_string(t.port));
    //         res->setBody(warp(to_json()).to_json_string());
    //         return;
    //     }
    //
    //     auto& s = g->mlat_server;
    //     s.id = t.id;
    //     s.port = t.port;
    //     s.ip = t.ip;
    //
    //     Global::save();
    //     res->setBody(warp(to_json()).to_json_string());
    // });
}
