namespace PlotLine.Models;

public static class StoryMemoryEntityTypes
{
    public const string Character = "Character";
    public const string Location = "Location";
    public const string Asset = "Asset";
}

public static class StoryMemoryAppearancePreferences
{
    public const string ExplicitEvidenceOnly = "ExplicitEvidenceOnly";
    public const string Balanced = "Balanced";
    public const string PredominantlyLight = "PredominantlyLight";
    public const string PredominantlyMedium = "PredominantlyMedium";
    public const string PredominantlyDark = "PredominantlyDark";
    public const string CustomMix = "CustomMix";
}

public sealed class StoryMemoryCharacter
{
    public int StoryMemoryCharacterID { get; init; }
    public int ImportSessionID { get; init; }
    public int ProjectID { get; init; }
    public int BookID { get; init; }
    public string CanonicalIdentityKey { get; init; } = string.Empty;
    public string DisplayName { get; init; } = string.Empty;
    public string EntityContext { get; init; } = "Story";
    public string SourceSectionType { get; init; } = "Story";
    public bool IsNamed { get; init; }
    public bool IsGroupEntity { get; init; }
    public bool IsResolved { get; init; }
    public bool IsNarrator { get; init; }
    public bool IsPrimaryPOV { get; init; }
    public int Significance { get; init; }
    public int EvidenceVersion { get; init; }
    public int? CreatedSceneResultID { get; init; }
    public int? LastUpdatedSceneResultID { get; init; }
    public DateTime CreatedUtc { get; init; }
    public DateTime UpdatedUtc { get; init; }
}

public sealed record StoryMemoryCharacterSave(
    int ImportSessionID,
    int ProjectID,
    int BookID,
    string CanonicalIdentityKey,
    string DisplayName,
    string EntityContext,
    string SourceSectionType,
    bool IsNamed,
    bool IsGroupEntity,
    bool IsResolved,
    bool IsNarrator,
    bool IsPrimaryPOV,
    int Significance,
    int SceneResultID);

public sealed class StoryMemoryCharacterAttribute
{
    public int StoryMemoryCharacterAttributeID { get; init; }
    public int StoryMemoryCharacterID { get; init; }
    public string AttributeType { get; init; } = string.Empty;
    public string NormalisedValue { get; init; } = string.Empty;
    public decimal Confidence { get; init; }
    public bool IsExplicit { get; init; }
    public string? EvidenceSummary { get; init; }
    public int? SourceSceneResultID { get; init; }
}

public sealed class StoryMemoryLocation
{
    public int StoryMemoryLocationID { get; init; }
    public int ImportSessionID { get; init; }
    public int ProjectID { get; init; }
    public int BookID { get; init; }
    public string CanonicalIdentityKey { get; init; } = string.Empty;
    public string DisplayName { get; init; } = string.Empty;
    public string SemanticType { get; init; } = string.Empty;
    public string? Subtype { get; init; }
    public string? InteriorExterior { get; init; }
    public int? ParentLocationID { get; init; }
    public int? FirstSeenSceneResultID { get; init; }
    public int? LastSeenSceneResultID { get; init; }
}

public sealed record StoryMemoryLocationSave(
    int ImportSessionID,
    int ProjectID,
    int BookID,
    string CanonicalIdentityKey,
    string DisplayName,
    string SemanticType,
    string? Subtype,
    string? InteriorExterior,
    int SceneResultID);

public sealed class StoryMemoryAsset
{
    public int StoryMemoryAssetID { get; init; }
    public int ImportSessionID { get; init; }
    public int ProjectID { get; init; }
    public int BookID { get; init; }
    public string CanonicalIdentityKey { get; init; } = string.Empty;
    public string DisplayName { get; init; } = string.Empty;
    public string SemanticType { get; init; } = string.Empty;
    public string? Subtype { get; init; }
    public string? Colour { get; init; }
    public string? Era { get; init; }
    public int? FirstSeenSceneResultID { get; init; }
    public int? LastSeenSceneResultID { get; init; }
}

public sealed record StoryMemoryAssetSave(
    int ImportSessionID,
    int ProjectID,
    int BookID,
    string CanonicalIdentityKey,
    string DisplayName,
    string SemanticType,
    string? Subtype,
    string? Colour,
    string? Era,
    int SceneResultID);

public sealed class StoryMemoryIllustrationAssignment
{
    public int StoryMemoryIllustrationAssignmentID { get; init; }
    public int ImportSessionID { get; init; }
    public string EntityType { get; init; } = string.Empty;
    public int EntityID { get; init; }
    public int? IllustrationLibraryItemID { get; init; }
    public string? StableCode { get; init; }
    public string AssignmentStatus { get; init; } = string.Empty;
    public bool IsFallback { get; init; }
    public int MatchScore { get; init; }
    public decimal Confidence { get; init; }
    public string? AssignmentReason { get; init; }
    public string EvidenceVersion { get; init; } = "21S";
    public DateTime AssignedUtc { get; init; }
    public DateTime LastValidatedUtc { get; init; }
    public DateTime? InvalidatedUtc { get; init; }
    public string? InvalidationReason { get; init; }
}

public sealed record StoryMemoryIllustrationAssignmentSave(
    int ImportSessionID,
    string EntityType,
    int EntityID,
    int? IllustrationLibraryItemID,
    string? StableCode,
    string AssignmentStatus,
    bool IsFallback,
    int MatchScore,
    decimal Confidence,
    string AssignmentReason,
    string EvidenceVersion);

public sealed class StoryMemoryIllustrationDemand
{
    public int StoryMemoryIllustrationDemandID { get; init; }
    public int ImportSessionID { get; init; }
    public int ProjectID { get; init; }
    public string EntityType { get; init; } = string.Empty;
    public string ArchetypeKey { get; init; } = string.Empty;
    public int DemandCount { get; init; }
    public int WaitingEntityCount { get; init; }
    public string Status { get; init; } = string.Empty;
    public int? QueuedIllustrationLibraryItemID { get; init; }
    public int? GeneratedIllustrationLibraryItemID { get; init; }
}

public sealed record StoryMemoryIllustrationDemandSave(
    int ImportSessionID,
    int ProjectID,
    string EntityType,
    string ArchetypeKey,
    int WaitingEntityCount,
    string Status,
    int? QueuedIllustrationLibraryItemID,
    int? GeneratedIllustrationLibraryItemID);

public sealed class StoryMemoryDiagnostics
{
    public int ImportSessionID { get; init; }
    public int CharacterCount { get; init; }
    public int LocationCount { get; init; }
    public int AssetCount { get; init; }
    public int AliasCount { get; init; }
    public int AttributeCount { get; init; }
    public int RelationshipCount { get; init; }
    public int AssignmentCount { get; init; }
    public int FallbackCount { get; init; }
    public int DemandCount { get; init; }
    public int ProcessedSceneCount { get; init; }
    public int? LastProcessedSceneResultID { get; init; }
    public string AppearancePreference { get; init; } = StoryMemoryAppearancePreferences.Balanced;
}

public sealed class StoryMemoryRebuildResult
{
    public int ImportSessionID { get; init; }
    public bool DryRun { get; init; }
    public int SceneResultsRead { get; init; }
    public int SceneResultsProcessed { get; init; }
    public int CharactersDiscovered { get; init; }
    public int LocationsDiscovered { get; init; }
    public int AssetsDiscovered { get; init; }
    public int RelationshipsDiscovered { get; init; }
    public int AssignmentsCreatedOrValidated { get; init; }
    public int DemandsCreated { get; init; }
    public int FallbacksRemaining { get; init; }
    public int AiCalls { get; init; }
    public IReadOnlyList<string> Warnings { get; init; } = [];
}

public sealed record StoryMemoryRebuildOptions
{
    public bool DryRun { get; init; }
    public bool RebuildAll { get; init; }
    public bool QueueDemand { get; init; }
    public int? MaxDemandToQueue { get; init; }
    public string AppearancePreference { get; init; } = StoryMemoryAppearancePreferences.Balanced;
    public string PrimaryAgeGroup { get; init; } = string.Empty;
    public string StoryEra { get; init; } = string.Empty;
    public string StoryLocation { get; init; } = string.Empty;
}

public sealed record StoryMemoryResolveOptions
{
    public bool QueueDemand { get; init; }
    public int? MaxDemandToQueue { get; init; }
    public string AppearancePreference { get; init; } = StoryMemoryAppearancePreferences.Balanced;
    public string PrimaryAgeGroup { get; init; } = string.Empty;
    public string StoryEra { get; init; } = string.Empty;
    public string StoryLocation { get; init; } = string.Empty;
}

public sealed record StoryMemoryImportContext(
    string AppearancePreference,
    string PrimaryAgeGroup,
    string StoryEra,
    string StoryLocation);
