namespace YMhut.Box.Core.Tools;

public enum ReferenceToolRiskLevel
{
    None,
    Low,
    Medium,
    High
}

public enum BuiltinReferenceToolKind
{
    Information,
    Dialog,
    Command,
    SystemEntry,
    ExternalHelper
}

public sealed record ExternalToolVariant(
    string Name,
    string Path,
    string? Architecture);

public sealed record ExternalToolItem(
    string Id,
    string Name,
    string Description,
    string CategoryName,
    ToolCategory Category,
    string ToolDirectory,
    string LaunchPath,
    string RelativePath,
    string Extension,
    string? Publisher,
    string? Version,
    string? IconGlyph,
    string? IconPath,
    string? PrimaryArchitecture,
    IReadOnlyList<string> Tags,
    IReadOnlyList<ExternalToolVariant> Variants,
    ReferenceToolRiskLevel RiskLevel,
    bool RequiresAdministrator)
{
    public bool IsRisky => RiskLevel != ReferenceToolRiskLevel.None || RequiresAdministrator;
}

public sealed class ExternalToolModule(ExternalToolItem tool) : IToolModule
{
    public const string IdPrefix = "external:";

    public ExternalToolItem Tool { get; } = tool;

    public string Id => Tool.Id;

    public ToolMetadata Metadata { get; } = new(
        tool.Id,
        tool.Name,
        tool.Description,
        tool.Category,
        tool.Tags.Concat(["external", "tools", tool.CategoryName, tool.Extension]).Distinct(StringComparer.OrdinalIgnoreCase).ToArray(),
        true,
        string.IsNullOrWhiteSpace(tool.IconGlyph) ? "\uE8B7" : tool.IconGlyph);

    public object CreateViewModel() => new ToolModuleViewModel(Metadata);

    public static bool IsExternalToolId(string id) => id.StartsWith(IdPrefix, StringComparison.OrdinalIgnoreCase);
}

public sealed record BuiltinReferenceToolDefinition(
    string Id,
    string Name,
    string Description,
    ToolCategory Category,
    string Glyph,
    BuiltinReferenceToolKind Kind,
    ReferenceToolRiskLevel RiskLevel,
    IReadOnlyList<string> Keywords,
    string PrimaryAction,
    IReadOnlyList<string> SecondaryActions)
{
    public bool IsRisky => RiskLevel != ReferenceToolRiskLevel.None;
}

public sealed class BuiltinReferenceToolModule(BuiltinReferenceToolDefinition definition) : IToolModule
{
    public const string IdPrefix = "builtin:";

    public BuiltinReferenceToolDefinition Definition { get; } = definition;

    public string Id { get; } = $"{IdPrefix}{definition.Id}";

    public ToolMetadata Metadata { get; } = new(
        $"{IdPrefix}{definition.Id}",
        definition.Name,
        definition.Description,
        definition.Category,
        definition.Keywords.Concat(["builtin", "reference", "ymhut", definition.Id]).Distinct(StringComparer.OrdinalIgnoreCase).ToArray(),
        true,
        definition.Glyph);

    public object CreateViewModel() => new ToolModuleViewModel(Metadata);

    public static bool IsBuiltinToolId(string id) => id.StartsWith(IdPrefix, StringComparison.OrdinalIgnoreCase);
}

public sealed record ToolExecutionLogDetail(
    string ToolId,
    string Operation,
    string Result,
    long ElapsedMilliseconds,
    string? ErrorSummary = null,
    string? Detail = null);

public sealed record ReferenceToolExecutionResult(
    bool Success,
    bool Cancelled,
    bool RequiresConfirmation,
    string Message,
    string? Detail = null,
    string? OutputPath = null,
    int? ExitCode = null)
{
    public static ReferenceToolExecutionResult Ok(string message, string? detail = null, string? outputPath = null, int? exitCode = null)
        => new(true, false, false, message, detail, outputPath, exitCode);

    public static ReferenceToolExecutionResult Fail(string message, string? detail = null, int? exitCode = null)
        => new(false, false, false, message, detail, null, exitCode);

    public static ReferenceToolExecutionResult Cancel(string message, string? detail = null)
        => new(false, true, false, message, detail);

    public static ReferenceToolExecutionResult ConfirmationRequired(string message, string? detail = null)
        => new(false, false, true, message, detail);
}
