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

namespace SIGCM.API.Controllers;

[ApiController]
[Route("api/[controller]")]
public class CouponsController : ControllerBase
{
    private readonly ICouponRepository _repository;
    private readonly AuditRepository _auditRepo;

    public CouponsController(ICouponRepository repository, AuditRepository auditRepo)
    {
        _repository = repository;
        _auditRepo = auditRepo;
    }

    [HttpGet]
    [Authorize(Roles = "Admin")]
    public async Task<IActionResult> GetAll()
    {
        var coupons = await _repository.GetAllAsync();
        return Ok(coupons);
    }

    [HttpGet("validate/{code}")]
    [Authorize]
    public async Task<IActionResult> GetByCode(string code)
    {
        var coupon = await _repository.GetByCodeAsync(code);
        if (coupon == null || !coupon.IsActive)
            return NotFound(new { message = "Cupón inválido o inactivo." });

        if (coupon.ExpiryDate.HasValue && coupon.ExpiryDate.Value < DateTime.UtcNow)
            return BadRequest(new { message = "El cupón ha expirado." });

        if (coupon.MaxUsages.HasValue)
        {
            // Note: We might need a method to count total usages if we want strictly enforce total max usages here
            // but for now, we return the coupon data so the frontend can display info.
        }

        return Ok(coupon);
    }

    [HttpPost]
    [Authorize(Roles = "Admin")]
    public async Task<IActionResult> Create(CreateCouponDto dto)
    {
        // Simple manual mapping
        var coupon = new Coupon
        {
            Code = dto.Code.ToUpper(),
            DiscountType = dto.DiscountType,
            DiscountValue = dto.DiscountValue,
            ExpiryDate = dto.ExpiryDate,
            MaxUsages = dto.MaxUsages,
            MaxUsagesPerUser = dto.MaxUsagesPerUser,
            IsActive = true
        };

        var id = await _repository.CreateAsync(coupon);

        // Audit Log
        var userIdClaim = User.FindFirst("Id")?.Value;
        if (int.TryParse(userIdClaim, out int userId))
        {
            await _auditRepo.AddLogAsync(new AuditLog
            {
                UserId = userId,
                Action = "CREATE_COUPON",
                EntityId = id,
                EntityType = "Coupon",
                Details = $"Cupón {coupon.Code} creado ({dto.DiscountType}: {dto.DiscountValue})",
                CreatedAt = DateTime.UtcNow
            });
        }

        return Ok(new { id });
    }

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

        // Audit Log
        var userIdClaim = User.FindFirst("Id")?.Value;
        if (int.TryParse(userIdClaim, out int userId))
        {
            await _auditRepo.AddLogAsync(new AuditLog
            {
                UserId = userId,
                Action = "DELETE_COUPON",
                EntityId = id,
                EntityType = "Coupon",
                Details = $"Cupón ID #{id} eliminado",
                CreatedAt = DateTime.UtcNow
            });
        }

        return NoContent();
    }
}

public class CreateCouponDto
{
    public required string Code { get; set; }
    public required string DiscountType { get; set; } // "Percentage" or "Fixed"
    public decimal DiscountValue { get; set; }
    public DateTime? ExpiryDate { get; set; }
    public int? MaxUsages { get; set; }
    public int? MaxUsagesPerUser { get; set; }
}
