package com.huangzj.base.spring.module;

import com.huangzj.base.module.GeneralModule;
import com.huangzj.base.module.ModuleMetricsProvider;
import com.huangzj.base.module.PlayerModule;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * 把容器里所有 {@link GeneralModule} 捞出来排个序，统一 tick、save，顺便给 HTTP 一个快照。
 */
@Component
public class PlayerModuleRegistry implements ApplicationContextAware {

    /** 排好序的模块列表，只在容器刷新时重建。 */
    private List<GeneralModule<?>> modules = List.of();

    /**
     * Spring 回调：收集所有 GeneralModule Bean，按 {@link PlayerModule#order()} 从小到大排。
     */
    @Override
    @SuppressWarnings({"rawtypes", "unchecked"})
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, GeneralModule> raw = applicationContext.getBeansOfType(GeneralModule.class);
        List<GeneralModule<?>> list = new ArrayList<>();
        for (GeneralModule m : raw.values()) {
            list.add(m);
        }
        list.sort(Comparator.comparingInt(this::orderOf));
        modules = List.copyOf(list);
    }

    /** 没标注解就当 0，和别的模块挤在一起。 */
    private int orderOf(GeneralModule<?> module) {
        PlayerModule ann = module.getClass().getAnnotation(PlayerModule.class);
        return ann == null ? 0 : ann.order();
    }

    /** 当前快照，一般给调试或管理接口。 */
    public List<GeneralModule<?>> all() {
        return modules;
    }

    /** 对所有「开了 tick」的模块跑一遍。 */
    public void runTickAll(long runAt) {
        for (GeneralModule<?> module : modules) {
            if (module.isEnableTick()) {
                module.runTick(runAt);
            }
        }
    }

    /** 依次存盘，谁失败谁自己处理，这里不中断链路。 */
    public void saveAll() {
        for (GeneralModule<?> module : modules) {
            module.saveData();
        }
    }

    /**
     * 拼一份给人看的列表：类名、顺序、是否 tick，外加实现了 {@link ModuleMetricsProvider} 的指标。
     */
    public List<Map<String, Object>> describeModules() {
        List<Map<String, Object>> rows = new ArrayList<>();
        for (GeneralModule<?> module : modules) {
            Map<String, Object> row = new LinkedHashMap<>();
            row.put("class", module.getClass().getSimpleName());
            PlayerModule ann = module.getClass().getAnnotation(PlayerModule.class);
            row.put("order", ann == null ? 0 : ann.order());
            row.put("enableTick", module.isEnableTick());
            if (module instanceof ModuleMetricsProvider provider) {
                row.putAll(provider.metrics());
            }
            rows.add(row);
        }
        return rows;
    }
}
