using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using SolutionErp.Application.Common.Interfaces;
using SolutionErp.Domain.Budgets;
using SolutionErp.Domain.Contracts;
using SolutionErp.Domain.Contracts.Details;
using SolutionErp.Domain.Forms;
using SolutionErp.Domain.Identity;
using SolutionErp.Domain.Master;
using SolutionErp.Domain.Master.Catalogs;
using SolutionErp.Domain.Notifications;
using SolutionErp.Domain.PurchaseEvaluations;

namespace SolutionErp.Infrastructure.Persistence;

public class ApplicationDbContext
    : IdentityDbContext<User, Role, Guid>, IApplicationDbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }

    public DbSet<Supplier> Suppliers => Set<Supplier>();
    public DbSet<Project> Projects => Set<Project>();
    public DbSet<Department> Departments => Set<Department>();
    public DbSet<UnitOfMeasure> UnitsOfMeasure => Set<UnitOfMeasure>();
    public DbSet<MaterialItem> MaterialItems => Set<MaterialItem>();
    public DbSet<ServiceItem> ServiceItems => Set<ServiceItem>();
    public DbSet<WorkItem> WorkItems => Set<WorkItem>();
    public DbSet<MenuItem> MenuItems => Set<MenuItem>();
    public DbSet<Permission> Permissions => Set<Permission>();
    public DbSet<ContractTemplate> ContractTemplates => Set<ContractTemplate>();
    public DbSet<ContractClause> ContractClauses => Set<ContractClause>();
    public DbSet<Contract> Contracts => Set<Contract>();
    public DbSet<ContractApproval> ContractApprovals => Set<ContractApproval>();
    public DbSet<ContractComment> ContractComments => Set<ContractComment>();
    public DbSet<ContractAttachment> ContractAttachments => Set<ContractAttachment>();
    public DbSet<ContractCodeSequence> ContractCodeSequences => Set<ContractCodeSequence>();
    public DbSet<ContractChangelog> ContractChangelogs => Set<ContractChangelog>();
    public DbSet<ContractDepartmentApproval> ContractDepartmentApprovals => Set<ContractDepartmentApproval>();
    public DbSet<Notification> Notifications => Set<Notification>();
    public DbSet<WorkflowTypeAssignment> WorkflowTypeAssignments => Set<WorkflowTypeAssignment>();
    public DbSet<WorkflowDefinition> WorkflowDefinitions => Set<WorkflowDefinition>();
    public DbSet<WorkflowStep> WorkflowSteps => Set<WorkflowStep>();
    public DbSet<WorkflowStepApprover> WorkflowStepApprovers => Set<WorkflowStepApprover>();
    public DbSet<ThauPhuDetail> ThauPhuDetails => Set<ThauPhuDetail>();
    public DbSet<GiaoKhoanDetail> GiaoKhoanDetails => Set<GiaoKhoanDetail>();
    public DbSet<NhaCungCapDetail> NhaCungCapDetails => Set<NhaCungCapDetail>();
    public DbSet<DichVuDetail> DichVuDetails => Set<DichVuDetail>();
    public DbSet<MuaBanDetail> MuaBanDetails => Set<MuaBanDetail>();
    public DbSet<NguyenTacNccDetail> NguyenTacNccDetails => Set<NguyenTacNccDetail>();
    public DbSet<NguyenTacDvDetail> NguyenTacDvDetails => Set<NguyenTacDvDetail>();

    public DbSet<PurchaseEvaluation> PurchaseEvaluations => Set<PurchaseEvaluation>();
    public DbSet<PurchaseEvaluationSupplier> PurchaseEvaluationSuppliers => Set<PurchaseEvaluationSupplier>();
    public DbSet<PurchaseEvaluationDetail> PurchaseEvaluationDetails => Set<PurchaseEvaluationDetail>();
    public DbSet<PurchaseEvaluationQuote> PurchaseEvaluationQuotes => Set<PurchaseEvaluationQuote>();
    public DbSet<PurchaseEvaluationApproval> PurchaseEvaluationApprovals => Set<PurchaseEvaluationApproval>();
    public DbSet<PurchaseEvaluationChangelog> PurchaseEvaluationChangelogs => Set<PurchaseEvaluationChangelog>();
    public DbSet<PurchaseEvaluationAttachment> PurchaseEvaluationAttachments => Set<PurchaseEvaluationAttachment>();
    public DbSet<PurchaseEvaluationWorkflowDefinition> PurchaseEvaluationWorkflowDefinitions => Set<PurchaseEvaluationWorkflowDefinition>();
    public DbSet<PurchaseEvaluationWorkflowStep> PurchaseEvaluationWorkflowSteps => Set<PurchaseEvaluationWorkflowStep>();
    public DbSet<PurchaseEvaluationWorkflowStepApprover> PurchaseEvaluationWorkflowStepApprovers => Set<PurchaseEvaluationWorkflowStepApprover>();
    public DbSet<PurchaseEvaluationCodeSequence> PurchaseEvaluationCodeSequences => Set<PurchaseEvaluationCodeSequence>();
    public DbSet<PurchaseEvaluationDepartmentOpinion> PurchaseEvaluationDepartmentOpinions => Set<PurchaseEvaluationDepartmentOpinion>();
    public DbSet<PurchaseEvaluationDepartmentApproval> PurchaseEvaluationDepartmentApprovals => Set<PurchaseEvaluationDepartmentApproval>();

    // Module Ngân sách (Phase 7) — 4 bảng: Budget header + Details + Approvals + Changelogs.
    public DbSet<Budget> Budgets => Set<Budget>();
    public DbSet<BudgetDetail> BudgetDetails => Set<BudgetDetail>();
    public DbSet<BudgetApproval> BudgetApprovals => Set<BudgetApproval>();
    public DbSet<BudgetChangelog> BudgetChangelogs => Set<BudgetChangelog>();
    public DbSet<BudgetDepartmentApproval> BudgetDepartmentApprovals => Set<BudgetDepartmentApproval>();

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

        // Rename Identity tables
        builder.Entity<User>(e =>
        {
            e.ToTable("Users");
            e.Property(u => u.FullName).HasMaxLength(200).IsRequired();
            e.Property(u => u.RefreshToken).HasMaxLength(512);
            e.Property(u => u.Position).HasMaxLength(200);
            e.HasIndex(u => u.DepartmentId);
            // FK Department — Restrict (không xóa dept nếu còn user assigned)
            e.HasOne<Department>()
                .WithMany()
                .HasForeignKey(u => u.DepartmentId)
                .OnDelete(DeleteBehavior.Restrict);
        });
        builder.Entity<Role>(e =>
        {
            e.ToTable("Roles");
            e.Property(r => r.ShortName).HasMaxLength(50);
            e.Property(r => r.Description).HasMaxLength(500);
        });
        builder.Entity<Microsoft.AspNetCore.Identity.IdentityUserRole<Guid>>(e => e.ToTable("UserRoles"));
        builder.Entity<Microsoft.AspNetCore.Identity.IdentityUserClaim<Guid>>(e => e.ToTable("UserClaims"));
        builder.Entity<Microsoft.AspNetCore.Identity.IdentityUserLogin<Guid>>(e => e.ToTable("UserLogins"));
        builder.Entity<Microsoft.AspNetCore.Identity.IdentityRoleClaim<Guid>>(e => e.ToTable("RoleClaims"));
        builder.Entity<Microsoft.AspNetCore.Identity.IdentityUserToken<Guid>>(e => e.ToTable("UserTokens"));

        builder.ApplyConfigurationsFromAssembly(typeof(ApplicationDbContext).Assembly);
    }
}
