using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using OneForMe.Services;

namespace OneForMe.Controllers;

[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
    private readonly ILdapService _ldapService;
    private readonly SignInManager<IdentityUser> _signInManager;
    private readonly UserManager<IdentityUser> _userManager;
    private readonly ILogger<AuthController> _logger;

    public AuthController(
        ILdapService ldapService,
        SignInManager<IdentityUser> signInManager,
        UserManager<IdentityUser> userManager,
        ILogger<AuthController> logger)
    {
        _ldapService = ldapService;
        _signInManager = signInManager;
        _userManager = userManager;
        _logger = logger;
    }

    /// <summary>
    /// Login user with LDAP credentials
    /// </summary>
    [HttpPost("login")]
    public async Task<IActionResult> Login([FromBody] LoginRequest request)
    {
        try
        {
            // Authenticate with LDAP
            var isAuthenticated = await _ldapService.AuthenticateAsync(request.Username, request.Password);
            
            if (!isAuthenticated)
            {
                _logger.LogWarning($"LDAP authentication failed for user {request.Username}");
                return Unauthorized(new { message = "Invalid username or password" });
            }

            // Get user details from LDAP
            var ldapUser = await _ldapService.GetUserAsync(request.Username);
            if (ldapUser == null)
            {
                _logger.LogWarning($"Could not retrieve LDAP user details for {request.Username}");
                return Unauthorized(new { message = "Could not retrieve user details" });
            }

            // Check if user exists in database, if not create them
            var user = await _userManager.FindByNameAsync(request.Username);
            if (user == null)
            {
                user = new IdentityUser
                {
                    UserName = request.Username,
                    Email = ldapUser.Email,
                    EmailConfirmed = true
                };
                var result = await _userManager.CreateAsync(user);
                if (!result.Succeeded)
                {
                    _logger.LogError($"Failed to create user {request.Username} in database");
                    return BadRequest(new { message = "Failed to create user account" });
                }
                _logger.LogInformation($"Created new user {request.Username} in database");
            }

            // Sign in the user
            await _signInManager.SignInAsync(user, false);
            _logger.LogInformation($"User {request.Username} signed in successfully");
            
            return Ok(new { message = "Login successful" });
        }
        catch (Exception ex)
        {
            _logger.LogError($"Login error: {ex.Message}");
            return StatusCode(500, new { message = "An error occurred during login" });
        }
    }

    /// <summary>
    /// Logout user
    /// </summary>
    [HttpPost("logout")]
    public async Task<IActionResult> Logout()
    {
        await _signInManager.SignOutAsync();
        _logger.LogInformation("User logged out");
        return Ok(new { message = "Logout successful" });
    }
}

public class LoginRequest
{
    public string Username { get; set; } = string.Empty;
    public string Password { get; set; } = string.Empty;
}