using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

namespace Health.Infrastructure.Data;

/// <summary>
/// 应用程序数据库上下文
/// </summary>
public sealed class AppDbContext(DbContextOptions<AppDbContext> options) : DbContext(options)
{

    // 核心业务表
    public DbSet<User> Users => Set<User>();
    public DbSet<HealthRecord> HealthRecords => Set<HealthRecord>();
    public DbSet<Medication> Medications => Set<Medication>();
    public DbSet<MedicationLog> MedicationLogs => Set<MedicationLog>();
    public DbSet<DietRecord> DietRecords => Set<DietRecord>();
    public DbSet<DietFoodItem> DietFoodItems => Set<DietFoodItem>();
    public DbSet<ExercisePlan> ExercisePlans => Set<ExercisePlan>();
    public DbSet<ExercisePlanItem> ExercisePlanItems => Set<ExercisePlanItem>();
    public DbSet<Report> Reports => Set<Report>();
    public DbSet<Conversation> Conversations => Set<Conversation>();
    public DbSet<ConversationMessage> ConversationMessages => Set<ConversationMessage>();
    public DbSet<Consultation> Consultations => Set<Consultation>();
    public DbSet<ConsultationMessage> ConsultationMessages => Set<ConsultationMessage>();
    public DbSet<Doctor> Doctors => Set<Doctor>();
    public DbSet<FollowUp> FollowUps => Set<FollowUp>();
    public DbSet<HealthArchive> HealthArchives => Set<HealthArchive>();

    // 支撑表
    public DbSet<RefreshToken> RefreshTokens => Set<RefreshToken>();
    public DbSet<VerificationCode> VerificationCodes => Set<VerificationCode>();
    public DbSet<NotificationPreference> NotificationPreferences => Set<NotificationPreference>();
    public DbSet<DeviceToken> DeviceTokens => Set<DeviceToken>();

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

        // ---- User ----
        builder.Entity<User>(e =>
        {
            e.HasIndex(u => u.Phone).IsUnique();
        });

        // ---- HealthRecord ----
        builder.Entity<HealthRecord>(e =>
        {
            e.HasIndex(r => new { r.UserId, r.RecordedAt }).IsDescending(false, true);
            e.HasIndex(r => new { r.UserId, r.MetricType });
            e.Property(r => r.MetricType).HasConversion<string>();
            e.Property(r => r.Source).HasConversion<string>();
        });

        // ---- Medication ----
        builder.Entity<Medication>(e =>
        {
            e.HasIndex(m => new { m.UserId, m.IsActive });
            e.Property(m => m.Frequency).HasConversion<string>();
            e.Property(m => m.Source).HasConversion<string>();
            e.Property(m => m.TimeOfDay).HasColumnType("time[]");
        });

        builder.Entity<MedicationLog>(e =>
        {
            e.HasIndex(l => new { l.MedicationId, l.CreatedAt }).IsDescending(false, true);
            e.Property(l => l.Status).HasConversion<string>();
        });

        // ---- Diet ----
        builder.Entity<DietRecord>(e =>
        {
            e.HasIndex(d => new { d.UserId, d.RecordedAt }).IsDescending(false, true);
            e.Property(d => d.MealType).HasConversion<string>();
        });

        // ---- ExercisePlan ----
        builder.Entity<ExercisePlan>(e =>
        {
            e.HasIndex(p => new { p.UserId, p.WeekStartDate }).IsDescending(false, true);
        });

        // ---- Report ----
        builder.Entity<Report>(e =>
        {
            e.Property(r => r.FileType).HasConversion<string>();
            e.Property(r => r.Category).HasConversion<string>();
            e.Property(r => r.Status).HasConversion<string>();
        });

        // ---- Conversation ----
        builder.Entity<Conversation>(e =>
        {
            e.HasIndex(c => new { c.UserId, c.UpdatedAt }).IsDescending(false, true);
            e.Property(c => c.AgentType).HasConversion<string>();
        });

        builder.Entity<ConversationMessage>(e =>
        {
            e.HasIndex(m => new { m.ConversationId, m.CreatedAt });
            e.Property(m => m.Role).HasConversion<string>();
        });

        // ---- Consultation ----
        builder.Entity<Consultation>(e =>
        {
            e.Property(c => c.Status).HasConversion<string>();
        });

        builder.Entity<ConsultationMessage>(e =>
        {
            e.HasIndex(m => new { m.ConsultationId, m.CreatedAt }).IsDescending(false, true);
            e.Property(m => m.SenderType).HasConversion<string>();
        });

        // ---- VerificationCode ----
        builder.Entity<VerificationCode>(e =>
        {
            e.HasIndex(v => new { v.Phone, v.CreatedAt }).IsDescending(false, true);
        });

        // ---- NotificationPreference ----
        builder.Entity<NotificationPreference>(e =>
        {
            e.HasIndex(n => n.UserId).IsUnique();
        });

        // ---- HealthArchive ----
        builder.Entity<HealthArchive>(e =>
        {
            e.HasIndex(a => a.UserId).IsUnique();
        });
    }
}
