using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Rdh.ElectronicMedicineKit.Models;
using System;
using System.Linq;
using System.Linq.Expressions;

namespace Rdh.ElectronicMedicineKit.EntityFrameworkCore
{
    public class ApplicationDbContext : DbContext
    {
        public DbSet<DrugInfo> DrugInfos { get; set; }
        public DbSet<DrugBatch> DrugBatches { get; set; }
        public DbSet<Drug> Drugs { get; set; }

        public DbSet<Patient> Patients { get; set; }
        public DbSet<User> Users { get; set; }
        public DbSet<Operation> Operations { get; set; }
        public DbSet<OperationRoom> OperationRooms { get; set; }
        public DbSet<OperationDrug> OperationDrugs { get; set; }

        public DbSet<MedicineKit> MedicineKits { get; set; }
        public DbSet<MedicineKitLocation> MedicineKitLocations { get; set; }
        public DbSet<MedicineKitConfig> MedicineKitConfigs { get; set; }
        public DbSet<MedicineKitStock> MedicineKitStocks { get; set; }

        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
        {
            ChangeTracker.StateChanged += UpdateTimestamps;
            ChangeTracker.Tracked += UpdateTimestamps;
        }

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

            foreach (var entityType in builder.Model.GetEntityTypes().Where(e => typeof(RootEntity).IsAssignableFrom(e.ClrType)))
            {
                // 添加全局 软删除 过滤器
                var isDeletedProperty = entityType.FindProperty(nameof(RootEntity.IsDeleted));
                if (isDeletedProperty != null)
                {
                    var parameter = Expression.Parameter(entityType.ClrType, "p");
                    var filterIsDeleted = Expression.Equal(Expression.Property(parameter, isDeletedProperty.PropertyInfo), Expression.Constant(false, typeof(bool)));
                    entityType.SetQueryFilter(Expression.Lambda(filterIsDeleted, parameter));
                }

                isDeletedProperty.SetDefaultValue(false);

                foreach (var prop in entityType.GetProperties().Where(e => typeof(Guid).IsAssignableFrom(e.ClrType) || typeof(Guid?).IsAssignableFrom(e.ClrType)))
                {
                    prop.SetValueConverter(new GuidToStringConverter());
                }
            }

            builder.Entity<User>(model => model.HasData(new User[]
            {
                new User { Name = "李浩" ,Code="a3ce8445"},
                new User { Name = "罗岩",Code="bb332e5a" },
                new User { Name = "刘强与" ,Code="bb332e52"},
                new User { Name = "文芳",Code="bb332e53" },
                new User { Name = "何颖" ,Code="bb332e54"},
                new User { Name = "张向丽",Code="bb332e55" },
                new User { Name = "汪玲" ,Code="bb332e56"},
                new User { Name = "李长风",Code="bb332e57" },
                new User { Name = "吴爱国" ,Code="bb332e58"},
                new User { Name = "白丽",Code="bb332e59" },
                new User { Name = "刘思雨" ,Code="bb332f54"},
                new User { Name = "张宇",Code="bb332e51" }
            }));

            builder.Entity<OperationRoom>(model => model.HasData(new OperationRoom[]
            {
                new OperationRoom{ Name = "手术间1", BaseStationCode="00"},
                new OperationRoom{Name="手术间2",BaseStationCode = "01"},
                new OperationRoom{Name="手术间3",BaseStationCode="02"}
            }));

            builder.Entity<Patient>(model => model.HasData(new Patient[]
            {
                new Patient { Name="陶竹生",PatientNo="10232853",Gender = Genders.男,BirthDay = DateTime.Parse("1995-12-01")} ,
                new Patient { Name="郦夏芳",PatientNo="10229717",Gender = Genders.女,BirthDay = DateTime.Parse("1987-12-01")} ,
                new Patient { Name="雷胜蓝",PatientNo="10251888",Gender = Genders.女,BirthDay = DateTime.Parse("1977-12-01")} ,
                new Patient { Name="张和初",PatientNo="10222577",Gender = Genders.男,BirthDay = DateTime.Parse("1996-12-01")} ,
                new Patient { Name="王美华",PatientNo="10221218",Gender = Genders.女,BirthDay = DateTime.Parse("1985-12-01")} ,
                new Patient { Name="谷乐平",PatientNo="10228969",Gender = Genders.男,BirthDay = DateTime.Parse("1975-12-01")} ,
                new Patient { Name="尤梅",PatientNo="10229521",Gender = Genders.女,BirthDay = DateTime.Parse("1999-12-01")} ,
                new Patient { Name="骆元方",PatientNo="10228510",Gender = Genders.男,BirthDay = DateTime.Parse("1965-12-01")}
            }));
            builder.Entity<MedicineKit>(model => model.HasData(new MedicineKit[]
            {
                new MedicineKit{ Code="000"}
            }));
        }

        private static void UpdateTimestamps(object sender, EntityEntryEventArgs e)
        {
            if (e.Entry.Entity is RootEntity entity)
            {
                switch (e.Entry.State)
                {
                    case EntityState.Deleted:
                        entity.IsDeleted = true;
                        entity.DeletionTime = DateTime.Now;
                        e.Entry.State = EntityState.Modified;
                        break;
                    case EntityState.Modified:
                        entity.LastModificationTime = DateTime.Now;
                        break;
                    case EntityState.Added:
                        entity.CreationTime = DateTime.Now;
                        break;
                }
            }
        }
    }
}

