using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SIGCM.Application.DTOs;
using SIGCM.Domain.Entities;
using SIGCM.Infrastructure.Repositories;
using SIGCM.Infrastructure.Services;

namespace SIGCM.API.Controllers;

[ApiController]
[Route("api/[controller]")]
[Authorize] // Requiere login, pero permite Admin y Cajero por defecto
public class PricingController : ControllerBase
{
  private readonly PricingService _service;
  private readonly PricingRepository _repository;
  private readonly AuditRepository _auditRepo;

  public PricingController(PricingService service, PricingRepository repository, AuditRepository auditRepo)
  {
    _service = service;
    _repository = repository;
    _auditRepo = auditRepo;
  }

  // Usado por: Panel Mostrador (Cajero) y Admin
  [HttpPost("calculate")]
  public async Task<IActionResult> Calculate(CalculatePriceRequest request)
  {
    var result = await _service.CalculateAsync(request);
    return Ok(result);
  }

  // --- Endpoints de Configuración (Solo Admin) ---

  // Obtener reglas de un rubro específico
  [HttpGet("{categoryId}")]
  [Authorize(Roles = "Admin")]
  public async Task<IActionResult> GetConfig(int categoryId)
  {
    var config = await _repository.GetByCategoryIdAsync(categoryId);
    return Ok(config);
  }

  // Guardar/Actualizar reglas
  [HttpPost]
  [Authorize(Roles = "Admin")]
  public async Task<IActionResult> SaveConfig(CategoryPricing pricing)
  {
    if (pricing.CategoryId == 0) return BadRequest("CategoryId es requerido");

    await _repository.UpsertPricingAsync(pricing);

    // Audit Log
    var userIdClaim = User.FindFirst("Id")?.Value;
    if (int.TryParse(userIdClaim, out int userId))
    {
        await _auditRepo.AddLogAsync(new Domain.Entities.AuditLog 
        {
            UserId = userId,
            Action = "SAVE_PRICING",
            EntityId = pricing.CategoryId,
            EntityType = "CategoryPricing",
            Details = $"Pricing updated for Category {pricing.CategoryId}",
            CreatedAt = DateTime.UtcNow
        });
    }

    return Ok(new { message = "Configuración guardada exitosamente" });
  }

  // --- ENDPOINTS DE PROMOCIONES ---

  [HttpGet("promotions")]
  [Authorize(Roles = "Admin")]
  public async Task<IActionResult> GetPromotions()
  {
    var promos = await _repository.GetAllPromotionsAsync();
    return Ok(promos);
  }

  [HttpPost("promotions")]
  [Authorize(Roles = "Admin")]
  public async Task<IActionResult> CreatePromotion(Promotion promo)
  {
    var id = await _repository.CreatePromotionAsync(promo);

    // Audit Log
    var userIdClaim = User.FindFirst("Id")?.Value;
    if (int.TryParse(userIdClaim, out int userId))
    {
        await _auditRepo.AddLogAsync(new Domain.Entities.AuditLog 
        {
            UserId = userId,
            Action = "CREATE_PROMOTION",
            EntityId = id,
            EntityType = "Promotion",
            Details = $"Promotion {promo.Name} created",
            CreatedAt = DateTime.UtcNow
        });
    }

    return Ok(new { id });
  }

  [HttpPut("promotions/{id}")]
  [Authorize(Roles = "Admin")]
  public async Task<IActionResult> UpdatePromotion(int id, Promotion promo)
  {
    if (id != promo.Id) return BadRequest();
    await _repository.UpdatePromotionAsync(promo);

    // Audit Log
    var userIdClaim = User.FindFirst("Id")?.Value;
    if (int.TryParse(userIdClaim, out int userId))
    {
        await _auditRepo.AddLogAsync(new Domain.Entities.AuditLog 
        {
            UserId = userId,
            Action = "UPDATE_PROMOTION",
            EntityId = id,
            EntityType = "Promotion",
            Details = $"Promotion {id} updated",
            CreatedAt = DateTime.UtcNow
        });
    }

    return NoContent();
  }

  [HttpDelete("promotions/{id}")]
  [Authorize(Roles = "Admin")]
  public async Task<IActionResult> DeletePromotion(int id)
  {
    await _repository.DeletePromotionAsync(id);

    // Audit Log
    var userIdClaim = User.FindFirst("Id")?.Value;
    if (int.TryParse(userIdClaim, out int userId))
    {
        await _auditRepo.AddLogAsync(new Domain.Entities.AuditLog 
        {
            UserId = userId,
            Action = "DELETE_PROMOTION",
            EntityId = id,
            EntityType = "Promotion",
            Details = $"Promotion {id} deleted",
            CreatedAt = DateTime.UtcNow
        });
    }

    return NoContent();
  }
}