import { Injectable } from '@nestjs/common';
import { PrismaService } from '../database/prisma.service';
import { RiotAccountService } from '../riot/riot-account.service';
import { CreateDuoAnalysisDto } from './dto/create-duo-analysis.dto';

@Injectable()
export class DuoService {
  constructor(
    private readonly prisma: PrismaService,
    private readonly riotAccountService: RiotAccountService,
  ) {}

  async create(dto: CreateDuoAnalysisDto) {
    const [playerA, playerB] = await Promise.all([
      this.riotAccountService.findOrSyncAccount(dto.playerA),
      this.riotAccountService.findOrSyncAccount(dto.playerB),
    ]);

    const [accountA, accountB] = await Promise.all([
      this.prisma.riotAccount.findUniqueOrThrow({ where: { puuid: playerA.puuid } }),
      this.prisma.riotAccount.findUniqueOrThrow({ where: { puuid: playerB.puuid } }),
    ]);

    const [snapshotA, snapshotB] = await Promise.all([
      this.prisma.playerAnalysisSnapshot.findFirst({
        where: { riotAccountId: accountA.id },
        orderBy: { analyzedAt: 'desc' },
      }),
      this.prisma.playerAnalysisSnapshot.findFirst({
        where: { riotAccountId: accountB.id },
        orderBy: { analyzedAt: 'desc' },
      }),
    ]);

    const compatibilityScore = this.calculateCompatibility(snapshotA?.traitScores, snapshotB?.traitScores);
    const relationType = compatibilityScore >= 75 ? '강한 시너지 듀오' : '보완이 필요한 듀오';

    const result = await this.prisma.duoAnalysisResult.create({
      data: {
        playerAAccountId: accountA.id,
        playerBAccountId: accountB.id,
        playerASnapshotId: snapshotA?.id,
        playerBSnapshotId: snapshotB?.id,
        compatibilityScore,
        relationType,
        traitDiffJson: this.diff(snapshotA?.traitScores, snapshotB?.traitScores),
        aiSummary:
          compatibilityScore >= 75
            ? '교전 타이밍과 운영 성향이 잘 맞는 조합입니다.'
            : '서로의 강점을 맞추려면 교전 타이밍 합의가 필요합니다.',
      },
    });

    return {
      id: result.id,
      compatibilityScore: result.compatibilityScore,
      relationType: result.relationType,
      traitDiff: result.traitDiffJson,
      summary: result.aiSummary,
    };
  }

  private calculateCompatibility(a: unknown, b: unknown) {
    const diff = this.diff(a, b) as Record<string, number>;
    const avgDiff =
      Object.values(diff).reduce((sum, value) => sum + Math.abs(value), 0) /
      Math.max(Object.values(diff).length, 1);
    return Math.max(0, Math.min(100, Math.round(100 - avgDiff)));
  }

  private diff(a: unknown, b: unknown) {
    const left = this.asScores(a);
    const right = this.asScores(b);
    return Object.fromEntries(
      Object.keys(left).map((key) => [key, left[key] - right[key]]),
    );
  }

  private asScores(value: unknown): Record<string, number> {
    const fallback = {
      aggression: 50,
      stability: 50,
      roaming: 50,
      vision: 50,
      objective: 50,
      growth: 50,
      fightJoin: 50,
    };
    if (!value || typeof value !== 'object') return fallback;
    return { ...fallback, ...(value as Record<string, number>) };
  }
}
