using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;

namespace Sockeye.Models
{
    public partial class AyContext : DbContext
    {
        public virtual DbSet<SchemaVersion> SchemaVersion { get; set; }
        public virtual DbSet<MetricMM> MetricMM { get; set; }
        public virtual DbSet<MetricDD> MetricDD { get; set; }
        public virtual DbSet<User> User { get; set; }
        public virtual DbSet<UserOptions> UserOptions { get; set; }
        public virtual DbSet<GlobalBizSettings> GlobalBizSettings { get; set; }
        public virtual DbSet<GlobalOpsBackupSettings> GlobalOpsBackupSettings { get; set; }
        public virtual DbSet<GlobalOpsNotificationSettings> GlobalOpsNotificationSettings { get; set; }
        public virtual DbSet<Event> Event { get; set; }
        public virtual DbSet<SearchDictionary> SearchDictionary { get; set; }
        public virtual DbSet<SearchKey> SearchKey { get; set; }
        public virtual DbSet<FileAttachment> FileAttachment { get; set; }
        public virtual DbSet<OpsJob> OpsJob { get; set; }
        public virtual DbSet<OpsJobLog> OpsJobLog { get; set; }
        public virtual DbSet<Translation> Translation { get; set; }
        public virtual DbSet<TranslationItem> TranslationItem { get; set; }
        public virtual DbSet<DataListSavedFilter> DataListSavedFilter { get; set; }
        public virtual DbSet<DataListColumnView> DataListColumnView { get; set; }
        public virtual DbSet<Tag> Tag { get; set; }
        public virtual DbSet<FormCustom> FormCustom { get; set; }
        public virtual DbSet<FormUserOptions> FormUserOptions { get; set; }
        public virtual DbSet<PickListTemplate> PickListTemplate { get; set; }
        public virtual DbSet<Memo> Memo { get; set; }
        public virtual DbSet<Reminder> Reminder { get; set; }
        public virtual DbSet<Review> Review { get; set; }
        public virtual DbSet<Customer> Customer { get; set; }
        public virtual DbSet<CustomerNote> CustomerNote { get; set; }
        public virtual DbSet<HeadOffice> HeadOffice { get; set; }
        public virtual DbSet<NotifySubscription> NotifySubscription { get; set; }
        public virtual DbSet<NotifyEvent> NotifyEvent { get; set; }
        public virtual DbSet<InAppNotification> InAppNotification { get; set; }
        public virtual DbSet<NotifyDeliveryLog> NotifyDeliveryLog { get; set; }




        public virtual DbSet<Logo> Logo { get; set; }
        public virtual DbSet<Report> Report { get; set; }
        public virtual DbSet<DashboardView> DashboardView { get; set; }


        public virtual DbSet<CustomerNotifySubscription> CustomerNotifySubscription { get; set; }
        public virtual DbSet<CustomerNotifyEvent> CustomerNotifyEvent { get; set; }
        public virtual DbSet<CustomerNotifyDeliveryLog> CustomerNotifyDeliveryLog { get; set; }



        public virtual DbSet<Integration> Integration { get; set; }
        public virtual DbSet<IntegrationItem> IntegrationItem { get; set; }
        public virtual DbSet<IntegrationLog> IntegrationLog { get; set; }

        public virtual DbSet<License> License { get; set; }
        public virtual DbSet<Vendor> Vendor { get; set; }
        public virtual DbSet<Product> Product { get; set; }
        public virtual DbSet<Purchase> Purchase { get; set; }
        public virtual DbSet<VendorNotification> VendorNotification { get; set; }
        public virtual DbSet<TrialLicenseRequest> TrialLicenseRequest { get; set; }
        public virtual DbSet<GZCase> GZCase { get; set; }
        public virtual DbSet<SubscriptionServer> SubscriptionServer { get; set; }

        //Note: had to add this constructor to work with the code in startup.cs that gets the connection string from the appsettings.json file
        //and commented out the above on configuring
        public AyContext(DbContextOptions<AyContext> options) : base(options)
        { }

        //https://stackoverflow.com/a/64053832/8939
        public void Replace<TEntity>(TEntity oldEntity, TEntity newEntity) where TEntity : class
        {
            ChangeTracker.TrackGraph(oldEntity, e => e.Entry.State = EntityState.Deleted);
            ChangeTracker.TrackGraph(newEntity, e => e.Entry.State = e.Entry.IsKeySet ? EntityState.Modified : EntityState.Added);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {

            //AUTOMATICALLY MATCH NAMES
            //https://andrewlock.net/customising-asp-net-core-identity-ef-core-naming-conventions-for-postgresql/
            foreach (var entity in modelBuilder.Model.GetEntityTypes())
            {
                // Replace table names
                var entityName = entity.GetTableName().ToLowerInvariant();
                if (!entityName.StartsWith("view"))
                    entity.SetTableName("a" + entityName);
                else
                    entity.SetTableName(entityName);


                // Replace column names            
                foreach (var property in entity.GetProperties())
                {
                    //Any object that has a concurrencytoken field
                    //set it up to work properly with PostgreSQL
                    if (property.Name == "Concurrency")
                    {
                        property.SetColumnName("xmin");
                        property.SetColumnType("xid");
                        property.ValueGenerated = ValueGenerated.OnAddOrUpdate;
                        property.IsConcurrencyToken = true;
                    }
                    else
                        property.SetColumnName(property.Name.ToLowerInvariant());
                }

                foreach (var key in entity.GetKeys())
                    key.SetName(key.GetName().ToLowerInvariant());

                foreach (var key in entity.GetForeignKeys())
                    key.SetConstraintName(key.GetConstraintName().ToLowerInvariant());

                foreach (var index in entity.GetIndexes())
                    index.SetDatabaseName(index.GetDatabaseName().ToLowerInvariant());

            }

            ///////////////////////////////
            //SERIALIZED OBJECTS
            //

            modelBuilder.Entity<GZCase>().Property(z => z.CaseId).UseIdentityByDefaultColumn();
            //## NOTE: if more added here then must also update globalbizsettingscontroller.seeds and client

            //////////////////////////////////////////////////////////////






            //-----------
        }

    }

}