#pragma once
//robotics
#include <robotics/thread_pool.hpp>
#include <robotics/utils.hpp>
//local
#include "../xml/xml_context.hpp"
#include "nexus_net_network_v1.hpp"
#include "nexus_net_network_v2.hpp"
#include "http_network.hpp"
#include "../models/web_sync_request_info.h"
#include "../models/web_drop_request_v1_info.h"
#include "../models/web_stepping_request_v1_info.h"
#include "../models/web_supply_request_v1_info.h"

/**
 * @brief network 类用于管理和协调多种网络组件，支持网络服务的启动、停止、云端同步、授权处理及事件分发等功能。该类实现了单例模式，确保全局仅有一个 network 实例。
 */
class network : public v3::thread_pool<network> {
public:
	/**
	 * @brief 返回 network 类的单例实例指针。
	 * @return 指向唯一 network 实例的指针。
	 */
	static network* instance() {
		static network g_network;
		return &g_network;
	}
	/**
	 * @brief 析构函数，用于销毁 network 对象并在销毁前调用 stop() 方法。
	 */
	~network() {
		stop();
	}
	/**
	 * @brief 启动所有网络组件。
	 */
	void start() {
		nexus_net_v1_->start();
		nexus_net_v2_->start();
	}
	/**
	 * @brief 停止所有网络服务。
	 */
	void stop() {
		nexus_net_v1_->stop();
		nexus_net_v2_->stop();
	}
	/**
	 * @brief 执行同步授权操作的回调函数。
	 */
	std::vector<web_drop_config_info> sync_drop_request() {
		auto response = http_network_->request_drop();
		LOG_INFO << "msg:" << response.msg << " code:" << response.code << " count:" << response.count;
		if (response.data.empty()) {
			throw std::runtime_error("没有返回数据.");
		}
		return response.data;
	}
	/**
	 * @brief 根据指定的键发起通用请求，并返回结果数据列表。
	 * @param key 用于请求的键值。
	 * @return 包含请求结果的 web_general_config_info 对象的 std::vector。如果没有返回数据，则抛出 std::runtime_error 异常。
	 */
	std::vector<web_general_config_info> sync_general_request(int key) {
		auto response = http_network_->request_general(key);
		LOG_INFO << "msg:" << response.msg << " code:" << response.code << " count:" << response.count;
		if (response.data.empty()) {
			throw std::runtime_error("没有返回数据.");
		}
		return response.data;
	}
	/**
	 * @brief 同步请求正则表达式配置，并返回配置列表。
	 * @return 包含所有正则表达式配置信息的 std::vector<web_regex_config_info>。如果未返回数据，则抛出 std::runtime_error 异常。
	 */
	std::vector<web_regex_config_info> sync_regex_request() {
		auto response = http_network_->request_regex();
		LOG_INFO << "msg:" << response.msg << " code:" << response.code << " count:" << response.count;
		if (response.data.empty()) {
			throw std::runtime_error("没有返回数据.");
		}
		return response.data;
	}
	/**
	 * @brief 同步处理一个网络请求。
	 * @param data 包含请求相关信息的 web_sync_request_info 常量引用。
	 * @return 如果请求同步成功则返回 true，否则返回 false。
	 */
	bool sync_request(web_sync_request_info const&data) {
		auto value = http_network_->request_sync(data);
		LOG_INFO << (&value);
		return value.success;
	}
	/**
	 * @brief 云端拖放事件的委托对象，用于处理包含 web_drop_config_info 列表的事件。
	 */
	v3::delegates<std::vector<web_drop_config_info>const&>		cloud_drop_event;
	/**
	 * @brief 用于处理 cloud_general_event 事件的委托对象，传递常量引用的 web_general_config_info 向量。
	 */
	v3::delegates<std::vector<web_general_config_info> const&>	cloud_general_event;
	/**
	 * @brief 云正则事件的委托对象，用于处理包含 web_regex_config_info 配置信息的向量参数的事件。
	 */
	v3::delegates<std::vector<web_regex_config_info> const&>	cloud_regex_event;
	/**
	 * @brief 表示一个不带参数的事件委托对象。
	 */
	v3::delegates<double, int>									local_stepping_event;
	/**
	 * @brief 本地供应事件的委托对象，用于处理带有整数和常量字符串引用参数的事件回调。
	 */
	v3::delegates<int, std::string const&>						local_supply_event;
	/**
	 * @brief 表示一个可用于本地拖放事件的委托对象，接受两个整数和一个常量字符串引用作为参数。
	 */
	v3::delegates<int, int, std::string const&>					local_drop_event;
private:
	/**
	 * @brief network 构造函数，初始化网络相关组件并绑定事件处理函数。
	 */
	network() :
		v3::thread_pool<network>(3) {
		http_network_ = http_network::instance();
		nexus_net_v1_ = nexus_net_network_v1::instance();
		nexus_net_v2_ = nexus_net_network_v2::instance();

		nexus_net_v1_->authorized_event.bind(&network::on_authorized_v1, this);
		nexus_net_v2_->authorized_event.bind(&network::on_authorized_v2, this);

		nexus_net_v1_->bind("local_stepping", &network::on_local_stepping_v1_response, this);
		nexus_net_v1_->bind("local_supply", &network::on_local_supply_v1_response, this);
		nexus_net_v1_->bind("local_drop", &network::on_local_drop_v1_response, this);


		nexus_net_v2_->bind("cloud_drop", &network::on_cloud_drop_response, this);
		nexus_net_v2_->bind("cloud_general", &network::on_cloud_general_response, this);
		nexus_net_v2_->bind("cloud_regex", &network::on_cloud_regex_response, this);
		nexus_net_v2_->bind("local_stepping", &network::on_local_stepping_v2_response, this);
		nexus_net_v2_->bind("local_supply", &network::on_local_supply_v2_response, this);
		nexus_net_v2_->bind("local_drop", &network::on_local_drop_v2_response, this);
	}
private:
	/**
	 * @brief 处理云端响应后的回调函数。
	 * @param data 包含云端响应内容的字符串。
	 */
	void on_cloud_drop_response(std::string const& data) {
		REGISTER_ASYNC_FUNC(on_cloud_drop_response, data);
		try {
			web_response_info<web_drop_config_info> value;
			v3::json_convert::deserialize(data, value);
			cloud_drop_event(value.data);
		}
		catch (std::exception const& ec) {
			LOG_ERROR << ec;
		}
	}
	/**
	 * @brief 处理云端通用响应数据，并触发后续事件。
	 * @param data 从云端收到的响应数据。
	 */
	void on_cloud_general_response(std::string const& data) {
		REGISTER_ASYNC_FUNC(on_cloud_general_response, data);
		try {
			web_response_info<web_general_config_info> value;
			v3::json_convert::deserialize(data, value);
			cloud_general_event(value.data);
		}
		catch (std::exception const& ec) {
			LOG_ERROR << ec;
		}
	}
	/**
	 * @brief 处理云端正则表达式的响应数据。
	 * @param data 包含响应内容的字符串。
	 */
	void on_cloud_regex_response(std::string const& data) {
		REGISTER_ASYNC_FUNC(on_cloud_regex_response, data);
		try {
			web_response_info<web_regex_config_info> value;
			v3::json_convert::deserialize(data, value);
			cloud_regex_event(value.data);
		}
		catch (std::exception const& ec) {
			LOG_ERROR << ec;
		}
	}
	/**
	 * @brief 处理本地步进响应事件。
	 * @param speed 步进的速度值。
	 * @param lineNo 相关的代码行号。
	 */
	void on_local_stepping_v2_response(double speed,int lineNo) {
		REGISTER_ASYNC_FUNC(on_local_stepping_v2_response, speed, lineNo);
		local_stepping_event(speed, lineNo);
	}
	/**
	 * @brief 处理本地供应响应的回调函数。
	 * @param supply_no 供应编号，用于标识本地供应请求。
	 * @param waybill_no 运单号，表示相关的物流单号。
	 */
	void on_local_supply_v2_response(int supply_no, std::string const& waybill_no) {
		REGISTER_ASYNC_FUNC(on_local_supply_v2_response, supply_no, waybill_no);
		local_supply_event(supply_no, waybill_no);
	}
	/**
	 * @brief 处理本地投递响应的回调函数。
	 * @param lattice_no 格口编号，用于标识具体的格口。
	 * @param drop_type 投递类型，指示投递的方式或类型。
	 * @param waybill_no 运单号，表示相关包裹的唯一标识。
	 */
	void on_local_drop_v2_response(int lattice_no, int drop_type, std::string const& waybill_no) {
		REGISTER_ASYNC_FUNC(on_local_drop_v2_response, lattice_no, drop_type, waybill_no);
		local_drop_event(lattice_no, drop_type, waybill_no);
	}
	/**
	 * @brief 处理本地步进响应的回调函数。
	 * @param value 包含步进请求信息的 web_stepping_request_v1_info 对象。
	 */
	void on_local_stepping_v1_response(web_stepping_request_v1_info value) {
		REGISTER_ASYNC_FUNC(on_local_stepping_v1_response, value);
		local_stepping_event(value.speed, value.layer_no);
	}
	/**
	 * @brief 处理本地供应响应的回调函数。
	 * @param value 包含供应请求信息的 web_supply_request_v1_info 对象。
	 */
	void on_local_supply_v1_response(web_supply_request_v1_info value) {
		REGISTER_ASYNC_FUNC(on_local_supply_v1_response, value);
		local_supply_event(value.supply_no, value.waybill_no);
	}
	/**
	 * @brief 处理本地投递响应的回调函数。
	 * @param value 包含投递请求信息的 web_drop_request_v1_info 对象。
	 */
	void on_local_drop_v1_response(web_drop_request_v1_info value) {
		REGISTER_ASYNC_FUNC(on_local_drop_v1_response, value);
		local_drop_event(value.lattice_no, value.type, value.waybill_no);
	}
private:
	/**
	 * @brief 根据授权状态处理设备ID的设置。
	 * @param status 表示是否已授权的布尔值。
	 * @param parent_code 父设备的代码，用于设置设备ID。
	 * @param parent_name 父设备的名称。
	 */
	void on_authorized_v2(bool status, std::string const& parent_code, std::string const& parent_name) {
		if (status) {
			http_network_->set_device_id(parent_code);
			LOG_INFO << "分布式授权成功v2.";
		}
		else {
			LOG_ERROR << "分布式授权失败v2.";
		}
	}
	/**
	 * @brief 根据授权状态记录分布式授权v1的日志信息。
	 * @param status 授权状态。如果为 true，表示授权成功；如果为 false，表示授权失败。
	 */
	void on_authorized_v1(bool status) {
		if (status) {
			LOG_INFO << "分布式授权成功v1.";
		}
		else {
			LOG_ERROR << "分布式授权失败v1.";
		}
	}
private:
	http_network*			http_network_ = nullptr;
	nexus_net_network_v1*	nexus_net_v1_ = nullptr;
	nexus_net_network_v2*	nexus_net_v2_ = nullptr;
};