using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SkyArtShop.Models;
using SkyArtShop.Services;

namespace SkyArtShop.Controllers;

[Authorize(Roles = "Admin,MasterAdmin")]
[Route("admin/users")]
public class AdminUsersController : Controller
{
	private readonly PostgreSQLService _pgService;

	private readonly PostgreAuthService _authService;

	public AdminUsersController(PostgreSQLService pgService, PostgreAuthService authService)
	{
		_pgService = pgService;
		_authService = authService;
	}

	[HttpGet("")]
	public async Task<IActionResult> Index()
	{
		return View((await _pgService.GetAllAsync<AdminUser>("AdminUsers")).OrderBy((AdminUser u) => u.CreatedAt).ToList());
	}

	[HttpGet("create")]
	public IActionResult Create()
	{
		base.ViewBag.Roles = GetAvailableRoles();
		return View();
	}

	[HttpPost("create")]
	public async Task<IActionResult> Create(AdminUser user, string password)
	{
		if (string.IsNullOrWhiteSpace(password))
		{
			base.ModelState.AddModelError("", "Password is required");
			base.ViewBag.Roles = GetAvailableRoles();
			return View(user);
		}
		if (await _authService.GetUserByEmailAsync(user.Email) != null)
		{
			base.ModelState.AddModelError("", "Email already exists");
			base.ViewBag.Roles = GetAvailableRoles();
			return View(user);
		}
		AdminUser adminUser = await _authService.CreateUserAsync(user.Email, password, user.Name, user.Role);
		adminUser.Phone = user.Phone;
		adminUser.Notes = user.Notes;
		adminUser.Permissions = GetRolePermissions(user.Role);
		adminUser.CreatedBy = base.User.Identity?.Name ?? "System";
		adminUser.PasswordNeverExpires = user.PasswordNeverExpires;
		adminUser.PasswordExpiresAt = (user.PasswordNeverExpires ? ((DateTime?)null) : new DateTime?(DateTime.UtcNow.AddDays(90.0)));
		await _pgService.UpdateAsync("AdminUsers", adminUser.Id, adminUser);
		base.TempData["Success"] = "User " + user.Name + " created successfully! They can now login.";
		return RedirectToAction("Index");
	}

	[HttpGet("edit/{id}")]
	public async Task<IActionResult> Edit(string id)
	{
		AdminUser adminUser = await _pgService.GetByIdAsync<AdminUser>("AdminUsers", id);
		if (adminUser == null)
		{
			return NotFound();
		}
		base.ViewBag.Roles = GetAvailableRoles();
		return View(adminUser);
	}

	[HttpPost("edit/{id}")]
	public async Task<IActionResult> Edit(string id, AdminUser user, string? newPassword)
	{
		AdminUser adminUser = await _pgService.GetByIdAsync<AdminUser>("AdminUsers", id);
		if (adminUser == null)
		{
			return NotFound();
		}
		adminUser.Name = user.Name;
		adminUser.Email = user.Email;
		adminUser.Role = user.Role;
		adminUser.Phone = user.Phone;
		adminUser.Notes = user.Notes;
		adminUser.IsActive = user.IsActive;
		adminUser.Permissions = GetRolePermissions(user.Role);
		adminUser.PasswordNeverExpires = user.PasswordNeverExpires;
		adminUser.PasswordExpiresAt = (user.PasswordNeverExpires ? ((DateTime?)null) : new DateTime?(DateTime.UtcNow.AddDays(90.0)));
		if (!string.IsNullOrWhiteSpace(newPassword))
		{
			adminUser.PasswordHash = _authService.HashPassword(newPassword);
		}
		await _pgService.UpdateAsync("AdminUsers", id, adminUser);
		if (!string.IsNullOrWhiteSpace(newPassword))
		{
			base.TempData["Success"] = "User " + user.Name + " and password updated successfully!";
		}
		else
		{
			base.TempData["Success"] = "User " + user.Name + " updated successfully!";
		}
		return RedirectToAction("Index");
	}

	[HttpPost("delete/{id}")]
	public async Task<IActionResult> Delete(string id)
	{
		AdminUser user = await _pgService.GetByIdAsync<AdminUser>("AdminUsers", id);
		if (user == null)
		{
			return NotFound();
		}
		if (user.Role == "MasterAdmin")
		{
			base.TempData["Error"] = "Cannot delete Master Admin!";
			return RedirectToAction("Index");
		}
		await _pgService.DeleteAsync<AdminUser>("AdminUsers", id);
		base.TempData["Success"] = "User " + user.Name + " deleted successfully!";
		return RedirectToAction("Index");
	}

	[HttpGet("view/{id}")]
	public async Task<IActionResult> ViewUser(string id)
	{
		AdminUser adminUser = await _pgService.GetByIdAsync<AdminUser>("AdminUsers", id);
		if (adminUser == null)
		{
			return NotFound();
		}
		return View("View", adminUser);
	}

	private List<string> GetAvailableRoles()
	{
		return new List<string> { "MasterAdmin", "Admin", "Cashier", "Accountant" };
	}

	private List<string> GetRolePermissions(string role)
	{
		return role switch
		{
			"MasterAdmin" => new List<string>
			{
				"manage_users", "manage_products", "manage_orders", "manage_content", "manage_settings", "view_reports", "manage_finances", "manage_inventory", "manage_customers", "manage_blog",
				"manage_portfolio", "manage_pages"
			}, 
			"Admin" => new List<string> { "manage_products", "manage_orders", "manage_content", "view_reports", "manage_inventory", "manage_customers", "manage_blog", "manage_portfolio", "manage_pages" }, 
			"Cashier" => new List<string> { "view_products", "manage_orders", "view_customers", "process_payments" }, 
			"Accountant" => new List<string> { "view_products", "view_orders", "view_reports", "manage_finances", "view_customers", "export_data" }, 
			_ => new List<string>(), 
		};
	}
}
