#pragma once

#include <desc/distribution/MaxEntFactor.hxx>
#include <elisa/Binomial.hxx>
#include <elisa/FWER.hxx>

namespace sd::disc
{

// #if HAS_FOUND_REAPER_HEADER
// template <typename Trait, typename Candidate>
// auto elisa_heuristic_scaled(const Component<Trait>& c,
//                             const Candidate&        x,
//                             const Config&           cfg,
//                             size_t                  layer)
// {
//     auto h = elisa_heuristic(c, x, cfg, layer);
//     return h > 0 ? h * usage_of_new_factor(x.pattern, c.data, c.model, x.row_ids) : h;
// }

// template <typename Trait, typename Candidate>
// auto elisa_heuristic_scaled(const Composition<Trait>& c,
//                             const Candidate&          x,
//                             const Config&             cfg,
//                             size_t                    layer)
// {
//     using float_type = typename Trait::float_type;

//     auto k  = c.data.num_components();
//     auto th = lg_fwer_geo<float_type>(cfg.alpha / k, layer, c.data.dim);

//     thread_local itemset<typename Trait::pattern_type> rows;

//     float_type acc = 0;
//     for (size_t i = 0; i < k; ++i)
//     {
//         rows.clear();
//         intersection(x.row_ids, c.masks[i], rows);

//         auto n_i = c.data.subset(i).size();
//         auto q   = static_cast<float_type>(count(rows)) / n_i;
//         auto p   = c.models[i].expectation(x.pattern);
//         auto h   = binomial_test(p, q, n_i, th);

//         if (h > 0)
//         {
//             auto u = usage_of_new_factor(x.pattern, c.data, c.models[i], rows);
//             acc    = std::max<float_type>(h * u, acc);
//         }
//     }

//     return acc;
// }
// // #undef HAS_FOUND_REAPER_HEADER
// #endif
// template<typename Trait>
// void retest_summary_compl(Component<Trait>& c, const Config& cfg))
// {
//     while(true) {
//         auto conf = summary_confidence_compl(c, cfg, [](auto&& pr, const auto& q, const auto&
//         x, size_t i) {
//             auto n_i = c.data.subset(i).size();
//             auto p   = c.models[i].expectation(x);
//             return binomial_test(p, q, n_i, th) - th;
//         });

//         auto rank = rank_confidence(conf);
//         bool has_removed = false;

//         for (size_t i = 0; i < rank.length(); ++i)
//         {
//             if(rank[i].second <= 0 && !is_singleton(c.summary.point(rank[i].first)))
//             {
//                 // remove
//                 c.summay.erase(co.summary.begin() + rank[i].first);

//                 has_removed = true;
//                 break;
//             }
//         }

//         if(!has_removed) {
//             break;
//         }
//     }
// }

} // namespace sd::disc