#ifndef PSC_GLOBAL_INCLUDE_H
#define PSC_GLOBAL_INCLUDE_H
#include "Core/Statistics/Statistics.h"
#include "Core/socket/ByteOrder.h"
#include "SSR/export.h"
#include <functional>
#include <iostream>
#include <map>
#include <mutex>
#include <optional>
#include <queue>
#include <stdexcept>
#include <string>
#include <thread>
#include <utility>
#include <vector>

class Global;

class Invalid_Http_Param final : public std::runtime_error {
public:
    using std::runtime_error::runtime_error;
};

[[noreturn]] inline void throw_invalid_http_param(const char* detail) {
    throw Invalid_Http_Param(detail);
}



#define CHECK_JSON_PARAM \
auto o_params = Psc::try_parse_json(req->body().data()); \
if (!o_params.has_value()) { \
throw_invalid_http_param("request body is not valid JSON"); \
} \
auto& params = o_params.value(); \
auto that_json = &params;

#define HTTP_REQUIRE_VALUE(NAME, EXPRESSION) \
auto o_http_##NAME = (EXPRESSION); \
if (!o_http_##NAME.has_value()) { \
throw_invalid_http_param(#NAME); \
} \
auto NAME = std::move(o_http_##NAME).value();

#define HTTP_REQUIRE_PTR(NAME, EXPRESSION) \
auto NAME = (EXPRESSION); \
if ((NAME) == nullptr) { \
throw_invalid_http_param(#NAME); \
}

#define HTTP_REQUIRE_TRUE(EXPRESSION, DETAIL) \
if (!(EXPRESSION)) { \
throw_invalid_http_param(DETAIL); \
}





template <typename Value_Type>
class Ordered_List {
public:
    void swap(size_t i, size_t j) {
        std::lock_guard g(mtx);
        if (i >= _list.size() || j >= _list.size()) return;

        std::swap(_list[i], _list[j]);
    }



    void push_back(Value_Type value) {
        std::lock_guard g(mtx);
        _list.push_back(value); // 添加默认值
    }

    void insert(int i, Value_Type value) {
        std::lock_guard g(mtx);
        _list.insert(_list.begin() + i, value);
    }

    Value_Type get(size_t i) {
        return _list[i];
    }

    void remove(size_t i) {
        std::lock_guard g(mtx);
        if (i >= _list.size()) return;
        _list.erase(_list.begin() + i);
    }
    std::vector<Value_Type> list(){
        std::lock_guard g(mtx);
        return this->_list;
    }

    void clear() {
        list().clear();
    }
protected:
    std::mutex mtx;
    std::vector<Value_Type> _list;
};



template <typename Key_Type, typename Value_Type>
class Ordered_Map {
public:

    std::optional<Value_Type> get(Key_Type key) {
        std::lock_guard g(mtx);
        auto it = _map.find(key);
        if (it != _map.end()) {
            return it->second;
        }
        return std::nullopt;
    }
    bool swap(size_t i, size_t j) {
        std::lock_guard g(mtx);
        if (i >= _list.size() || j >= _list.size()) return false;

        std::swap(_list[i], _list[j]);

        // 更新 map 中的 value，假设你可以从 Value 中获取 key
        Key_Type key_i = _list[i]->key;
        Key_Type key_j = _list[j]->key;

        _map[key_i] = _list[i];
        _map[key_j] = _list[j];
        return true;
    }



    void push_back(Value_Type value) {
        std::lock_guard g(mtx);
        _list.push_back(value); // 添加默认值
        _map[value->key] = value;      // 插入到 map
    }

    bool insert(int i, Value_Type value) {
        std::lock_guard g(mtx);
        if (i < 0 || static_cast<size_t>(i) > _list.size()) return false;
        _list.insert(_list.begin() + i, value);
        _map[value->key] = value;
        return true;
    }

    Value_Type get(size_t i) {
        return _list[i];
    }

    std::optional<Value_Type> try_get(size_t i) {
        std::lock_guard g(mtx);
        if (i >= _list.size()) return std::nullopt;
        return _list[i];
    }

    bool remove(size_t i) {
        std::lock_guard g(mtx);
        if (i >= _list.size()) return false;
        Key_Type& key = _list[i]->key;
        _map.erase(key);
        _list.erase(_list.begin() + i);
        return true;
    }
    std::vector<Value_Type> list(){
        std::lock_guard g(mtx);
        return this->_list;
    }
    // std::map<Key_Type, Value_Type> map(){
    //     std::lock_guard g(mtx);
    //     return this->_map;
    // }
    void clear() {
        list().clear();
        _map.clear();
    }
protected:
    std::mutex mtx;
    std::vector<Value_Type> _list;
    std::map<Key_Type, Value_Type> _map;
};

class Mode_AC_Statistic_Data {
public:
    Psc::JSON to_json() {
        std::lock_guard g(mtx);
        Psc::JSON ret = Psc::JSON::object();
        Ret_J(pre_second_num);
        Ret_J(total_num);
        Ret_J(length_error_num);
        // Ret_J(speed);
        return ret;
    }
    void add() {
        std::lock_guard g(mtx);
        add_inter();
        // speed.update(1);
    }
    void add_length_error() {
        std::lock_guard g(mtx);
        add_inter();
        length_error_num++;
    }

protected:
    std::atomic<size_t> length_error_num{};
    void add_inter() {
        total_num++;
        auto cur_time = std::time(nullptr);
        if (cur_time != utc)
        {
            utc = cur_time;
            pre_second_num = 0;
        }
        pre_second_num++;
    }
    std::mutex mtx;
    size_t pre_second_num{};
    size_t total_num{};
    time_t utc{};
   // Psc::Speed_Statistics speed;
};


class Statistic_Data {
public:
    time_t utc{};
    size_t pre_second_num{};
    size_t total_num{};
    [[nodiscard]] Psc::JSON to_json() const {
        Psc::JSON ret = Psc::JSON::object();
        Ret_J(pre_second_num);
        Ret_J(total_num);
        return ret;
    }
    Statistic_Data() = default;
};

class DF_Statistic_Data {
public:
    time_t utc{};
    size_t pre_second_num{};
    size_t total_num{};
    size_t crc_error_num{};
    Psc::JSON to_json() {
        Psc::JSON ret = Psc::JSON::object();
        Ret_J(pre_second_num);
        Ret_J(total_num);
        Ret_J(crc_error_num);
        // Ret_J(speed);

        std::string t = "null";
        if (total_num != 0) {
            t = std::to_string(static_cast<double>(crc_error_num)/static_cast<double>(total_num)) + "%";
        }
        ret.append({"crc误码率", t});
        for (auto& cur : statistic_map)
        {
            ret.append({cur.first, cur.second.to_json()});
        }
        return ret;
    }
    void add() {
        add_inter();
    }
    void add_crc_error() {
        crc_error_num++;
    }
    void add_sub_part(const std::string& key) {
        add_sub_part_inter(key);
    }

    // Psc::Speed_Statistics speed;
protected:
    void add_inter() {
        total_num++;
        auto cur_time = std::time(nullptr);
        if (cur_time != utc)
        {
            utc = cur_time;
            pre_second_num = 0;
        }
        pre_second_num++;
        // speed.update(1);
    }

    void add_sub_part_inter(const std::string& key) {
        auto t = get_create_statistic_data(key);
        t->total_num++;
        auto cur_time = std::time(nullptr);
        if (cur_time != t->utc)
        {
            t->utc = cur_time;
            t->pre_second_num = 0;
        }
        t->pre_second_num++;
    }
    Statistic_Data* get_create_statistic_data(const std::string& key) {
        Statistic_Data* t;
        auto iter = statistic_map.find(key);
        if (iter == statistic_map.end())
        {
            Statistic_Data cur{};
            statistic_map.insert(std::make_pair(key, cur));
        }
        t = &statistic_map[key];
        return t;
    }

    std::map<std::string, Statistic_Data> statistic_map;
};

class Mode_S_Statistic_Data {
public:
    // Psc::Speed_Statistics speed;

    // Psc::Speed_Statistics total_speed() const {
    //     Psc::Speed_Statistics total_speed{};
    //     for (auto& cur : DF_Statistic_Data_map) {
    //         total_speed += cur.second.speed;
    //     }
    //     return total_speed;
    // }
    Psc::JSON to_json() {
        size_t total_num = get_total_num();
        size_t crc_error_num = get_crc_error_num();
        Psc::JSON ret = Psc::JSON::object();


        ret.append({"每秒数量", get_total_pre_second_num()});

        Ret_J(length_error_num);
        Ret_J(total_num);

        std::string t = "null";
        if (total_num != 0) {
            t = std::to_string(static_cast<double>(crc_error_num)/static_cast<double>(total_num)) + "%";
        }
        Ret_J(crc_error_num);
        ret.append({"crc_error_rate", t});




        Psc::JSON df_sub_type = Psc::JSON::object();
        for (auto& cur : DF_Statistic_Data_map)
        {
            df_sub_type.append({Psc::to_string(cur.first) + " [" + std::to_string(static_cast<int>(cur.first)) +  "]", cur.second.to_json()});
        }
        Psc::JSON cpr_error_o = Psc::JSON::object();
        for (auto& cur : cpr_error)
        {
            cpr_error_o.append({Psc::to_string(cur.first) + " [" + std::to_string(static_cast<int>(cur.first)) +  "]", Psc::to_string(cur.second)});
        }
        ret.append({"DF子类型", df_sub_type});
        ret.append({"CPR统计信息", cpr_error_o});
        return ret;
    }

    void add_length_error(const std::string& key) {
        length_error_num++;
    }

    void add_cpr_error(SSR::CPR_Error_Type cet) {
        ++cpr_error[cet];
    }

    DF_Statistic_Data* get_create_df_statistic_data(const SSR::Downlink_Format& key) {
        DF_Statistic_Data* t;
        auto iter = DF_Statistic_Data_map.find(key);
        if (iter == DF_Statistic_Data_map.end())
        {
            DF_Statistic_Data cur{};
            DF_Statistic_Data_map.insert(std::make_pair(key, cur));
        }
        t = &DF_Statistic_Data_map[key];
        return t;
    }

    size_t get_total_pre_second_num() {
        size_t ret = 0;
        for (auto& cur : DF_Statistic_Data_map) {
            ret += cur.second.pre_second_num;
        }
        return ret;
    }

    size_t get_total_num() {
        size_t ret = 0;
        for (auto& cur : DF_Statistic_Data_map) {
            ret += cur.second.total_num;
        }
        return ret;
    }
    size_t get_crc_error_num() {
        size_t ret = 0;
        for (auto& cur : DF_Statistic_Data_map) {
            ret += cur.second.crc_error_num;
        }
        return ret;
    }


protected:
    std::atomic<size_t> length_error_num{};
    std::map<SSR::Downlink_Format, DF_Statistic_Data> DF_Statistic_Data_map;
    std::map<SSR::CPR_Error_Type, size_t> cpr_error;
};


template <typename T>
class Immutable : public T {

};

#endif
