namespace Sonex.Services.ImageSync;

using System.ComponentModel;
using System.Runtime.InteropServices;

internal sealed class NetworkShareConnection : IDisposable
{
    private const int ResourceTypeDisk = 0x00000001;
    private const int ConnectTemporary = 0x00000004;
    private const int ErrorSessionCredentialConflict = 1219;

    private readonly string _shareRoot;
    private readonly bool _disconnectOnDispose;

    private NetworkShareConnection(string shareRoot, bool disconnectOnDispose)
    {
        _shareRoot = shareRoot;
        _disconnectOnDispose = disconnectOnDispose;
    }

    public static NetworkShareConnection? ConnectIfNeeded(
        string sourceRoot,
        string userName,
        string password)
    {
        if (!sourceRoot.StartsWith(@"\\", StringComparison.Ordinal))
            return null;

        string shareRoot = GetShareRoot(sourceRoot);
        if (string.IsNullOrWhiteSpace(shareRoot))
            return null;

        if (string.IsNullOrWhiteSpace(userName))
            return null;

        var resource = new NetResource
        {
            Scope = 0,
            ResourceType = ResourceTypeDisk,
            DisplayType = 0,
            Usage = 0,
            LocalName = null,
            RemoteName = shareRoot,
            Comment = null,
            Provider = null
        };

        int result = WNetAddConnection2(ref resource, password, userName, ConnectTemporary);
        if (result == 0)
            return new NetworkShareConnection(shareRoot, disconnectOnDispose: true);

        if (result == ErrorSessionCredentialConflict && Directory.Exists(sourceRoot))
            return new NetworkShareConnection(shareRoot, disconnectOnDispose: false);

        throw new IOException(
            $"Cannot connect to network share '{shareRoot}'. {new Win32Exception(result).Message}",
            new Win32Exception(result));
    }

    public void Dispose()
    {
        if (!_disconnectOnDispose)
            return;

        try
        {
            WNetCancelConnection2(_shareRoot, 0, true);
        }
        catch
        {
        }
    }

    private static string GetShareRoot(string path)
    {
        string trimmed = path.TrimEnd('\\', '/');
        string[] parts = trimmed.Split('\\', StringSplitOptions.RemoveEmptyEntries);

        if (parts.Length < 2)
            return string.Empty;

        return $@"\\{parts[0]}\{parts[1]}";
    }

    [DllImport("mpr.dll", CharSet = CharSet.Unicode)]
    private static extern int WNetAddConnection2(
        ref NetResource netResource,
        string password,
        string username,
        int flags);

    [DllImport("mpr.dll", CharSet = CharSet.Unicode)]
    private static extern int WNetCancelConnection2(
        string name,
        int flags,
        bool force);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    private struct NetResource
    {
        public int Scope;
        public int ResourceType;
        public int DisplayType;
        public int Usage;
        public string? LocalName;
        public string? RemoteName;
        public string? Comment;
        public string? Provider;
    }
}
