using ControlCenter.Api.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace ControlCenter.Api.Configurations;

/// <summary>
/// EF Core entity type configuration for the agents table.
/// Enforces snake_case naming, required fields, and index design.
/// </summary>
public class AgentConfiguration : IEntityTypeConfiguration<Agent>
{
    public void Configure(EntityTypeBuilder<Agent> builder)
    {
        // Table name — snake_case
        builder.ToTable("agents");

        // Primary key
        builder.HasKey(a => a.Id);
        builder.Property(a => a.Id)
            .HasColumnName("id")
            .ValueGeneratedOnAdd();

        // Status — stored as PostgreSQL enum via Npgsql
        builder.Property(a => a.Status)
            .HasColumnName("status")
            .HasColumnType("agent_status")
            .IsRequired();

        // Task — nullable text
        builder.Property(a => a.Task)
            .HasColumnName("task")
            .HasColumnType("text");

        // Progress — nullable integer (0–100)
        builder.Property(a => a.Progress)
            .HasColumnName("progress");

        // Session key — required, not null
        builder.Property(a => a.SessionKey)
            .HasColumnName("session_key")
            .HasColumnType("text")
            .IsRequired();

        // Channel — required, not null
        builder.Property(a => a.Channel)
            .HasColumnName("channel")
            .HasColumnType("text")
            .IsRequired();

        // Last activity — required, defaults to now()
        builder.Property(a => a.LastActivity)
            .HasColumnName("last_activity")
            .HasColumnType("timestamptz")
            .IsRequired();

        // Created at — auto-set on insert
        builder.Property(a => a.CreatedAt)
            .HasColumnName("created_at")
            .HasColumnType("timestamptz")
            .IsRequired()
            .HasDefaultValueSql("now()");

        // Updated at — auto-set on insert and update
        builder.Property(a => a.UpdatedAt)
            .HasColumnName("updated_at")
            .HasColumnType("timestamptz")
            .IsRequired()
            .HasDefaultValueSql("now()");

        // Indexes
        // Sessions are looked up by session_key frequently
        builder.HasIndex(a => a.SessionKey)
            .HasDatabaseName("ix_agents_session_key")
            .IsUnique();

        // Agents are filtered by channel for channel-specific queries
        builder.HasIndex(a => a.Channel)
            .HasDatabaseName("ix_agents_channel");

        // Agents are filtered by status for fleet health monitoring
        builder.HasIndex(a => a.Status)
            .HasDatabaseName("ix_agents_status");

        // Check constraint: progress must be 0–100 if present
        builder.ToTable(t => t.HasCheckConstraint("ck_agents_progress_range", "progress IS NULL OR (progress >= 0 AND progress <= 100)"));
    }
}