#pragma once

#include "Gallery_Enum.h"
#include "render_2D/scene/Scene.h"
#include "render_2D/renderable/Renderable.h"

#include "adminive/adminive.hpp"
#include "adminive/adapters/magic_enum.hpp"

#include <cstdint>
#include <stdexcept>
#include <string>

namespace renderive::web {

struct Gallery_Consumer_Feedback_Snapshot {
    bool master_enabled{};
    bool pixel_enabled{};
    bool presentation_enabled{};
    bool manual_enabled{};
    double manual_fps{};
    std::string source;
    std::uint64_t pixel_interval_ns{};
    std::uint64_t presentation_interval_ns{};
    std::uint64_t manual_interval_ns{};
};

struct Gallery_Render_Performance {
    std::uint64_t render_attempt_count{};
    std::uint64_t successful_render_count{};
    std::uint64_t failed_render_count{};
    double measured_fps{};
    double lifetime_average_fps{};
    double last_render_ms{};
    double average_render_ms{};
    double maximum_render_ms{};
    double render_deviation_ms{};
    double render_p50_ms{};
    double render_p95_ms{};
    double render_p99_ms{};
    std::uint64_t render_sample_count{};
    double pixel_response_fps{};
    double last_pixel_snapshot_ms{};
    double last_pixel_encode_ms{};
    double average_pixel_encode_ms{};
    double maximum_pixel_encode_ms{};
    double pixel_encode_deviation_ms{};
    double pixel_encode_p50_ms{};
    double pixel_encode_p95_ms{};
    double pixel_encode_p99_ms{};
    std::uint64_t pixel_encode_sample_count{};
    double last_pixel_request_ms{};
    double average_pixel_request_ms{};
    double pixel_request_deviation_ms{};
    double pixel_request_p95_ms{};
    double pixel_request_p99_ms{};
    std::uint64_t last_pixel_bytes{};
    double pixel_payload_megabytes_per_second{};
    bool automatic_low_latency_scheduler{};
};

struct Gallery_Client_Performance {
    double transport_fps{};
    double presentation_fps{};
    std::uint64_t websocket_buffered_bytes{};
    std::uint64_t changed_pixel_frames{};
    std::uint64_t duplicate_pixel_frames{};
    std::uint64_t frame_request_timeout_count{};
    double frame_round_trip_ms{};
    double frame_round_trip_average_ms{};
    double frame_round_trip_deviation_ms{};
    double frame_round_trip_p95_ms{};
    double frame_round_trip_p99_ms{};
    double display_interval_ms{};
    double display_interval_average_ms{};
    double display_interval_latest_ms{};
    double display_interval_p95_ms{};
    double display_interval_p99_ms{};
    double display_interval_deviation_ms{};
    std::uint64_t overwritten_pixel_frames{};
    double last_pixel_receive_age_ms{};
    double last_pixel_change_age_ms{};
};

} // namespace renderive::web

namespace adminive {

template <class Json>
struct Value_Adapter<renderive::Frame_Control_Mode, Json> {
    using value_type = std::string;

    static std::string read(renderive::Frame_Control_Mode value) {
        return renderive::web::gallery_enum_id(value);
    }
    static void write(renderive::Frame_Control_Mode& target, std::string value) {
        const auto parsed =
            renderive::web::gallery_enum_cast<renderive::Frame_Control_Mode>(value);
        if (!parsed)
            throw std::invalid_argument("unknown frame control mode: " + value);
        target = *parsed;
    }
};

template <>
struct Type_Descriptor<renderive::Frame_Observer_Snapshot> {
    static auto get() {
        using T = renderive::Frame_Observer_Snapshot;
        return object<T>("kernel_observer",
            ADMINIVE_FIELD_LABEL(T, mode, "模式")
                .enum_label<renderive::Frame_Control_Mode::Manual>("手动刷新")
                .enum_label<renderive::Frame_Control_Mode::Low_Latency>("低延迟")
                .enum_label<renderive::Frame_Control_Mode::Playback>("回放队列"),
            ADMINIVE_FIELD_LABEL(T, last_event, "最近事件"),
            ADMINIVE_FIELD_LABEL(T, limit_state, "当前瓶颈"),
            ADMINIVE_FIELD_LABEL(T, frequency_hz, "配置频率"),
            ADMINIVE_FIELD_LABEL(T, observation_count, "观察次数"),
            ADMINIVE_FIELD_LABEL(T, produced_frame_count, "发布"),
            ADMINIVE_FIELD_LABEL(T, consumed_frame_count, "完成"),
            ADMINIVE_FIELD_LABEL(T, dropped_frame_count, "丢弃"),
            ADMINIVE_FIELD_LABEL(T, failed_operation_count, "失败"),
            ADMINIVE_FIELD_LABEL(T, pending_frame_count, "待处理"),
            ADMINIVE_FIELD_LABEL(T, latest_sequence, "最新序号"),
            ADMINIVE_FIELD_LABEL(T, paint_duration_ns, "绘制事件耗时"),
            ADMINIVE_FIELD_LABEL(T, render_duration_ns, "后台渲染"),
            ADMINIVE_FIELD_LABEL(T, target_interval_ns, "目标间隔"),
            ADMINIVE_FIELD_LABEL(T, frequency_limit_enabled, "频率限制"),
            ADMINIVE_FIELD_LABEL(T, consumer_feedback_enabled, "内核反馈有效"),
            ADMINIVE_FIELD_LABEL(T, bottleneck_duration_ns, "内部瓶颈"),
            ADMINIVE_FIELD_LABEL(T, consumer_sample_interval_ns, "消费者原始采样"),
            ADMINIVE_FIELD_LABEL(T, consumer_smoothed_interval_ns, "消费者平滑周期"),
            ADMINIVE_FIELD_LABEL(T, consumer_variation_ns, "消费者抖动"),
            ADMINIVE_FIELD_LABEL(T, consumer_safety_interval_ns, "消费者安全期限"),
            ADMINIVE_FIELD_LABEL(T, consumer_interval_ns, "消费者限速周期"),
            ADMINIVE_FIELD_LABEL(T, next_refresh_interval_ns, "下次刷新"),
            ADMINIVE_FIELD_LABEL(T, paint_lease_wait_ns, "绘制租约等待"),
            ADMINIVE_FIELD_LABEL(T, paint_state_wait_ns, "绘制状态等待"),
            ADMINIVE_FIELD_LABEL(T, publish_state_wait_ns, "发布状态等待"),
            ADMINIVE_FIELD_LABEL(T, ready_wait_ns, "就绪等待"),
            ADMINIVE_FIELD_LABEL(T, frame_age_at_render_ns, "开始渲染时帧龄"),
            ADMINIVE_FIELD_LABEL(T, render_lease_wait_ns, "渲染租约等待"),
            ADMINIVE_FIELD_LABEL(T, render_state_wait_ns, "渲染状态等待"),
            ADMINIVE_FIELD_LABEL(T, render_finish_state_wait_ns, "渲染完成等待"),
            ADMINIVE_FIELD_LABEL(T, queue_wait_ns, "回放队列等待"),
            ADMINIVE_FIELD_LABEL(T, end_to_end_ns, "端到端延迟"))
            .label("内核观察器");
    }
};

template <>
struct Type_Descriptor<renderive::web::Gallery_Consumer_Feedback_Snapshot> {
    static auto get() {
        using T = renderive::web::Gallery_Consumer_Feedback_Snapshot;
        return object<T>("consumer_feedback",
            ADMINIVE_FIELD_LABEL(T, master_enabled, "消费者反馈总开关"),
            ADMINIVE_FIELD_LABEL(T, pixel_enabled, "像素响应反馈"),
            ADMINIVE_FIELD_LABEL(T, presentation_enabled, "浏览器呈现反馈"),
            ADMINIVE_FIELD_LABEL(T, manual_enabled, "手动消费者反馈"),
            ADMINIVE_FIELD_LABEL(T, manual_fps, "手动消费者 FPS"),
            ADMINIVE_FIELD_LABEL(T, source, "生效反馈来源"),
            ADMINIVE_FIELD_LABEL(T, pixel_interval_ns, "像素响应周期"),
            ADMINIVE_FIELD_LABEL(T, presentation_interval_ns, "浏览器呈现周期"),
            ADMINIVE_FIELD_LABEL(T, manual_interval_ns, "手动消费者周期"))
            .label("消费者反馈");
    }
};

template <>
struct Type_Descriptor<renderive::web::Gallery_Render_Performance> {
    static auto get() {
        using T = renderive::web::Gallery_Render_Performance;
        return object<T>("render_performance",
            ADMINIVE_FIELD_LABEL(T, render_attempt_count, "渲染尝试"),
            ADMINIVE_FIELD_LABEL(T, successful_render_count, "渲染成功"),
            ADMINIVE_FIELD_LABEL(T, failed_render_count, "渲染失败"),
            ADMINIVE_FIELD_LABEL(T, measured_fps, "最近渲染帧率"),
            ADMINIVE_FIELD_LABEL(T, lifetime_average_fps, "平均渲染帧率"),
            ADMINIVE_FIELD_LABEL(T, last_render_ms, "最近渲染耗时"),
            ADMINIVE_FIELD_LABEL(T, average_render_ms, "平均渲染耗时"),
            ADMINIVE_FIELD_LABEL(T, maximum_render_ms, "最大渲染耗时"),
            ADMINIVE_FIELD_LABEL(T, render_deviation_ms, "渲染标准差"),
            ADMINIVE_FIELD_LABEL(T, render_p50_ms, "渲染 P50"),
            ADMINIVE_FIELD_LABEL(T, render_p95_ms, "渲染 P95"),
            ADMINIVE_FIELD_LABEL(T, render_p99_ms, "渲染 P99"),
            ADMINIVE_FIELD_LABEL(T, render_sample_count, "渲染窗口样本"),
            ADMINIVE_FIELD_LABEL(T, pixel_response_fps, "像素响应帧率"),
            ADMINIVE_FIELD_LABEL(T, last_pixel_snapshot_ms, "最近像素快照耗时"),
            ADMINIVE_FIELD_LABEL(T, last_pixel_encode_ms, "最近像素编码耗时"),
            ADMINIVE_FIELD_LABEL(T, average_pixel_encode_ms, "平均像素编码耗时"),
            ADMINIVE_FIELD_LABEL(T, maximum_pixel_encode_ms, "最大像素编码耗时"),
            ADMINIVE_FIELD_LABEL(T, pixel_encode_deviation_ms, "像素编码标准差"),
            ADMINIVE_FIELD_LABEL(T, pixel_encode_p50_ms, "像素编码 P50"),
            ADMINIVE_FIELD_LABEL(T, pixel_encode_p95_ms, "像素编码 P95"),
            ADMINIVE_FIELD_LABEL(T, pixel_encode_p99_ms, "像素编码 P99"),
            ADMINIVE_FIELD_LABEL(T, pixel_encode_sample_count, "像素编码窗口样本"),
            ADMINIVE_FIELD_LABEL(T, last_pixel_request_ms, "最近像素请求耗时"),
            ADMINIVE_FIELD_LABEL(T, average_pixel_request_ms, "像素请求滑动平均"),
            ADMINIVE_FIELD_LABEL(T, pixel_request_deviation_ms, "像素请求标准差"),
            ADMINIVE_FIELD_LABEL(T, pixel_request_p95_ms, "像素请求 P95"),
            ADMINIVE_FIELD_LABEL(T, pixel_request_p99_ms, "像素请求 P99"),
            ADMINIVE_FIELD_LABEL(T, last_pixel_bytes, "最近像素负载"),
            ADMINIVE_FIELD_LABEL(T, pixel_payload_megabytes_per_second, "像素负载吞吐"),
            ADMINIVE_FIELD_LABEL(T, automatic_low_latency_scheduler, "自动低延迟调度"))
            .label("渲染性能");
    }
};

template <>
struct Type_Descriptor<renderive::web::Gallery_Client_Performance> {
    static auto get() {
        using T = renderive::web::Gallery_Client_Performance;
        return object<T>("client_performance",
            ADMINIVE_FIELD_LABEL(T, transport_fps, "像素响应帧率"),
            ADMINIVE_FIELD_LABEL(T, presentation_fps, "浏览器呈现帧率"),
            ADMINIVE_FIELD_LABEL(T, websocket_buffered_bytes, "WebSocket 缓冲"),
            ADMINIVE_FIELD_LABEL(T, changed_pixel_frames, "变化像素帧"),
            ADMINIVE_FIELD_LABEL(T, duplicate_pixel_frames, "重复像素帧"),
            ADMINIVE_FIELD_LABEL(T, frame_request_timeout_count, "像素请求超时"),
            ADMINIVE_FIELD_LABEL(T, frame_round_trip_ms, "WebSocket 往返耗时"),
            ADMINIVE_FIELD_LABEL(T, frame_round_trip_average_ms, "WebSocket 往返滑动平均"),
            ADMINIVE_FIELD_LABEL(T, frame_round_trip_deviation_ms, "WebSocket 往返标准差"),
            ADMINIVE_FIELD_LABEL(T, frame_round_trip_p95_ms, "WebSocket 往返 P95"),
            ADMINIVE_FIELD_LABEL(T, frame_round_trip_p99_ms, "WebSocket 往返 P99"),
            ADMINIVE_FIELD_LABEL(T, display_interval_ms, "呈现中位周期"),
            ADMINIVE_FIELD_LABEL(T, display_interval_average_ms, "呈现滑动平均周期"),
            ADMINIVE_FIELD_LABEL(T, display_interval_latest_ms, "最近呈现周期"),
            ADMINIVE_FIELD_LABEL(T, display_interval_p95_ms, "呈现 P95 周期"),
            ADMINIVE_FIELD_LABEL(T, display_interval_p99_ms, "呈现 P99 周期"),
            ADMINIVE_FIELD_LABEL(T, display_interval_deviation_ms, "呈现周期标准差"),
            ADMINIVE_FIELD_LABEL(T, overwritten_pixel_frames, "未呈现覆盖帧"),
            ADMINIVE_FIELD_LABEL(T, last_pixel_receive_age_ms, "最近像素龄"),
            ADMINIVE_FIELD_LABEL(T, last_pixel_change_age_ms, "最近变化龄"))
            .label("浏览器性能");
    }
};

template <>
struct Type_Descriptor<renderive::Renderable_Observation> {
    static auto get() {
        using T = renderive::Renderable_Observation;
        return object<T>("renderable_observer",
            ADMINIVE_FIELD_LABEL(T, event, "最近状态事件")
                .enum_label<renderive::Renderable_Observer_Event::None>("尚无事件")
                .enum_label<renderive::Renderable_Observer_Event::Cache_Updated>("缓存状态已更新")
                .enum_label<renderive::Renderable_Observer_Event::Published>("渲染状态已发布"),
            ADMINIVE_FIELD_LABEL(T, event_time_ns, "事件时间"),
            ADMINIVE_FIELD_LABEL(T, cache_update_count, "缓存更新次数"),
            ADMINIVE_FIELD_LABEL(T, publish_count, "状态发布次数"))
            .label("渲染对象观察器");
    }
};

static_assert(Described_Type<renderive::Frame_Observer_Snapshot>);
static_assert(Described_Type<renderive::web::Gallery_Consumer_Feedback_Snapshot>);
static_assert(Described_Type<renderive::web::Gallery_Render_Performance>);
static_assert(Described_Type<renderive::web::Gallery_Client_Performance>);
static_assert(Described_Type<renderive::Renderable_Observation>);

} // namespace adminive
