using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using SolutionErp.Application.Common.Interfaces;
using SolutionErp.Domain.ApprovalWorkflowsV2;
using SolutionErp.Domain.ContractSigningPlans;
using SolutionErp.Domain.Contracts;
using SolutionErp.Domain.Contracts.Details;
using SolutionErp.Domain.Forms;
using SolutionErp.Domain.Hrm;
using SolutionErp.Domain.Identity;
using SolutionErp.Domain.Master;
using SolutionErp.Domain.Master.Catalogs;
using SolutionErp.Domain.Notifications;
using SolutionErp.Domain.Office;
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>();
    // [K1 S164 — Mig 70] Danh mục Hợp đồng SOL-CCM-SP-002 (86 dòng × 8 nhóm duyệt)
    public DbSet<ContractCatalogEntry> ContractCatalogEntries => Set<ContractCatalogEntry>();
    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>();
    // Plan B Chunk C (S29 — Mig 33) — Ý kiến cấp duyệt V2 cho HĐ. Mirror PE Mig 26.
    public DbSet<ContractLevelOpinion> ContractLevelOpinions => Set<ContractLevelOpinion>();
    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>();
    // Mig 26 (Session 19) — Ý kiến cấp duyệt V2 dynamic
    public DbSet<PurchaseEvaluationLevelOpinion> PurchaseEvaluationLevelOpinions => Set<PurchaseEvaluationLevelOpinion>();
    // [S61 Mig 50] Ngân sách gói thầu per cặp (ProjectId, WorkItemId) — thay module Budget cũ.
    public DbSet<PeWorkItemBudget> PeWorkItemBudgets => Set<PeWorkItemBudget>();

    // Quy trình duyệt mới (Mig 22 — Session 17): schema riêng UAT.
    public DbSet<ApprovalWorkflow> ApprovalWorkflows => Set<ApprovalWorkflow>();
    public DbSet<ApprovalWorkflowStep> ApprovalWorkflowSteps => Set<ApprovalWorkflowStep>();
    public DbSet<ApprovalWorkflowLevel> ApprovalWorkflowLevels => Set<ApprovalWorkflowLevel>();

    // Phase 10.1 G-H1 (Mig 34 — S33) — Hồ sơ Nhân sự port từ NamGroup.
    public DbSet<EmployeeProfile> EmployeeProfiles => Set<EmployeeProfile>();
    public DbSet<EmployeeWorkHistory> EmployeeWorkHistories => Set<EmployeeWorkHistory>();
    public DbSet<EmployeeEducation> EmployeeEducations => Set<EmployeeEducation>();
    public DbSet<EmployeeFamilyRelation> EmployeeFamilyRelations => Set<EmployeeFamilyRelation>();
    public DbSet<EmployeeSkill> EmployeeSkills => Set<EmployeeSkill>();
    public DbSet<EmployeeDocument> EmployeeDocuments => Set<EmployeeDocument>();
    public DbSet<EmployeeCodeSequence> EmployeeCodeSequences => Set<EmployeeCodeSequence>();

    // Phase 10.2 G-H2 (Mig 35 — S34) — Cấu hình HRM 4 catalog lookup.
    public DbSet<LeaveType> LeaveTypes => Set<LeaveType>();
    public DbSet<Holiday> Holidays => Set<Holiday>();
    public DbSet<ShiftPattern> ShiftPatterns => Set<ShiftPattern>();
    public DbSet<OtPolicy> OtPolicies => Set<OtPolicy>();

    // Phase 11 P11-C (Mig 44 — S51) — Danh mục xe công + tài xế.
    public DbSet<Vehicle> Vehicles => Set<Vehicle>();
    public DbSet<Driver> Drivers => Set<Driver>();

    // Phase 10.2 G-O2 (Mig 36 — S36) — Phòng họp + Booking + Attendee join.
    public DbSet<MeetingRoom> MeetingRooms => Set<MeetingRoom>();
    public DbSet<MeetingBooking> MeetingBookings => Set<MeetingBooking>();
    public DbSet<MeetingBookingAttendee> MeetingBookingAttendees => Set<MeetingBookingAttendee>();

    // Phase 10.3 G-O3 (Mig 38 — S37) — Đề xuất + Attachment + LevelOpinion + CodeSequence.
    public DbSet<Proposal> Proposals => Set<Proposal>();
    public DbSet<ProposalAttachment> ProposalAttachments => Set<ProposalAttachment>();
    public DbSet<ProposalLevelOpinion> ProposalLevelOpinions => Set<ProposalLevelOpinion>();
    public DbSet<ProposalCodeSequence> ProposalCodeSequences => Set<ProposalCodeSequence>();

    // Phase 10.3 G-O4+G-O5+G-O6 (Mig 39 — S38) — Workflow Apps skeleton 5 entity.
    public DbSet<LeaveRequest> LeaveRequests => Set<LeaveRequest>();
    public DbSet<OtRequest> OtRequests => Set<OtRequest>();
    public DbSet<TravelRequest> TravelRequests => Set<TravelRequest>();
    public DbSet<VehicleBooking> VehicleBookings => Set<VehicleBooking>();
    public DbSet<ItTicket> ItTickets => Set<ItTicket>();

    // Phase 11 P11-A (Mig 41) — LevelOpinions 4 module + shared CodeSequence.
    public DbSet<LeaveRequestLevelOpinion> LeaveRequestLevelOpinions => Set<LeaveRequestLevelOpinion>();
    public DbSet<OtRequestLevelOpinion> OtRequestLevelOpinions => Set<OtRequestLevelOpinion>();
    public DbSet<TravelRequestLevelOpinion> TravelRequestLevelOpinions => Set<TravelRequestLevelOpinion>();
    public DbSet<VehicleBookingLevelOpinion> VehicleBookingLevelOpinions => Set<VehicleBookingLevelOpinion>();
    public DbSet<WorkflowAppCodeSequence> WorkflowAppCodeSequences => Set<WorkflowAppCodeSequence>();

    // Phase 10.4 G-P1 (Mig 40 — S38) — Chấm công web GPS.
    public DbSet<Attendance> Attendances => Set<Attendance>();

    // Phase 11 P11-B Wave 1 (Mig 42) — Số dư phép theo năm.
    public DbSet<LeaveBalance> LeaveBalances => Set<LeaveBalance>();

    // [W1 Mig 69 — S161] GĐ2 "Kế hoạch ký kết HĐ" — 7 bảng (mirror IApplicationDbContext).
    public DbSet<ContractSigningPlan> ContractSigningPlans => Set<ContractSigningPlan>();
    public DbSet<ContractSigningPlanLine> ContractSigningPlanLines => Set<ContractSigningPlanLine>();
    public DbSet<ContractSigningPlanDossierItem> ContractSigningPlanDossierItems => Set<ContractSigningPlanDossierItem>();
    public DbSet<ContractSigningPlanLevelOpinion> ContractSigningPlanLevelOpinions => Set<ContractSigningPlanLevelOpinion>();
    public DbSet<ContractSigningPlanAttachment> ContractSigningPlanAttachments => Set<ContractSigningPlanAttachment>();
    public DbSet<ContractSigningPlanChangelog> ContractSigningPlanChangelogs => Set<ContractSigningPlanChangelog>();
    public DbSet<ContractSigningPlanApproval> ContractSigningPlanApprovals => Set<ContractSigningPlanApproval>();

    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);
    }
}
