using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using TaxBaik.Web.Services;

namespace TaxBaik.Web.Controllers;

[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
    private readonly AuthService _authService;

    public AuthController(AuthService authService)
    {
        _authService = authService;
    }

    [HttpPost("login")]
    public async Task<IActionResult> Login([FromBody] LoginRequest request)
    {
        if (string.IsNullOrWhiteSpace(request.Username) || string.IsNullOrWhiteSpace(request.Password))
            return BadRequest(new ProblemDetails { Title = "로그인 정보가 필요합니다.", Status = StatusCodes.Status400BadRequest });

        var tokenPair = await _authService.AuthenticateAndGenerateTokenPairAsync(request.Username, request.Password);
        if (tokenPair == null)
            return Unauthorized(new ProblemDetails { Title = "아이디 또는 비밀번호가 올바르지 않습니다.", Status = StatusCodes.Status401Unauthorized });

        return Ok(new
        {
            token = tokenPair.AccessToken,
            accessToken = tokenPair.AccessToken,
            refreshToken = tokenPair.RefreshToken,
            expiresIn = tokenPair.ExpiresIn
        });
    }

    [HttpPost("refresh")]
    public async Task<IActionResult> Refresh([FromBody] RefreshTokenRequest request)
    {
        if (string.IsNullOrWhiteSpace(request.RefreshToken))
            return BadRequest(new ProblemDetails { Title = "Refresh token이 필요합니다.", Status = StatusCodes.Status400BadRequest });

        var tokenPair = await _authService.RefreshAccessTokenAsync(request.RefreshToken);
        if (tokenPair == null)
            return Unauthorized(new ProblemDetails { Title = "Refresh token이 유효하지 않습니다.", Status = StatusCodes.Status401Unauthorized });

        return Ok(new
        {
            token = tokenPair.AccessToken,
            accessToken = tokenPair.AccessToken,
            refreshToken = tokenPair.RefreshToken,
            expiresIn = tokenPair.ExpiresIn
        });
    }

    [HttpPost("change-password")]
    [Microsoft.AspNetCore.Authorization.Authorize]
    public async Task<IActionResult> ChangePassword([FromBody] ChangePasswordRequest request)
    {
        var username = User.FindFirstValue(ClaimTypes.Name);
        if (string.IsNullOrWhiteSpace(username))
            return Unauthorized(new ProblemDetails { Title = "인증 정보가 올바르지 않습니다.", Status = StatusCodes.Status401Unauthorized });

        try
        {
            var changed = await _authService.ChangePasswordAsync(username, request.CurrentPassword, request.NewPassword);
            if (!changed)
                return Unauthorized(new ProblemDetails { Title = "현재 비밀번호가 올바르지 않습니다.", Status = StatusCodes.Status401Unauthorized });

            return Ok(new { message = "비밀번호가 변경되었습니다." });
        }
        catch (ArgumentException ex)
        {
            return BadRequest(new ProblemDetails { Title = ex.Message, Status = StatusCodes.Status400BadRequest });
        }
    }

    [HttpPost("reset-password")]
    public async Task<IActionResult> ResetPassword([FromBody] ResetPasswordRequest request)
    {
        try
        {
            var reset = await _authService.ResetPasswordAsync(request.Username, request.NewPassword, request.ResetToken);
            if (!reset)
                return Unauthorized(new ProblemDetails { Title = "재설정 토큰 또는 사용자 정보가 올바르지 않습니다.", Status = StatusCodes.Status401Unauthorized });

            return Ok(new { message = "비밀번호가 재설정되었습니다." });
        }
        catch (InvalidOperationException)
        {
            return StatusCode(StatusCodes.Status503ServiceUnavailable, new ProblemDetails
            {
                Title = "비밀번호 재설정 토큰이 서버에 설정되어 있지 않습니다.",
                Status = StatusCodes.Status503ServiceUnavailable
            });
        }
        catch (ArgumentException ex)
        {
            return BadRequest(new ProblemDetails { Title = ex.Message, Status = StatusCodes.Status400BadRequest });
        }
    }
}

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

public class ChangePasswordRequest
{
    public string CurrentPassword { get; set; } = string.Empty;
    public string NewPassword { get; set; } = string.Empty;
}

public class ResetPasswordRequest
{
    public string Username { get; set; } = string.Empty;
    public string NewPassword { get; set; } = string.Empty;
    public string ResetToken { get; set; } = string.Empty;
}

public class RefreshTokenRequest
{
    public string RefreshToken { get; set; } = string.Empty;
}
