namespace EEMSServerCore.Managers;

internal class DeviceManager(SqlSugarCustom orm)
{
    private readonly ConcurrentDictionary<string, DeviceInfo> DevicesFromConnectionID = [];
    private readonly ConcurrentDictionary<Guid, DeviceInfo> DevicesFromGuid = [];
    private readonly ConcurrentDictionary<Guid, string> deviceConnectionID = [];

    public bool Initialize()
    {
        if (!orm.Query("Devices", out List<DeviceInfo>? devices) || devices is null)
            return false;
        foreach (var item in devices)
        {
            if (!item.Guid.HasValue)
                continue;

            this.LoginDevice(item, out _);
        }
        return true;
    }

    public bool LoginDevice(string connectionID, DeviceInfo deviceInfo, ISingleClientProxy singleClient, out bool isNewDevice)
    {
        isNewDevice = false;
        if (!deviceInfo.Guid.HasValue)
            return false;

        if (!orm.InsertOrUpdate(EEMSCenterConfig.DeviceTableName, deviceInfo, t => Guid.Equals(t.Guid, deviceInfo.Guid), out isNewDevice))
            return false;

        DevicesFromGuid[deviceInfo.Guid.Value] = deviceInfo;
        DevicesFromConnectionID[connectionID] = deviceInfo;
        ClientManager.DeviceClients[deviceInfo.Guid.Value] = singleClient;
        return true;
    }

    public bool LoginDevice(DeviceInfo deviceInfo, out bool isNewDevice)
    {
        isNewDevice = false;
        if (!deviceInfo.Guid.HasValue)
            return false;
        DevicesFromGuid[deviceInfo.Guid.Value] = deviceInfo;

        return orm.InsertOrUpdate(EEMSCenterConfig.DeviceTableName, deviceInfo, t => t.Guid == deviceInfo.Guid, out isNewDevice);
    }

    public bool RemoveDevice(string connectionID, out DeviceInfo? device)
    {
        DevicesFromConnectionID.TryRemove(connectionID, out device);
        if (device is null || !device.Guid.HasValue)
            return false;
        Guid guid = device.Guid.Value;
        DevicesFromGuid.TryRemove(guid, out device);

        return orm.Delete<DeviceInfo>("Devices", t => t.Guid == guid);
    }

    public bool RemoveDevice(Guid guid, out DeviceInfo? device)
    {
        if (!DevicesFromGuid.TryRemove(guid, out device) || device is null)
            return false;

        if (!deviceConnectionID.TryRemove(guid, out string? connectionID) || string.IsNullOrEmpty(connectionID))
            return false;

        DevicesFromConnectionID.TryRemove(connectionID, out _);
        return orm.Delete<DeviceInfo>("Devices", t => t.Guid == guid);
    }

    public bool TryGetDevice(string connectionID, out DeviceInfo? device)
    {
        device = default;
        if (string.IsNullOrEmpty(connectionID))
            return false;

        return DevicesFromConnectionID.TryGetValue(connectionID, out device);
    }

    public bool TryGetDevice(Guid guid, out DeviceInfo? device)
    {
        return DevicesFromGuid.TryGetValue(guid, out device);
    }

    public bool GetDeviceList(out Dictionary<Guid, DeviceInfo>? devices)
    {
        devices = this.DevicesFromGuid.ToDictionary();
        return true;
    }

}
