const std = @import("std");
const Config = @import("../config.zig").Config;
const ws = @import("../net/ws/client.zig");
const colors = @import("colors.zig");

/// UserContext represents an authenticated user session
pub const UserContext = struct {
    name: []const u8,
    admin: bool,
    allocator: std.mem.Allocator,

    pub fn deinit(self: *UserContext) void {
        self.allocator.free(self.name);
    }
};

/// Authenticate user with the server using API key
pub fn authenticateUser(allocator: std.mem.Allocator, config: Config) !UserContext {
    const ws_url = try std.fmt.allocPrint(allocator, "ws://{s}:9101/ws", .{config.worker_host});
    defer allocator.free(ws_url);

    // Try to connect with the API key to validate it
    var client = ws.Client.connect(allocator, ws_url, config.api_key) catch |err| {
        switch (err) {
            error.ConnectionRefused => return error.ConnectionFailed,
            error.NetworkUnreachable => return error.ServerUnreachable,
            error.InvalidURL => return error.ConfigInvalid,
            else => return error.AuthenticationFailed,
        }
    };
    defer client.close();

    // For now, create a user context after successful authentication
    // In a real implementation, this would get user info from the server
    const user_name = try allocator.dupe(u8, "authenticated_user");
    return UserContext{
        .name = user_name,
        .admin = false,
        .allocator = allocator,
    };
}

/// Authenticate user and return context with connection
pub fn authenticateWithConnection(
    allocator: std.mem.Allocator,
    config: Config,
) !struct { UserContext, ws.Client } {
    const ws_url = try std.fmt.allocPrint(allocator, "ws://{s}:9101/ws", .{config.worker_host});
    defer allocator.free(ws_url);

    var client = ws.Client.connect(allocator, ws_url, config.api_key) catch |err| {
        switch (err) {
            error.ConnectionRefused => return error.ConnectionFailed,
            error.NetworkUnreachable => return error.ServerUnreachable,
            error.InvalidURL => return error.ConfigInvalid,
            else => return error.AuthenticationFailed,
        }
    };
    errdefer client.close();

    const user_name = try allocator.dupe(u8, "authenticated_user");
    const user_ctx = UserContext{
        .name = user_name,
        .admin = false,
        .allocator = allocator,
    };

    return .{ user_ctx, client };
}
