//======================================================================================================
// Company Name:       MotionTechnologies.inc
// Copyright Year:     2025
// File:               MoABoneNameMappings.h
//======================================================================================================

#pragma once

#include "CoreMinimal.h"

struct MOALIVELINK_API FMoABoneHierarchyInfo
{
    FString BoneName;
    FString ExpectedParent;
    TArray<FString> ExpectedChildren;

    FMoABoneHierarchyInfo() = default;
    FMoABoneHierarchyInfo(const FString& InName, const FString& InParent, const TArray<FString>& InChildren = TArray<FString>())
        : BoneName(InName), ExpectedParent(InParent), ExpectedChildren(InChildren) {}
};

struct MOALIVELINK_API FMoAHierarchyValidationResult
{
    bool bIsValid = true;
    float ConfidenceScore = 1.0f;
    FString ErrorMessage;

    FMoAHierarchyValidationResult() = default;
    FMoAHierarchyValidationResult(bool bValid, float Score, const FString& Msg = TEXT(""))
        : bIsValid(bValid), ConfidenceScore(Score), ErrorMessage(Msg) {}
};

class MOALIVELINK_API FMoABoneNameMappings
{
public:
    static TArray<FString> GenerateVariations(const FString& BoneName);
    static const TMap<FString, TArray<FString>>& GetCommonMappings();
    static FString NormalizeBoneName(const FString& BoneName);
    static const TMap<FString, FMoABoneHierarchyInfo>& GetExpectedBoneHierarchy();
    static FMoAHierarchyValidationResult ValidateBoneHierarchy(
        const FString& SourceBoneName,
        const FString& CandidateTargetBone,
        const TMap<FName, FName>& TargetBoneParentMap,
        const TMap<FString, FString>& CurrentMappings);
    static TArray<TPair<FString, float>> RankCandidatesByHierarchy(
        const FString& SourceBoneName,
        const TArray<FString>& CandidateTargetBones,
        const TMap<FName, FName>& TargetBoneParentMap,
        const TMap<FString, FString>& CurrentMappings);
    static bool AreBonesMutuallyExclusive(const FString& SourceBone1, const FString& SourceBone2);
};

