using System.Globalization;
using System.IO;
using NexusShell.Models;

namespace NexusShell.Services;

public sealed class NexusDiskService
{
    private static readonly CultureInfo DaDk = CultureInfo.GetCultureInfo("da-DK");

    public IReadOnlyList<NexusDiskVolumeInfo> GetVolumes()
    {
        var volumes = new List<NexusDiskVolumeInfo>();

        foreach (var drive in DriveInfo.GetDrives())
        {
            if (!drive.IsReady)
            {
                continue;
            }

            if (drive.DriveType is not (DriveType.Fixed or DriveType.Removable or DriveType.Network))
            {
                continue;
            }

            var totalGb = drive.TotalSize / (1024d * 1024 * 1024);
            var freeGb = drive.AvailableFreeSpace / (1024d * 1024 * 1024);
            var usedGb = Math.Max(0, totalGb - freeGb);
            var usedPercent = totalGb > 0 ? (int)Math.Clamp(usedGb * 100d / totalGb, 0, 100) : 0;
            var letter = drive.Name.TrimEnd('\\');
            var label = string.IsNullOrWhiteSpace(drive.VolumeLabel) ? letter : $"{drive.VolumeLabel} ({letter})";

            volumes.Add(new NexusDiskVolumeInfo
            {
                Name = label,
                FriendlyLabel = BuildFriendlyLabel(drive, letter),
                DriveLetter = letter,
                TotalGb = totalGb,
                UsedGb = usedGb,
                FreeGb = freeGb,
                UsedPercent = usedPercent,
                DriveType = FormatDriveType(drive.DriveType),
            });
        }

        return volumes
            .OrderByDescending(static v => v.DriveLetter.StartsWith("C", StringComparison.OrdinalIgnoreCase))
            .ThenBy(static v => v.DriveLetter, StringComparer.OrdinalIgnoreCase)
            .ToList();
    }

    public double GetPrimaryFreeGb()
    {
        var systemRoot = Path.GetPathRoot(Environment.SystemDirectory);
        var drive = !string.IsNullOrWhiteSpace(systemRoot)
            ? new DriveInfo(systemRoot)
            : DriveInfo.GetDrives().FirstOrDefault(static d => d is { IsReady: true, DriveType: DriveType.Fixed });

        return drive is { IsReady: true }
            ? drive.AvailableFreeSpace / (1024d * 1024 * 1024)
            : -1;
    }

    private static string BuildFriendlyLabel(DriveInfo drive, string letter)
    {
        if (!string.IsNullOrWhiteSpace(drive.VolumeLabel))
        {
            return $"{drive.VolumeLabel} — {letter}";
        }

        return drive.DriveType switch
        {
            DriveType.Removable => $"Flytbart drev — {letter}",
            DriveType.Network => $"Netværksdrev — {letter}",
            _ => $"Systemdisk — {letter}",
        };
    }

    private static string FormatDriveType(DriveType type) => type switch
    {
        DriveType.Fixed => "Fast disk",
        DriveType.Removable => "Flytbart",
        DriveType.Network => "Netværk",
        _ => type.ToString(),
    };

    public static string FormatGb(double gb) => $"{gb.ToString("0.#", DaDk)} GB";
}
