using System.Runtime.InteropServices.ComTypes;
using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore;

namespace OpenWarehouse.warehouse.api.Data;

public class ApplicationDbContext: DbContext, IDataProtectionKeyContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        var itemInWarehouseClaims = modelBuilder.Entity<ItemInWarehouseClaims>();
        itemInWarehouseClaims.HasOne(e => e.Item)
            .WithMany(e => e.ItemInWarehouseClaims)
            .HasForeignKey(e => e.ItemId);
        itemInWarehouseClaims.HasIndex(ic => new { ic.ItemId, ic.ClaimType })
            .IsUnique();
        
        var wrehouseClaims = modelBuilder.Entity<WarehouseClaims>();
        wrehouseClaims.HasOne(e => e.Warehouse)
            .WithMany(e => e.Claims)
            .HasForeignKey(e => e.WarehouseId);
        wrehouseClaims.HasIndex(ic => new { ic.WarehouseId, ic.ClaimType })
            .IsUnique();
        
         var itemClaims = modelBuilder.Entity<ItemClaims>();
         itemClaims.HasIndex(ic => new { ic.ItemId, ic.ClaimType })
            .IsUnique();
         itemClaims.HasOne(ic => ic.Item)
            .WithMany(i => i.ItemClaims) 
            .HasForeignKey(ic => ic.ItemId);
        
        var itemTag = modelBuilder.Entity<ItemCategoryTag>();
        itemTag.HasOne(e => e.ParentTag)
            .WithMany(e => e.ListOfChildrenTag)
            .HasForeignKey(e => e.ParentTagId);
        itemTag.HasIndex(ic => new { ic.Name })
            .IsUnique();

        var item = modelBuilder.Entity<Item>();
        item.HasOne(e => e.Producer)
            .WithMany(e => e.Items)
            .HasForeignKey(e => e.ProducerId)
            .IsRequired(true);
        item.HasIndex(ic => new { ic.Name, ic.ProducerId })
            .IsUnique();
        item.Navigation(ic => ic.ItemClaims)
            .UsePropertyAccessMode(PropertyAccessMode.Property);

        var producers = modelBuilder.Entity<Producers>();
        producers.HasIndex(ic => new { ic.Name })
            .IsUnique();
        producers.Navigation(ic => ic.Claims)
            .UsePropertyAccessMode(PropertyAccessMode.Property);

        var producerClaims = modelBuilder.Entity<ProducerClaims>();
        producerClaims.HasOne(e => e.Producer)
            .WithMany(e => e.Claims)
            .HasForeignKey(e => e.ProducerId);
        producerClaims.HasIndex(ic => new { ic.ProducerId, ic.ClaimType })
            .IsUnique();

        modelBuilder.Entity<ServiceClaims>()
            .HasIndex(ic => ic.ClaimType)
            .IsUnique();

        modelBuilder.Entity<ItemInWarehouse>()
            .Navigation(ic => ic.ItemInWarehouseClaims)
            .UsePropertyAccessMode(PropertyAccessMode.Property);

        modelBuilder.Entity<Warehouse>()
            .Navigation(ic => ic.Claims)
            .UsePropertyAccessMode(PropertyAccessMode.Property);
        
    }
    
    public DbSet<Image> Images { get; init; }
    public DbSet<Item> Items { get; init; }
    public DbSet<ItemCategoryTag> ItemCategoryTags { get; init; }
    public DbSet<ItemClaims> ItemClaims { get; init; }
    public DbSet<ItemInWarehouse> ItemInWarehouses { get; init; }
    public DbSet<ItemInWarehouseClaims> ItemInWarehousesClaims { get; init; }
    public DbSet<Producers> Producers { get; init; }
    public DbSet<ProducerClaims> ProducerClaims { get; init; }
    public DbSet<Warehouse> Warehouses { get; init; }
    public DbSet<WarehouseClaims> WarehouseClaims { get; init; }
    public DbSet<ServiceClaims> ServiceClaims { get; init; }
    public DbSet<DataProtectionKey> DataProtectionKeys { get; init; }
    public DbSet<TaskStatusTable> TaskStatus { get; init; }
}