using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Newtonsoft.Json;
using PSTW_CentralSystem.Areas.Inventory.Models;
using PSTW_CentralSystem.Models;
using System.Text.Json;

namespace PSTW_CentralSystem.DBContext
{
    public class CentralSystemContext : IdentityDbContext<UserModel, RoleModel, int>
    {
        private readonly IWebHostEnvironment _hostingEnvironment;
        public CentralSystemContext(DbContextOptions<CentralSystemContext> options, IWebHostEnvironment hostingEnvironment) : base(options)
        {
            _hostingEnvironment = hostingEnvironment;
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            //modelBuilder.HasDefaultSchema("CentralSystem");
            modelBuilder.Entity<ModuleSettingModel>()
            .Property(e => e.MethodAllowedUserType)
            .HasConversion(
                v => JsonConvert.SerializeObject(v),  // Convert List<MethodAllowedUserType> to JSON string
                v => JsonConvert.DeserializeObject<List<MethodAllowedUserType>>(v))
            .Metadata.SetValueComparer(
                new ValueComparer<List<MethodAllowedUserType>>(
                    (c1, c2) => c1 != null && c2 != null && c1.SequenceEqual(c2), // Compare two lists
                    c => c != null ? c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())) : 0, // HashCode
                    c => c != null ? c.ToList() : null // Clone the list to avoid mutations
                ));

            // Seeding Roles
            modelBuilder.Entity<RoleModel>().HasData(
                new RoleModel { Id = 1, Name = "SuperAdmin", NormalizedName = "SuperAdmin".ToUpper(), Description = "Can access all pages" },
                new RoleModel { Id = 2, Name = "SystemAdmin", NormalizedName = "SystemAdmin".ToUpper(), Description = "Can access some admin pages" },
                new RoleModel { Id = 3, Name = "Engineer", NormalizedName = "Engineer".ToUpper(), Description = "Can access operation pages" },
                new RoleModel { Id = 4, Name = "Observer", NormalizedName = "Observer".ToUpper(), Description = "Can access data viewer pages" },
                new RoleModel { Id = 5, Name = "Inventory Master", NormalizedName = "Inventory Master".ToUpper(), Description = "Handle inventory module" },
                new RoleModel { Id = 6, Name = "Finance", NormalizedName = "Finance".ToUpper(), Description = "Involve in inventory transaction" });

            var passwordHasher = new PasswordHasher<UserModel>();

            var superAdmin = new UserModel
            {
                Id = 1, // Use `Guid.NewGuid().ToString()` if the Id is a string.
                FullName = "MAAdmin",
                UserName = "admin@pstw.com.my",
                NormalizedUserName = "ADMIN@PSTW.COM.MY",
                Email = "admin@pstw.com.my",
                NormalizedEmail = "ADMIN@PSTW.COM.MY",
                SecurityStamp = Guid.NewGuid().ToString(),
                EmailConfirmed = true,
                UserInfoStatus = 1,
            };
            var systemAdmin = new UserModel
            {
                Id = 2, // Use `Guid.NewGuid().ToString()` if the Id is a string.
                FullName = "SysAdmin",
                UserName = "sysadmin@pstw.com.my",
                NormalizedUserName = "SYSADMIN@PSTW.COM.MY",
                Email = "sysadmin@pstw.com.my",
                NormalizedEmail = "SYSADMIN@PSTW.COM.MY",
                SecurityStamp = Guid.NewGuid().ToString(),
                EmailConfirmed = true,
                UserInfoStatus = 1,
            };

            // Hash the password
            superAdmin.PasswordHash = passwordHasher.HashPassword(superAdmin, "5u@Dmin12345678");
            systemAdmin.PasswordHash = passwordHasher.HashPassword(systemAdmin, "5ys@Dmin12345678");

            modelBuilder.Entity<UserModel>().HasData(superAdmin, systemAdmin);

            // Seeding AdminRole
            modelBuilder.Entity<IdentityUserRole<int>>().HasData(
                new IdentityUserRole<int> { UserId = 1, RoleId = 1 });

            // Seeding SystemAdminRole
            modelBuilder.Entity<IdentityUserRole<int>>().HasData(
                new IdentityUserRole<int> { UserId = 2, RoleId = 2 });
        }

        public new DbSet<UserModel> Users { get; set; }
        public new DbSet<RoleModel> Roles { get; set; }
        public DbSet<ModuleSettingModel> ModuleSettings { get; set; }
        public DbSet<CompanyModel> Companies { get; set; }
        public DbSet<DepartmentModel> Departments { get; set; }
        public DbSet<ManufacturerModel> Manufacturers { get; set; }
        public DbSet<ItemModel> Items { get; set; }
        public DbSet<RequestModel> Requests { get; set; }
        public DbSet<ProductModel> Products { get; set; }
        public DbSet<SupplierModel> Suppliers { get; set; }
        public DbSet<InventoryMasterModel> InventoryMasters { get; set; }
        public DbSet<ItemMovementModel> ItemMovements { get; set; }
        public DbSet<StationModel> Stations { get; set; }
        public DbSet<StoreModel> Stores { get; set; }

    }
}
