#include <cpr/api.h>
#include <cpr/cprtypes.h>
#include <cpr/response.h>
#include <iostream>
#include <cpr/cpr.h>
#include <nlohmann/json.hpp>
#include <vector>
#include <string>

#define API "https://www.dnd5eapi.co/api/rules"

typedef struct {
    std::string name;
    std::string url;
} Rule;

int main() {
    cpr::Url url = API;
    std::vector<Rule> rules;

    // Получаем список правил
    cpr::Response response = cpr::Get(url);
    if (response.status_code != 200) {
        std::cerr << "Ошибка: Невозможно получить данные из API. Код состояния: " << response.status_code << "\n";
        return -1;
    }

    nlohmann::json response_json = nlohmann::json::parse(response.text);
    for (const auto& item : response_json["results"]) {
        Rule rule;
        rule.name = item["name"];
        rule.url = item["url"];
        rules.push_back(rule);
    }

    bool exit_program = false;

    while (!exit_program) {
        std::cout << "\n=== Доступные правила ===\n";
        for (size_t i = 0; i < rules.size(); ++i) {
            std::cout << i + 1 << ". " << rules[i].name << "\n";
        }
        std::cout << "0. Выйти\n";

        int choice;
        std::cout << "\nВведите номер правила для просмотра или 0 для выхода: ";
        std::cin >> choice;

        if (choice == 0) {
            exit_program = true;
            continue;
        }

        if (choice < 1 || choice > rules.size()) {
            std::cerr << "Неверный выбор. Попробуйте снова.\n";
            continue;
        }

        Rule selected_rule = rules[choice - 1];
        std::string full_url = "https://www.dnd5eapi.co" + selected_rule.url;
        cpr::Response rule_response = cpr::Get(cpr::Url(full_url));

        if (rule_response.status_code != 200) {
            std::cerr << "Ошибка: Невозможно получить детали правила. Код состояния: " << rule_response.status_code << "\n";
            continue;
        }

        nlohmann::json rule_json = nlohmann::json::parse(rule_response.text);

        std::cout << "\n=== " << rule_json["name"] << " ===\n\n";
        std::cout << "Описание:\n" << rule_json["desc"] << "\n";

        if (rule_json.contains("subsections") && !rule_json["subsections"].empty()) {
            std::vector<std::string> subsection_urls;
            std::cout << "\nПодразделы:\n";
            for (size_t i = 0; i < rule_json["subsections"].size(); ++i) {
                const auto& subsection = rule_json["subsections"][i];
                std::cout << i + 1 << ". " << subsection["name"] << "\n";
                // Исправлено: явное преобразование к std::string
                subsection_urls.push_back("https://www.dnd5eapi.co" + subsection["url"].get<std::string>());
            }

            std::cout << "0. Вернуться назад\n";

            int subsection_choice;
            std::cout << "\nВведите номер подраздела для просмотра или 0 для возврата: ";
            std::cin >> subsection_choice;

            if (subsection_choice == 0) {
                continue;
            }

            if (subsection_choice < 1 || subsection_choice > subsection_urls.size()) {
                std::cerr << "Неверный выбор подраздела. Попробуйте снова.\n";
                continue;
            }

            std::string subsection_url = subsection_urls[subsection_choice - 1];
            cpr::Response subsection_response = cpr::Get(cpr::Url(subsection_url));

            if (subsection_response.status_code != 200) {
                std::cerr << "Ошибка: Невозможно получить детали подраздела. Код состояния: " << subsection_response.status_code << "\n";
                continue;
            }

            nlohmann::json subsection_json = nlohmann::json::parse(subsection_response.text);
            std::cout << "\n=== " << subsection_json["name"] << " ===\n\n";
            std::cout << "Описание:\n" << subsection_json["desc"].get<std::string>() << "\n";
        } else {
            std::cout << "У этого правила нет подразделов.\n";
        }
    }

    return 0;
}
