import type { RiskAllocation, RiskBudget, SymbolRuntimeState } from "./types";

export interface AllocationOptions {
  minNotionalPerSymbol?: number;
  minBasePerSymbol?: number;
}

export class RiskAllocator {
  constructor(private readonly budget: RiskBudget, private readonly options: AllocationOptions = {}) {}

  allocate(states: SymbolRuntimeState[]): Map<string, RiskAllocation> {
    if (!states.length) {
      return new Map();
    }
    const activeStates = states.filter(s => s.status === "active" && (s.score ?? 0) > 0);
    if (!activeStates.length) {
      return new Map();
    }

    const scoreSum = activeStates.reduce((sum, state) => sum + (state.score ?? 0), 0);
    if (scoreSum <= 0) {
      return new Map();
    }

    const allocations = new Map<string, RiskAllocation>();
    for (const state of activeStates) {
      const score = state.score ?? 0;
      const ratio = score / scoreSum;

      let notionalLimit = ratio * this.budget.totalNotional;
      let baseLimit = ratio * this.budget.totalBase;

      if (this.options.minNotionalPerSymbol) {
        notionalLimit = Math.max(notionalLimit, this.options.minNotionalPerSymbol);
      }
      if (this.options.minBasePerSymbol) {
        baseLimit = Math.max(baseLimit, this.options.minBasePerSymbol);
      }

      notionalLimit = Math.min(notionalLimit, state.config.maxNotional);
      baseLimit = Math.min(baseLimit, state.config.maxBase);

      allocations.set(state.config.symbol, {
        notionalLimit,
        baseLimit
      });
    }
    return allocations;
  }
}
