using ClosedXML.Excel;
using System.IO;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using System.Security.Claims;
using WarehouseAppSHIPS.Data;
using WarehouseAppSHIPS.Models;
using System.Linq;
using System;
using Microsoft.AspNetCore.SignalR;
using WarehouseAppSHIPS.Hubs;

namespace WarehouseAppSHIPS.Controllers
{
    // KUNCI: Master Admin, Supervisor, dan Staff Gudang boleh masuk ke sini!
    [Authorize(Roles = "MasterAdmin,Supervisor,StaffGudang")]
    public class ApprovalController : Controller
    {
        private readonly ApplicationDbContext _context;
        private readonly IHubContext<NotificationHub> _hubContext;

        public ApprovalController(ApplicationDbContext context, IHubContext<NotificationHub> hubContext)
        {
            _context = context;
            _hubContext = hubContext;
        }

        // 1. Menampilkan Daftar Antrean Request
        public IActionResult Index()
        {
            var data = _context.MaterialRequests
                .Include(r => r.Requester)
                .Include(r => r.Material)
                .OrderByDescending(r => r.RequestDate)
                .ToList();
            return View(data);
        }

        // 2. Tombol Aksi: SETUJUI
        public IActionResult Approve(int id)
        {
            var req = _context.MaterialRequests
                .Include(r => r.Material)
                .Include(r => r.Requester)
                .FirstOrDefault(r => r.Id == id);

            if (req != null && req.Status == RequestStatus.Pending)
            {
                if (req.Material != null && req.Material.Stock >= req.Qty)
                {
                    req.Status = RequestStatus.Approved;
                    req.Material.Stock -= req.Qty;

                    var notif = new AppNotification
                    {
                        Title = "Status Permintaan Material",
                        Message = $"Permintaan {req.Material.Name} (Qty: {req.Qty}) telah DISETUJUI oleh {User.Identity?.Name}.",
                        ActionUrl = "/MaterialRequest/Index"
                    };
                    _context.AppNotifications.Add(notif);
                    _context.SaveChanges();

                    _hubContext.Clients.All.SendAsync("TerimaNotif", notif.Title, notif.Message, notif.ActionUrl);

                    TempData["Success"] = $"Berhasil disetujui! Stok {req.Material.Name} telah dipotong sebanyak {req.Qty}.";
                }
                else
                {
                    TempData["Error"] = "GAGAL: Stok fisik di gudang tidak mencukupi untuk request ini!";
                }
            }
            return RedirectToAction("Index");
        }

        // 3. Tombol Aksi: TOLAK
        public IActionResult Reject(int id)
        {
            var req = _context.MaterialRequests
                .Include(r => r.Material)
                .FirstOrDefault(r => r.Id == id);

            if (req != null && req.Status == RequestStatus.Pending)
            {
                req.Status = RequestStatus.Rejected;

                string namaBarang = req.Material?.Name ?? "barang";
                var notif = new AppNotification
                {
                    Title = "Status Permintaan Material",
                    Message = $"Permintaan {namaBarang} (Qty: {req.Qty}) telah DITOLAK oleh {User.Identity?.Name}.",
                    ActionUrl = "/MaterialRequest/Index"
                };
                _context.AppNotifications.Add(notif);
                _context.SaveChanges();

                _hubContext.Clients.All.SendAsync("TerimaNotif", notif.Title, notif.Message, notif.ActionUrl);

                TempData["Success"] = "Request berhasil ditolak.";
            }
            return RedirectToAction("Index");
        }

        // 4. Fitur Cetak Slip (Hanya untuk yang sudah disetujui)
        public IActionResult PrintSlip(int id)
        {
            var req = _context.MaterialRequests
                .Include(r => r.Requester)
                .Include(r => r.Material)
                .FirstOrDefault(r => r.Id == id);

            if (req == null || req.Status != RequestStatus.Approved)
            {
                return RedirectToAction("Index");
            }

            return View(req);
        }
    }
}