using Microsoft.AspNetCore.Mvc;
using SIGCM.Domain.Entities;
using SIGCM.Infrastructure.Repositories;

namespace SIGCM.API.Controllers;

[ApiController]
[Route("api/[controller]")]
[Microsoft.AspNetCore.Authorization.Authorize]
public class ClientsController : ControllerBase
{
  private readonly ClientRepository _repo;
  private readonly AuditRepository _auditRepo;

  public ClientsController(ClientRepository repo, AuditRepository auditRepo)
  {
    _repo = repo;
    _auditRepo = auditRepo;
  }

  [HttpGet("search")]
  public async Task<IActionResult> Search([FromQuery] string q)
  {
    if (string.IsNullOrWhiteSpace(q)) return Ok(new List<object>());
    var clients = await _repo.SearchAsync(q);
    return Ok(clients);
  }

  [HttpGet]
  public async Task<IActionResult> GetAll([FromQuery] string? q = null)
  {
    var clients = await _repo.GetAllWithStatsAsync(q);
    return Ok(clients);
  }

  [HttpPut("{id}")]
  public async Task<IActionResult> Update(int id, Client client)
  {
    if (id != client.Id) return BadRequest("ID de URL no coincide con el cuerpo");
    await _repo.UpdateAsync(client);

    // Audit Log
    var userIdClaim = User.FindFirst("Id")?.Value;
    if (int.TryParse(userIdClaim, out int userId))
    {
      await _auditRepo.AddLogAsync(new AuditLog
      {
        UserId = userId,
        Action = "UPDATE_CLIENT",
        EntityId = id,
        EntityType = "Client",
        Details = $"Cliente {client.Name} actualizado (DNI/CUIT: {client.DniOrCuit})",
        CreatedAt = DateTime.UtcNow
      });
    }

    return NoContent();
  }

  [HttpGet("{id}/summary")]
  public async Task<IActionResult> GetSummary(int id)
  {
    var summary = await _repo.GetClientSummaryAsync(id);
    if (summary == null) return NotFound();
    return Ok(summary);
  }

  [HttpPost("{id}/reset-password")]
  [Microsoft.AspNetCore.Authorization.Authorize(Roles = "Admin")]
  public async Task<IActionResult> ResetPassword(int id)
  {
    // Establecemos 1234 como clave por defecto para el blanqueo
    var passwordHash = BCrypt.Net.BCrypt.HashPassword("1234");
    await _repo.ResetPasswordAsync(id, passwordHash);

    // Audit Log
    var userIdClaim = User.FindFirst("Id")?.Value;
    if (int.TryParse(userIdClaim, out int userId))
    {
      await _auditRepo.AddLogAsync(new AuditLog
      {
        UserId = userId,
        Action = "RESET_CLIENT_PASSWORD",
        EntityId = id,
        EntityType = "User",
        Details = "Contraseña de cliente restablecida a '1234' por el administrador.",
        CreatedAt = DateTime.UtcNow
      });
    }

    return Ok(new { message = "Contraseña restablecida a '1234' correctamente." });
  }
}