#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>

double percentile(const std::vector<double>& data, double p) {
    if (data.empty()) return NAN;
    double idx = p * (data.size() - 1);
    size_t i = static_cast<size_t>(idx);
    double frac = idx - i;
    return data[i] * (1.0 - frac) + data[std::min(i + 1, data.size() - 1)] * frac;
}

void rolling_cagr_stats_dca_correct(const std::vector<double>& returns, int duration) {
    size_t n = returns.size();
    if (n < duration) {
        std::cout << "Not enough data for the specified duration.\n";
        return;
    }

    std::vector<double> cagr_list;

    for (size_t start = 0; start <= n - duration; ++start) {
        double total_value = 0.0;

        for (int j = 0; j < duration; ++j) {
            double compounded = 1.0;
            for (int t = j; t < duration; ++t) {
                compounded *= (1.0 + returns[start + t]);
            }
            total_value += compounded;
        }

        double cagr = std::pow(total_value / duration, 1.0 / duration) - 1.0;
        cagr_list.push_back(cagr);
    }

    std::sort(cagr_list.begin(), cagr_list.end());

    auto percentile = [](const std::vector<double>& data, double p) {
        double idx = p * (data.size() - 1);
        size_t i = static_cast<size_t>(idx);
        double frac = idx - i;
        return data[i] * (1 - frac) + data[std::min(i + 1, data.size() - 1)] * frac;
    };

    double min_cagr = cagr_list.front();
    double max_cagr = cagr_list.back();
    double median_cagr = percentile(cagr_list, 0.50);
    double bottom_15 = percentile(cagr_list, 0.15);
    double top_15 = percentile(cagr_list, 0.85);

    std::cout << "=== DCA Mode (Corrected Logic) ===\n";
    std::cout << "Duration: " << duration << " years\n";
    std::cout << "Number of periods: " << cagr_list.size() << "\n";
    std::cout << "Min CAGR: " << std::fixed << std::setprecision(2) << min_cagr * 100 << "%\n";
    std::cout << "Bottom 15th percentile CAGR: " << bottom_15 * 100 << "%\n";
    std::cout << "Median CAGR: " << median_cagr * 100 << "%\n";
    std::cout << "Top 85th percentile CAGR: " << top_15 * 100 << "%\n";
    std::cout << "Max CAGR: " << max_cagr * 100 << "%\n";
}


int main() {
    std::vector<double> returns = {
        -0.04, 0.14, 0.15, -0.14, -0.19, 0.26, 0.28, 0.04, 0.08, 0.28,
        0.08, -0.06, 0.24, 0.22, -0.01, 0.26, 0.14, -0.02, 0.14, 0.16,
        -0.16, 0.29, 0.15, 0.18, -0.03, 0.20, 0.13, 0.20, 0.02, 0.08,
        -0.04, 0.04, -0.07, 0.33, 0.12, 0.06, 0.15, 0.01, -0.26, 0.31,
        0.22, -0.03, 0.15, 0.19, 0.08, -0.06, 0.16, 0.13, -0.11, 0.21,
        0.13, 0.12, -0.18, 0.15, 0.12
    };

    int duration = 18;
    rolling_cagr_stats_dca_correct(returns, duration);

    return 0;
}
