// Oleg Petruny proprietary.

#include "AgeOfWarManager.h"

#include "Camera/CameraComponent.h"
#include "Components/ChildActorComponent.h"

#include "AgeOfWarUnit.h"
#include "MainGameModeBase.h"
#include "PlayerBase.h"

TMap<UClass*, FAgeOfWarUnitStats> AAgeOfWarManager::unitStats = {};

const FAgeOfWarUnitStats& AAgeOfWarManager::UnitGetStats(TSubclassOf<AAgeOfWarUnit> unitClass)
{
    check(unitStats.Contains(*unitClass));
    //if(!unitStats.Contains(*unitClass))
    //{
    //    static FAgeOfWarUnitStats empty;
    //    return empty;
    //}

    return unitStats[unitClass];
}

AAgeOfWarManager::AAgeOfWarManager()
{
    auto root = CreateDefaultSubobject<USceneComponent>(TEXT("Scene"));

    camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
    camera->SetupAttachment(root);
}

void AAgeOfWarManager::Start(APlayerBase* playerPawn, FMinigameEndCallback delegate)
{
    if(!playerPawn)
        return;

    AMinigame::Start(playerPawn, delegate);

    player->LockPlayer(FPlayerLock::All());
    player->SwitchToView(this);

    FillUnitStats();
    TArray<UChildActorComponent*> units;
    GetComponents<UChildActorComponent>(units);
    for(auto& unit : units)
    {
        if(auto proxy = Cast<AAgeOfWarUnit>(unit->GetChildActor()))
        {
            proxy->manager = this;
            proxy->UpdateStats();
        }
    }
}

void AAgeOfWarManager::End()
{
    for(auto& unit : spawnedUnits)
        unit->Destroy();
    spawnedUnits.Empty();

    unitStats.Empty();

    player->ReturnPlayerView();
    player->UnlockPlayer(FPlayerLock::All());

    AMinigame::End();
}

void AAgeOfWarManager::UnitKill(AAgeOfWarUnit* unit)
{
    OnUnitKill(unit);
    spawnedUnits.Remove(unit);
}

void AAgeOfWarManager::AddUnitStats(TSubclassOf<AAgeOfWarUnit> unitClass, FAgeOfWarUnitStats stats)
{
    unitStats.Add(unitClass, stats);
}

FAgeOfWarUnitStats AAgeOfWarManager::GetUnitStats(TSubclassOf<AAgeOfWarUnit> unitClass)
{
    return UnitGetStats(unitClass);
}

void AAgeOfWarManager::SpawnUnit(TSubclassOf<AAgeOfWarUnit> unitClass, FTransform transform, bool computer)
{
    FActorSpawnParameters spawnParams{};
    spawnParams.Owner = this;
    auto unit = GetWorld()->SpawnActor<AAgeOfWarUnit>(*unitClass, transform, spawnParams);
    unit->team = computer ? UnitTeam::AI : UnitTeam::Player;
    unit->manager = this;
    unit->UpdateStats();
    spawnedUnits.Add(unit);
}
