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

namespace SkyArtShop.Controllers;

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

	private readonly SlugService _slugService;

	private readonly string _productsCollection = "Products";

	public AdminProductsController(PostgreSQLService pgService, SlugService slugService)
	{
		_pgService = pgService;
		_slugService = slugService;
	}

	[HttpGet("")]
	public async Task<IActionResult> Index()
	{
		return View((await _pgService.GetAllAsync<Product>(_productsCollection)).OrderByDescending((Product p) => p.CreatedAt).ToList());
	}

	[HttpGet("create")]
	public IActionResult Create()
	{
		return View(new Product());
	}

	[HttpPost("create")]
	public async Task<IActionResult> Create(Product product, string? ProductVariantsJson)
	{
		try
		{
			base.ModelState.Remove("ShortDescription");
			base.ModelState.Remove("Description");
			base.ModelState.Remove("ProductVariantsJson");
			base.ModelState.Remove("Id");
			base.ModelState.Remove("Slug");
			base.ModelState.Remove("ImageUrl");
			base.ModelState.Remove("Images");
			if (!base.ModelState.IsValid)
			{
				foreach (ModelError item in base.ModelState.Values.SelectMany((ModelStateEntry v) => v.Errors))
				{
					Console.WriteLine("[CREATE] Validation Error: " + item.ErrorMessage);
				}
				return View(product);
			}
		}
		catch (Exception ex)
		{
			Console.WriteLine("[CREATE] Error: " + ex.Message);
			Console.WriteLine("[CREATE] Stack: " + ex.StackTrace);
			base.TempData["ErrorMessage"] = "Error creating product: " + ex.Message;
			return View(product);
		}
		if (!base.Request.Form.ContainsKey("IsActive"))
		{
			product.IsActive = false;
		}
		if (!base.Request.Form.ContainsKey("IsFeatured"))
		{
			product.IsFeatured = false;
		}
		if (!base.Request.Form.ContainsKey("IsTopSeller"))
		{
			product.IsTopSeller = false;
		}
		Console.WriteLine("[CREATE] ProductVariantsJson received: '" + (ProductVariantsJson ?? "NULL") + "'");
		if (!string.IsNullOrEmpty(ProductVariantsJson))
		{
			try
			{
				product.Variants = JsonSerializer.Deserialize<List<ProductVariant>>(ProductVariantsJson) ?? new List<ProductVariant>();
				Console.WriteLine($"[CREATE] Variants deserialized successfully: {product.Variants.Count} variants");
				foreach (ProductVariant variant in product.Variants)
				{
					Console.WriteLine($"  - {variant.ColorName} ({variant.ColorHex}) with {variant.Images?.Count ?? 0} images, Stock: {variant.StockQuantity}");
				}
			}
			catch (Exception ex2)
			{
				Console.WriteLine("[CREATE] Error parsing variants: " + ex2.Message);
				Console.WriteLine("[CREATE] JSON was: " + ProductVariantsJson);
				product.Variants = new List<ProductVariant>();
			}
		}
		else
		{
			Console.WriteLine("[CREATE] No variants provided - ProductVariantsJson is null or empty");
			product.Variants = new List<ProductVariant>();
		}
		product.Colors = new List<string>();
		product.Color = string.Empty;
		try
		{
			product.CreatedAt = DateTime.UtcNow;
			product.UpdatedAt = DateTime.UtcNow;
			product.Slug = _slugService.GenerateSlug(product.Name);
			await _pgService.InsertAsync(_productsCollection, product);
			base.TempData["SuccessMessage"] = "Product created successfully!";
			return RedirectToAction("Index");
		}
		catch (Exception ex3)
		{
			Console.WriteLine("[CREATE] Database Error: " + ex3.Message);
			Console.WriteLine("[CREATE] Stack: " + ex3.StackTrace);
			base.TempData["ErrorMessage"] = "Error saving product: " + ex3.Message;
			return View(product);
		}
	}

	[HttpGet("edit/{id}")]
	public async Task<IActionResult> Edit(string id)
	{
		Product product = await _pgService.GetByIdAsync<Product>(_productsCollection, id);
		if (product == null)
		{
			return NotFound();
		}
		return View("Create", product);
	}

	[HttpPost("edit/{id}")]
	public async Task<IActionResult> Edit(string id, Product product, string? ProductVariantsJson)
	{
		try
		{
			base.ModelState.Remove("Images");
			base.ModelState.Remove("Slug");
			base.ModelState.Remove("ShortDescription");
			base.ModelState.Remove("Description");
			base.ModelState.Remove("ProductVariantsJson");
			base.ModelState.Remove("Id");
			base.ModelState.Remove("ImageUrl");
			if (!base.ModelState.IsValid)
			{
				foreach (ModelError item in base.ModelState.Values.SelectMany((ModelStateEntry v) => v.Errors))
				{
					Console.WriteLine("[EDIT] Validation Error: " + item.ErrorMessage);
				}
				return View("Create", product);
			}
		}
		catch (Exception ex)
		{
			Console.WriteLine("[EDIT] Error: " + ex.Message);
			Console.WriteLine("[EDIT] Stack: " + ex.StackTrace);
			base.TempData["ErrorMessage"] = "Error updating product: " + ex.Message;
			return View("Create", product);
		}
		if (!base.Request.Form.ContainsKey("IsActive"))
		{
			product.IsActive = false;
		}
		if (!base.Request.Form.ContainsKey("IsFeatured"))
		{
			product.IsFeatured = false;
		}
		if (!base.Request.Form.ContainsKey("IsTopSeller"))
		{
			product.IsTopSeller = false;
		}
		Product existingProduct = await _pgService.GetByIdAsync<Product>(_productsCollection, id);
		if (existingProduct == null)
		{
			base.TempData["ErrorMessage"] = "Product not found.";
			return RedirectToAction("Index");
		}
		existingProduct.Name = product.Name;
		existingProduct.ShortDescription = product.ShortDescription;
		existingProduct.Description = product.Description;
		existingProduct.Price = product.Price;
		existingProduct.Category = product.Category;
		existingProduct.Color = product.Color;
		Console.WriteLine("[EDIT] ProductVariantsJson received: '" + (ProductVariantsJson ?? "NULL") + "'");
		if (!string.IsNullOrEmpty(ProductVariantsJson))
		{
			try
			{
				existingProduct.Variants = JsonSerializer.Deserialize<List<ProductVariant>>(ProductVariantsJson) ?? new List<ProductVariant>();
				Console.WriteLine($"[EDIT] Variants deserialized successfully: {existingProduct.Variants.Count} variants");
				foreach (ProductVariant variant in existingProduct.Variants)
				{
					Console.WriteLine($"  - {variant.ColorName} ({variant.ColorHex}) with {variant.Images?.Count ?? 0} images, Stock: {variant.StockQuantity}");
				}
			}
			catch (Exception ex2)
			{
				Console.WriteLine("[EDIT] Error parsing variants: " + ex2.Message);
				Console.WriteLine("[EDIT] JSON was: " + ProductVariantsJson);
				existingProduct.Variants = new List<ProductVariant>();
			}
		}
		else
		{
			Console.WriteLine("[EDIT] No variants provided - ProductVariantsJson is null or empty");
			existingProduct.Variants = new List<ProductVariant>();
		}
		existingProduct.Colors = new List<string>();
		existingProduct.Color = string.Empty;
		existingProduct.StockQuantity = product.StockQuantity;
		existingProduct.IsFeatured = product.IsFeatured;
		existingProduct.IsTopSeller = product.IsTopSeller;
		existingProduct.IsActive = product.IsActive;
		existingProduct.UpdatedAt = DateTime.UtcNow;
		existingProduct.Slug = _slugService.GenerateSlug(product.Name);
		if (base.Request.Form.ContainsKey("Images"))
		{
			List<string> list = (existingProduct.Images = (from img in base.Request.Form["Images"]
				where !string.IsNullOrEmpty(img)
				select (img)).ToList());
			if (list.Any() && string.IsNullOrEmpty(product.ImageUrl))
			{
				existingProduct.ImageUrl = list[0] ?? "";
			}
		}
		if (!string.IsNullOrEmpty(product.ImageUrl))
		{
			existingProduct.ImageUrl = product.ImageUrl;
		}
		if (!string.IsNullOrEmpty(product.SKU))
		{
			existingProduct.SKU = product.SKU;
		}
		if (product.CostPrice > 0m)
		{
			existingProduct.CostPrice = product.CostPrice;
		}
		try
		{
			await _pgService.UpdateAsync(_productsCollection, id, existingProduct);
			base.TempData["SuccessMessage"] = "Product updated successfully!";
			return RedirectToAction("Index");
		}
		catch (Exception ex3)
		{
			Console.WriteLine("[EDIT] Database Error: " + ex3.Message);
			Console.WriteLine("[EDIT] Stack: " + ex3.StackTrace);
			base.TempData["ErrorMessage"] = "Error saving product changes: " + ex3.Message;
			return View("Create", existingProduct);
		}
	}

	[HttpPost("delete/{id}")]
	public async Task<IActionResult> Delete(string id)
	{
		await _pgService.DeleteAsync<Product>(_productsCollection, id);
		base.TempData["SuccessMessage"] = "Product deleted successfully!";
		return RedirectToAction("Index");
	}
}
