namespace RpgRoller.Domain;

public enum RulesetKind
{
    D6,
    Dnd5e,
    Rolemaster
}

public enum RollVisibility
{
    Public,
    Private
}

public sealed class UserAccount
{
    public required Guid Id { get; init; }
    public required string Username { get; init; }
    public required string UsernameNormalized { get; init; }
    public required string PasswordHash { get; set; }
    public required string DisplayName { get; set; }
    public required string Roles { get; set; }
    public Guid? ActiveCharacterId { get; set; }
}

public static class UserRoles
{
    public const string Admin = "admin";
}

public sealed class UserSession
{
    public required string Token { get; init; }
    public required Guid UserId { get; init; }
    public required DateTimeOffset CreatedAtUtc { get; init; }
}

public sealed class Campaign
{
    public required Guid Id { get; init; }
    public required Guid GmUserId { get; init; }
    public required string Name { get; set; }
    public required RulesetKind Ruleset { get; set; }
    public long Version { get; set; }
}

public sealed class Character
{
    public required Guid Id { get; init; }
    public required Guid OwnerUserId { get; set; }
    public Guid? CampaignId { get; set; }
    public required string Name { get; set; }
}

public sealed class SkillGroup
{
    public required Guid Id { get; init; }
    public required Guid CharacterId { get; set; }
    public required string Name { get; set; }
    public required string DiceRollDefinition { get; set; }
    public required int WildDice { get; set; }
    public required bool AllowFumble { get; set; }
    public int? FumbleRange { get; set; }
}

public sealed class Skill
{
    public required Guid Id { get; init; }
    public required Guid CharacterId { get; set; }
    public Guid? SkillGroupId { get; set; }
    public required string Name { get; set; }
    public required string DiceRollDefinition { get; set; }
    public required int WildDice { get; set; }
    public required bool AllowFumble { get; set; }
    public int? FumbleRange { get; set; }
    public bool RolemasterAutoRetry { get; set; }
}

public sealed class RollLogEntry
{
    public required Guid Id { get; init; }
    public required Guid CampaignId { get; init; }
    public required Guid CharacterId { get; init; }
    public required Guid SkillId { get; init; }
    public required Guid RollerUserId { get; init; }
    public required RollVisibility Visibility { get; init; }
    public required int Result { get; init; }
    public required string Breakdown { get; init; }
    public required string Dice { get; init; }
    public required DateTimeOffset TimestampUtc { get; init; }
}

public enum DiceExpressionKind
{
    Standard,
    RolemasterOpenEndedPercentile
}

public sealed record DiceExpression(int DiceCount, int Sides, int Modifier, string Canonical, DiceExpressionKind Kind = DiceExpressionKind.Standard);