#include "HyperTwistDrillManager.h"
#include "DrillTypes.h"
#include "Misc/Paths.h"
#include "Serialization/JsonSerializer.h"
#include "Serialization/JsonObjectConverter.h"
#include "HAL/PlatformFileManager.h"
#include "Misc/FileHelper.h"

void UHyperTwistDrillManager::Initialize(FSubsystemCollectionBase& Collection)
{
    Super::Initialize(Collection);
    CurrentState = EDrillState::Idle;
    CurrentCaseIndex = -1;
    LoadUserData();
}

void UHyperTwistDrillManager::Deinitialize()
{
    SaveUserData();
    Super::Deinitialize();
}

FString GetSaveFilePath()
{
    return FPaths::ProjectSavedDir() + TEXT("DrillUserData.json");
}

void UHyperTwistDrillManager::LoadUserData()
{
    FString FilePath = GetSaveFilePath();
    FString JsonString;

    if (FFileHelper::LoadFileToString(JsonString, *FilePath))
    {
        FJsonObjectConverter::JsonObjectStringToUStruct(JsonString, &UserData, 0, 0);
    }
}

void UHyperTwistDrillManager::SaveUserData()
{
    FString JsonString;
    if (FJsonObjectConverter::UStructToJsonObjectString(UserData, JsonString))
    {
        FFileHelper::SaveStringToFile(JsonString, *GetSaveFilePath());
    }
}

void UHyperTwistDrillManager::SetState(EDrillState NewState)
{
    if (CurrentState != NewState)
    {
        CurrentState = NewState;
        OnDrillStateChanged.Broadcast(CurrentState);
    }
}

void UHyperTwistDrillManager::StartDrill(UHyperTwistDrillAsset* DrillAsset)
{
    if (!DrillAsset || DrillAsset->DrillCases.Num() == 0)
    {
        return;
    }

    ActiveDrillQueue = DrillAsset->DrillCases;
    CurrentCaseIndex = 0;

    OnNewDrillCase.Broadcast(ActiveDrillQueue[CurrentCaseIndex]);
    SetState(EDrillState::Presenting);
}

void UHyperTwistDrillManager::Next()
{
    if (CurrentState == EDrillState::Idle || ActiveDrillQueue.Num() == 0)
    {
        return;
    }

    CurrentCaseIndex++;
    if (ActiveDrillQueue.IsValidIndex(CurrentCaseIndex))
    {
        OnNewDrillCase.Broadcast(ActiveDrillQueue[CurrentCaseIndex]);
        SetState(EDrillState::Presenting);
    }
    else
    {
        // Drill finished
        CurrentCaseIndex = -1;
        ActiveDrillQueue.Empty();
        SetState(EDrillState::Idle);
    }
}

void UHyperTwistDrillManager::ShowSolution()
{
    if (CurrentState == EDrillState::Presenting || CurrentState == EDrillState::AwaitingInput)
    {
        SetState(EDrillState::ShowingSolution);
    }
}

void UHyperTwistDrillManager::AddCurrentCaseToFavorites()
{
    if (ActiveDrillQueue.IsValidIndex(CurrentCaseIndex))
    {
        const FString& caseId = ActiveDrillQueue[CurrentCaseIndex].InitialState;
        UserData.FavoriteCases.AddUnique(caseId);
        SaveUserData();
    }
}
