using Microsoft.AspNetCore.Mvc;
using bitforum.Models.Log;
using bitforum.DTOs.Request;
using bitforum.DTOs.Response;
using bitforum.Helpers;
using bitforum.Services;
using bitforum.Repository;

namespace bitforum.Controllers.API.Auth
{
    [ApiController]
    [Route("api/auth")]
    public class LoginController : ControllerBase
    {
        private readonly ILogger<LoginController> _logger;
        private readonly DefaultDbContext _db;
        private readonly IJwtAuthService _jwtAuthService;
        private readonly IMemberRepository _memberRepository;
        private ResultDto _result = new ResultDto();

        public LoginController(ILogger<LoginController> logger, DefaultDbContext db, IJwtAuthService jwtAuthService, IMemberRepository memberRepository)
        {
            _logger = logger;
            _db = db;
            _jwtAuthService = jwtAuthService;
            _memberRepository = memberRepository;
        }

        // 로그인
        [HttpPost("login")]
        public async Task<ActionResult<ResultDto>> Login([FromBody] LoginDto request)
        {
            var loginLog = new LoginLog();

            try
            {
                // 유효성 검사
                if (!ModelState.IsValid)
                {
                    _result.Errors = ModelState.GetErrors();
                    throw new Exception("유효성 검사에 실패하였습니다.");
                }

                loginLog.Account = request.Email;
                loginLog.Referer = HttpContext.Request.Headers["Referer"].ToString();
                loginLog.Url = HttpContext.Request.Path.ToString();
                loginLog.IpAddress = HttpContext.GetClientIP();
                loginLog.UserAgent = Request.Headers["User-Agent"].ToString();

                // 계정 확인
                var member = await _memberRepository.FindMemberByEmail(request.Email);
                if (member == null)
                {
                    loginLog.Reason = "계정을 찾을 수 없음";
                    throw new Exception("해당 정보로 귀하의 계정을 확인할 수 없습니다.");
                }

                if (member.IsDenied)
                {
                    loginLog.Reason = "접속 차단되었음";
                    throw new Exception("접속이 차단되어 로그인이 불가합니다.");
                }

                if (!BCrypt.Net.BCrypt.Verify(request.Password, member.Password))
                {
                    loginLog.Reason = "비밀번호 틀림";
                    throw new Exception("해당 정보로 귀하의 계정을 확인할 수 없습니다.");
                }

                // 로그인 기록
                loginLog.MemberID = member.ID;
                loginLog.Success = true;
                loginLog.Reason = "로그인 성공";
                loginLog.CreatedAt = DateTime.UtcNow;

                // 로그인 시간, IP 갱신
                member.LastLoginIp = HttpContext.GetClientIP();
                member.LastLoginAt = DateTime.UtcNow;

                // JWT 토큰 발급
                _jwtAuthService.SetAccessTokenAndCookieAsync(member);
                await _jwtAuthService.SetRefreshTokenAndCookieAsync(member);

                _result.Message = "로그인 성공";
            }
            catch (Exception e)
            {
                _logger.LogError(e, e.Message);
                _result.Ok = false;
                _result.Status = StatusCodes.Status400BadRequest;
                _result.Message = e.Message;
            }

            await _db.LoginLog.AddAsync(loginLog);
            await _db.SaveChangesAsync();

            return _result;
        }
    }
}
