using Microsoft.EntityFrameworkCore;
using Hua.Todo.Core.Entities;

namespace Hua.Todo.Application.Data;

/// <summary>
/// 应用程序数据库上下文（EF Core）。
/// </summary>
public class TodoDbContext : DbContext
{
    /// <summary>
    /// 创建 <see cref="TodoDbContext"/>。
    /// </summary>
    /// <param name="options">数据库上下文配置。</param>
    public TodoDbContext(DbContextOptions<TodoDbContext> options) : base(options)
    {
    }

    /// <summary>
    /// 任务集合。
    /// </summary>
    public DbSet<TaskEntity> Tasks { get; set; }

    /// <summary>
    /// 用户集合。
    /// </summary>
    public DbSet<UserEntity> Users { get; set; }

    /// <summary>
    /// 用户会话集合。
    /// </summary>
    public DbSet<UserSessionEntity> UserSessions { get; set; }

    /// <summary>
    /// 安全策略集合。
    /// </summary>
    public DbSet<SecurityPolicyEntity> SecurityPolicies { get; set; }

    /// <summary>
    /// 配置实体模型映射。
    /// </summary>
    /// <param name="modelBuilder">模型构建器。</param>
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<TaskEntity>(entity =>
        {
            entity.ToTable("Tasks");
            entity.HasKey(e => e.Id);
            entity.Property(e => e.UserId).IsRequired().HasDefaultValue(TodoUserIds.LocalUserId);
            entity.Property(e => e.Title).IsRequired().HasMaxLength(200);
            entity.Property(e => e.Priority).HasDefaultValue(TaskPriority.Medium);
            entity.Property(e => e.IsCompleted).HasDefaultValue(false);
            entity.Property(e => e.CreatedAt).HasDefaultValueSql("datetime('now')");
            entity.Property(e => e.UpdatedAt).HasDefaultValueSql("datetime('now')");

            entity.HasOne(e => e.User)
                .WithMany(u => u.Tasks)
                .HasForeignKey(e => e.UserId)
                .OnDelete(DeleteBehavior.Cascade);

            entity.HasOne(e => e.ParentTask)
                .WithMany(e => e.SubTasks)
                .HasForeignKey(e => e.ParentTaskId)
                .OnDelete(DeleteBehavior.Restrict);
        });

        modelBuilder.Entity<UserEntity>(entity =>
        {
            entity.ToTable("Users");
            entity.HasKey(e => e.Id);
            entity.Property(e => e.UserName).IsRequired().HasMaxLength(64);
            entity.HasIndex(e => e.UserName).IsUnique();
            entity.Property(e => e.PasswordHash).IsRequired();
            entity.Property(e => e.Role).IsRequired().HasMaxLength(32);
        });

        modelBuilder.Entity<UserSessionEntity>(entity =>
        {
            entity.ToTable("UserSessions");
            entity.HasKey(e => e.Id);
            entity.Property(e => e.CreatedAtUtc).IsRequired();
            entity.Property(e => e.ExpiresAtUtc).IsRequired();
            entity.HasIndex(e => e.UserId);
            entity.HasOne(e => e.User)
                .WithMany()
                .HasForeignKey(e => e.UserId)
                .OnDelete(DeleteBehavior.Cascade);
        });

        modelBuilder.Entity<SecurityPolicyEntity>(entity =>
        {
            entity.ToTable("SecurityPolicies");
            entity.HasKey(e => e.Id);
            entity.Property(e => e.AllowPersist).HasDefaultValue(true);
            entity.Property(e => e.AllowSync).HasDefaultValue(true);
            entity.HasIndex(e => e.UserId).IsUnique();
            entity.HasOne(e => e.User)
                .WithMany()
                .HasForeignKey(e => e.UserId)
                .OnDelete(DeleteBehavior.Cascade);
        });
    }
}
