import { Injectable } from '@nestjs/common';
import { TraitScores } from '../ai/prompt-builder.service';

type ParticipantStat = {
  kills: number;
  deaths: number;
  assists: number;
  goldEarned: number;
  totalDamageToChampions: number;
  damageTaken: number;
  visionScore: number;
  wardsPlaced: number;
  wardsKilled: number;
  controlWardsBought: number;
  totalMinionsKilled: number;
  neutralMinionsKilled: number;
  killParticipation: unknown;
};

@Injectable()
export class GgtiScoreService {
  calculate(participants: ParticipantStat[]): TraitScores {
    if (participants.length === 0) {
      return this.emptyScores();
    }

    const avg = (pick: (item: ParticipantStat) => number) =>
      participants.reduce((sum, item) => sum + pick(item), 0) / participants.length;

    const kills = avg((p) => p.kills);
    const deaths = avg((p) => p.deaths);
    const assists = avg((p) => p.assists);
    const damage = avg((p) => p.totalDamageToChampions);
    const vision = avg((p) => p.visionScore);
    const wards = avg((p) => p.wardsPlaced + p.wardsKilled + p.controlWardsBought);
    const cs = avg((p) => p.totalMinionsKilled + p.neutralMinionsKilled);
    const kp = avg((p) =>
      typeof p.killParticipation === 'number' ? p.killParticipation * 100 : 50,
    );

    return {
      aggression: this.clamp(kills * 9 + assists * 3 + damage / 450),
      stability: this.clamp(100 - deaths * 13),
      roaming: this.clamp(kp * 0.65 + assists * 4),
      vision: this.clamp(vision * 2.2 + wards * 1.2),
      objective: this.clamp(kp * 0.5 + wards * 2),
      growth: this.clamp(cs / 2.8 + avg((p) => p.goldEarned) / 350),
      fightJoin: this.clamp(kp * 0.85 + assists * 2),
    };
  }

  resolveType(scores: TraitScores) {
    const entries = Object.entries(scores).sort((a, b) => b[1] - a[1]);
    const first = this.toType(entries[0][0], entries[0][1]);
    const second = this.toType(entries[1][0], entries[1][1]);
    return first === second ? first : `${first}-${second}`;
  }

  private toType(trait: string, score: number) {
    if (trait === 'roaming') return 'ROAM';
    if (trait === 'growth') return 'FARM';
    if (trait === 'objective' || trait === 'vision') return 'SHOT';
    if (trait === 'stability') return 'SAFE';
    if (trait === 'aggression' && score >= 80) return 'LIMIT';
    if (trait === 'aggression') return 'CARRY';
    if (trait === 'fightJoin') return 'BAIT';
    return 'CARRY';
  }

  private emptyScores(): TraitScores {
    return {
      aggression: 0,
      stability: 0,
      roaming: 0,
      vision: 0,
      objective: 0,
      growth: 0,
      fightJoin: 0,
    };
  }

  private clamp(value: number) {
    return Math.max(0, Math.min(100, Math.round(value)));
  }
}
