import type { SkillEntry, ValueScoreBreakdown } from "@capakraken/shared";

export interface ValueScoreInput {
  skills: SkillEntry[];
  lcrCents: number;
  chargeabilityTarget: number;
  currentChargeability: number; // actual % (computed from allocations by caller)
  maxLcrCents: number;          // org-wide max (for normalization)
}

export interface ValueScoreWeights {
  skillDepth: number;
  skillBreadth: number;
  costEfficiency: number;
  chargeability: number;
  experience: number;
}

/**
 * Computes a context-free value score (price/quality ratio) for a resource.
 * All dimensions are 0-100; total is a weighted composite clamped to 0-100.
 */
export function computeValueScore(
  input: ValueScoreInput,
  weights: ValueScoreWeights,
): ValueScoreBreakdown {
  const { skills, lcrCents, chargeabilityTarget, currentChargeability, maxLcrCents } = input;

  // 1. Skill Depth: avg proficiency normalized to 100
  let skillDepth = 0;
  if (skills.length > 0) {
    const avgProficiency = skills.reduce((sum, s) => sum + s.proficiency, 0) / skills.length;
    skillDepth = Math.round((avgProficiency / 5) * 100);
  }

  // 2. Skill Breadth: skill count capped at 10 skills → 100
  const skillBreadth = Math.min(100, skills.length * 10);

  // 3. Cost Efficiency: cheapest = 100; if all same LCR → 0 for all
  let costEfficiency = 0;
  if (maxLcrCents === 0) {
    costEfficiency = 100;
  } else {
    costEfficiency = Math.round((1 - lcrCents / maxLcrCents) * 100);
    costEfficiency = Math.max(0, Math.min(100, costEfficiency));
  }

  // 4. Chargeability: closer to target = higher; ±50pp gap = 0
  const chargeability = Math.max(
    0,
    100 - Math.abs(chargeabilityTarget - currentChargeability) * 2,
  );

  // 5. Experience: avg yearsExperience capped at 10yr → 100
  let experience = 0;
  const skillsWithYears = skills.filter((s) => (s.yearsExperience ?? 0) > 0);
  if (skillsWithYears.length > 0) {
    const avgYears = skillsWithYears.reduce((sum, s) => sum + (s.yearsExperience ?? 0), 0) / skillsWithYears.length;
    experience = Math.min(100, Math.round(avgYears * 10));
  }

  const total = Math.max(
    0,
    Math.min(
      100,
      Math.round(
        skillDepth * weights.skillDepth +
          skillBreadth * weights.skillBreadth +
          costEfficiency * weights.costEfficiency +
          chargeability * weights.chargeability +
          experience * weights.experience,
      ),
    ),
  );

  return {
    skillDepth,
    skillBreadth,
    costEfficiency,
    chargeability: Math.round(chargeability),
    experience,
    total,
  };
}
