using System;
using BO.AppServer.Metadata.Configuration;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Quadarax.Foundation.Core.Data.Extensions;

namespace BO.AppServer.Data.Entity
{
    public partial class BOContext
    {
        private readonly string _connectionString;
        private readonly ILogger _logger;

        public BOContext(DbContextOptions<BOContext> options, IOptions<Configuration> config, ILoggerFactory logger)
            : base(options)
        {
            if (config == null)
                throw new ArgumentNullException(nameof(config));

            _connectionString = config.Value.System.DbConnectionBO;
            if (logger == null)
                throw new ArgumentNullException(nameof(logger));
            _logger = logger.CreateLogger<BOContext>();
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                var cs = new ConnectionStringHelper(_connectionString);
                _logger.Log(LogLevel.Information, $"Connecting to database '{cs}' ...");
                optionsBuilder.UseSqlServer(_connectionString);
            }
        }

        partial void OnModelCreatingPartial(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Workspace>(entity =>
                {
                    // WORKAROUND temporary solution for keyless entity
                    //modelBuilder.Entity<UserWorkspace>()
                    //    .HasAlternateKey(x => x.Id);
                    
                    modelBuilder.Entity<UserWorkspace>()
                        .HasKey(t => new { t.WorkspaceId, t.UserId });
                        

                    modelBuilder.Entity<UserWorkspace>()
                        .HasOne(am => am.User)
                        .WithMany(a => a.UserWorkspaces)
                        .HasForeignKey(am => am.UserId).HasConstraintName("REL_BillingInfo_User");

                    modelBuilder.Entity<UserWorkspace>()
                        .HasOne(am => am.Workspace)
                        .WithMany(m => m.UserWorkspaces)
                        .HasForeignKey(am => am.WorkspaceId).HasConstraintName("REL_BillingInfo_Workspace");


                    //modelBuilder.Entity<BillingInfo>().Metadata.AddIgnored("Workspace");
                    modelBuilder.Entity<Workspace>().HasOne(d => d.BillingInfo)
                    .WithOne(p => p.Workspace)
                    .HasForeignKey<BillingInfo>(a => a.WorkspaceId)
                    .OnDelete(DeleteBehavior.NoAction)
                    .HasConstraintName("REL_Workspace_BillingInfo");
                    modelBuilder.Entity<Workspace>().HasMany(w=>w.Structures)
                        .WithOne(s => s.Workspace)
                        .HasForeignKey(s => s.WorkspaceId)
                        .HasConstraintName("REL_Structure_Workspace");
                    modelBuilder.Entity<Workspace>().Navigation(w => w.Structures).AutoInclude();
                    modelBuilder.Entity<Workspace>().Navigation(w => w.CreatedByUser).AutoInclude();
                    modelBuilder.Entity<Workspace>().Navigation(w => w.ModifiedByUser).AutoInclude();


                    modelBuilder.Entity<Structure>().Navigation(w => w.Metadocuments).AutoInclude();
                    modelBuilder.Entity<Structure>().HasOne(d => d.CreatedByUser)
                        .WithMany(p => p.StructureCreatedByUsers)
                        .HasForeignKey(d => d.CreatedByUserId)
                        .OnDelete(DeleteBehavior.ClientSetNull)
                        .HasConstraintName("REL_Structure_User_Created");
                    modelBuilder.Entity<Structure>().HasOne(d => d.ModifiedByUser)
                        .WithMany(p => p.StructureModifiedByUsers)
                        .HasForeignKey(d => d.ModifiedByUserId)
                        .HasConstraintName("REL_Structure_User_Modified");

                    modelBuilder.Entity<Metadocument>().Navigation(w => w.CreatedByUser).AutoInclude();
                    modelBuilder.Entity<Metadocument>().Navigation(w => w.ModifiedByUser).AutoInclude();


                    modelBuilder.Entity<Artifact>().Navigation(w => w.CreatedByUser).AutoInclude();


                    modelBuilder.Entity<BillingPlan>().Navigation(w => w.CreatedByUser).AutoInclude();
                    modelBuilder.Entity<BillingPlan>().Navigation(w => w.ModifiedByUser).AutoInclude();

                    modelBuilder.Entity<MimeType>().Navigation(w => w.CreatedByUser).AutoInclude();
                    modelBuilder.Entity<MimeType>().Navigation(w => w.ModifiedByUser).AutoInclude();
                }
            );
        }
    }
}
