using foundation_system.Data;
using foundation_system.Models;
using foundation_system.Models.ViewModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;

namespace foundation_system.Controllers
{
    [Authorize]
    public class CajaChicaController : Controller
    {
        private readonly ApplicationDbContext _context;

        public CajaChicaController(ApplicationDbContext context)
        {
            _context = context;
        }

        // GET: CajaChica
        public async Task<IActionResult> Index()
        {
            var cajas = await _context.CajasChicas
                .Include(c => c.Responsable)
                .ThenInclude(u => u.Persona)
                .ToListAsync();
            return View(cajas);
        }

        // GET: CajaChica/Details/5
        public async Task<IActionResult> Details(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var cajaChica = await _context.CajasChicas
                .Include(c => c.Responsable)
                    .ThenInclude(u => u.Persona)
                .Include(c => c.Movimientos.OrderByDescending(m => m.FechaMovimiento).ThenByDescending(m => m.Id))
                    .ThenInclude(m => m.CategoriaGasto)
                .Include(c => c.Movimientos)
                    .ThenInclude(m => m.UsuarioRegistro)
                        .ThenInclude(u => u.Persona)
                .FirstOrDefaultAsync(m => m.Id == id);

            if (cajaChica == null)
            {
                return NotFound();
            }

            return View(cajaChica);
        }

        // GET: CajaChica/Create
        public IActionResult Create()
        {
            ViewData["ResponsableUsuarioId"] = new SelectList(_context.Usuarios.Include(u => u.Persona).Select(u => new {
                Id = u.Id,
                NombreCompleto = u.Persona.Nombres + " " + u.Persona.Apellidos
            }), "Id", "NombreCompleto");
            return View(new CajaChicaViewModel());
        }

        // POST: CajaChica/Create
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create(CajaChicaViewModel model)
        {
            if (ModelState.IsValid)
            {
                // Verify user doesn't already have an open box
                var existingBox = await _context.CajasChicas
                    .AnyAsync(c => c.ResponsableUsuarioId == model.ResponsableUsuarioId && c.Estado == "ABIERTA");

                if (existingBox)
                {
                    ModelState.AddModelError("ResponsableUsuarioId", "El usuario ya tiene una caja chica abierta.");
                }
                else
                {
                    var cajaChica = new CajaChica
                    {
                        Nombre = model.Nombre,
                        ResponsableUsuarioId = model.ResponsableUsuarioId,
                        MontoAsignado = model.MontoAsignado,
                        SaldoActual = model.MontoAsignado, // Starts full
                        FechaApertura = model.FechaApertura,
                        Estado = "ABIERTA",
                        CreadoEn = DateTime.UtcNow,
                        ActualizadoEn = DateTime.UtcNow
                    };

                    _context.Add(cajaChica);
                    await _context.SaveChangesAsync();

                    // Create initial movement
                    var movimiento = new CajaChicaMovimiento
                    {
                        CajaChicaId = cajaChica.Id,
                        TipoMovimiento = "APERTURA",
                        FechaMovimiento = model.FechaApertura,
                        Monto = model.MontoAsignado,
                        Descripcion = "Apertura de Fondo Fijo",
                        UsuarioRegistroId = long.Parse(User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value ?? "1"), // Fallback to 1 if not found
                        CreadoEn = DateTime.UtcNow
                    };
                    
                    _context.Add(movimiento);
                    await _context.SaveChangesAsync();

                    return RedirectToAction(nameof(Index));
                }
            }
            
            ViewData["ResponsableUsuarioId"] = new SelectList(_context.Usuarios.Include(u => u.Persona).Select(u => new {
                Id = u.Id,
                NombreCompleto = u.Persona.Nombres + " " + u.Persona.Apellidos
            }), "Id", "NombreCompleto", model.ResponsableUsuarioId);
            return View(model);
        }
        
        // POST: CajaChica/Close/5
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Close(int id)
        {
            var caja = await _context.CajasChicas.FindAsync(id);
            if (caja == null) return NotFound();

            if (caja.SaldoActual != caja.MontoAsignado)
            {
                 // In a real scenario, you'd require reimbursement first or an adjustment
                 // For now, we'll just allow closing but maybe warn (or simple logic)
            }

            caja.Estado = "CERRADA";
            caja.FechaCierre = DateOnly.FromDateTime(DateTime.Today);
            caja.ActualizadoEn = DateTime.UtcNow;
            
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
    }
}
