import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Character } from '../characters/entities/character.entity';
import { TravelService } from '../travel/travel.service';
import { LocationConnection } from './entities/location-connection.entity';

export interface LocationSummary {
  id: string;
  key: string;
  name: string;
}

export interface CurrentLocationConnection {
  targetLocation: LocationSummary;
  travelDurationSeconds: number;
  danger: 'LOW' | 'HIGH';
}

export interface CurrentLocationResponse {
  id: string;
  key: string;
  name: string;
  description: string;
  regionKey: string;
  minRecommendedLevel: number;
  maxRecommendedLevel: number;
  dangerLevel: number;
  isSafe: boolean;
  huntingEnabled: boolean;
  artworkPath: string;
  connections: CurrentLocationConnection[];
}

@Injectable()
export class WorldService {
  constructor(
    private readonly travelService: TravelService,
    @InjectRepository(Character)
    private readonly characters: Repository<Character>,
    @InjectRepository(LocationConnection)
    private readonly connections: Repository<LocationConnection>,
  ) {}

  async getCurrentLocation(
    characterId: string,
  ): Promise<CurrentLocationResponse> {
    await this.travelService.completeTravelIfDue(characterId);

    const character = await this.characters.findOne({
      where: { id: characterId },
      relations: { currentLocation: true },
    });
    if (!character) {
      throw new NotFoundException('Character not found.');
    }

    const connections = await this.connections.find({
      where: { fromLocationId: character.currentLocationId, enabled: true },
      relations: { toLocation: true },
    });
    const location = character.currentLocation;

    return {
      id: location.id,
      key: location.key,
      name: location.name,
      description: location.description,
      regionKey: location.regionKey,
      minRecommendedLevel: location.minRecommendedLevel,
      maxRecommendedLevel: location.maxRecommendedLevel,
      dangerLevel: location.dangerLevel,
      isSafe: location.isSafe,
      huntingEnabled: location.huntingEnabled,
      artworkPath: location.artworkPath,
      connections: connections
        .filter((connection) => connection.enabled)
        .map((connection) => ({
          targetLocation: {
            id: connection.toLocation.id,
            key: connection.toLocation.key,
            name: connection.toLocation.name,
          },
          travelDurationSeconds: connection.travelDurationSeconds,
          danger: this.toDangerRating(connection.ambushChance),
        })),
    };
  }

  private toDangerRating(ambushChance: string): 'LOW' | 'HIGH' {
    return Number(ambushChance) <= 0.05 ? 'LOW' : 'HIGH';
  }
}
