using Microsoft.EntityFrameworkCore;
using PowderCoating.Core.Entities;

namespace PowderCoating.Infrastructure.Services;

public partial class SeedDataService
{
    /// <summary>
    /// Seeds the 16 standard job status lookup rows for a company, covering the full
    /// powder-coating workflow from Pending through Delivered/Cancelled.
    /// </summary>
    /// <remarks>
    /// Job status is a lookup table (<see cref="JobStatusLookup"/>) rather than a C# enum so
    /// that operators can customise display names, colours, and ordering without a code deploy.
    /// The <c>StatusCode</c> string constants (e.g., "PENDING", "COATING") are referenced
    /// throughout the application code and must not be changed after initial seeding.
    ///
    /// Idempotency check: if 16 or more rows already exist for the company, the method
    /// returns 0 immediately.  This threshold equals the full set size, so a partially-seeded
    /// company (e.g., from a previous failed run) will be re-seeded automatically.
    ///
    /// Key flags per status row:
    /// - <c>IsTerminalStatus</c> = true for Completed, Delivered, Cancelled — the AI
    ///   accounting service uses this to distinguish active vs closed jobs.
    /// - <c>IsWorkInProgressStatus</c> = true for production stages (In Preparation through
    ///   Quality Check) — used by dashboard KPIs and scheduling views.
    /// - <c>IsSystemDefined</c> = true for statuses that drive automated workflows
    ///   (Pending, Completed, Cancelled) — operators cannot delete these.
    /// - <c>WorkflowCategory</c> groups statuses for reporting (Pre-Production, Production,
    ///   Post-Production, Other).
    /// </remarks>
    /// <param name="company">The tenant company to seed statuses for.</param>
    /// <returns>The number of status rows created (16), or 0 if already seeded.</returns>
    private async Task<int> SeedJobStatusLookupsAsync(Company company)
    {
        // Check if job statuses already exist for this company
        var existingCount = await _context.Set<JobStatusLookup>()
            .IgnoreQueryFilters()
            .CountAsync(s => s.CompanyId == company.Id && !s.IsDeleted);

        if (existingCount >= 16)
        {
            return 0; // Already seeded
        }

        var statuses = new List<JobStatusLookup>
        {
            new JobStatusLookup
            {
                StatusCode = "PENDING",
                DisplayName = "Pending",
                DisplayOrder = 1,
                ColorClass = "secondary",
                IconClass = "bi-clock",
                IsActive = true,
                IsSystemDefined = true,
                IsTerminalStatus = false,
                IsWorkInProgressStatus = false,
                WorkflowCategory = "Pre-Production",
                Description = "Job has been created and is awaiting approval",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobStatusLookup
            {
                StatusCode = "QUOTED",
                DisplayName = "Quoted",
                DisplayOrder = 2,
                ColorClass = "info",
                IconClass = "bi-file-text",
                IsActive = true,
                IsSystemDefined = false,
                IsTerminalStatus = false,
                IsWorkInProgressStatus = false,
                WorkflowCategory = "Pre-Production",
                Description = "Quote has been generated for this job",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobStatusLookup
            {
                StatusCode = "APPROVED",
                DisplayName = "Approved",
                DisplayOrder = 3,
                ColorClass = "primary",
                IconClass = "bi-check-circle",
                IsActive = true,
                IsSystemDefined = false,
                IsTerminalStatus = false,
                IsWorkInProgressStatus = false,
                WorkflowCategory = "Pre-Production",
                Description = "Job has been approved and is ready to start",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobStatusLookup
            {
                StatusCode = "IN_PREPARATION",
                DisplayName = "In Preparation",
                DisplayOrder = 4,
                ColorClass = "warning",
                IconClass = "bi-tools",
                IsActive = true,
                IsSystemDefined = false,
                IsTerminalStatus = false,
                IsWorkInProgressStatus = true,
                WorkflowCategory = "Production",
                Description = "Job is being prepared for processing",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobStatusLookup
            {
                StatusCode = "SANDBLASTING",
                DisplayName = "Sandblasting",
                DisplayOrder = 5,
                ColorClass = "warning",
                IconClass = "bi-wind",
                IsActive = true,
                IsSystemDefined = false,
                IsTerminalStatus = false,
                IsWorkInProgressStatus = true,
                WorkflowCategory = "Production",
                Description = "Surface preparation in progress",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobStatusLookup
            {
                StatusCode = "MASKING_TAPING",
                DisplayName = "Masking/Taping",
                DisplayOrder = 6,
                ColorClass = "warning",
                IconClass = "bi-scissors",
                IsActive = true,
                IsSystemDefined = false,
                IsTerminalStatus = false,
                IsWorkInProgressStatus = true,
                WorkflowCategory = "Production",
                Description = "Masking areas that should not be coated",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobStatusLookup
            {
                StatusCode = "CLEANING",
                DisplayName = "Cleaning",
                DisplayOrder = 7,
                ColorClass = "warning",
                IconClass = "bi-droplet",
                IsActive = true,
                IsSystemDefined = false,
                IsTerminalStatus = false,
                IsWorkInProgressStatus = true,
                WorkflowCategory = "Production",
                Description = "Final cleaning before coating",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobStatusLookup
            {
                StatusCode = "IN_OVEN",
                DisplayName = "In Oven",
                DisplayOrder = 8,
                ColorClass = "warning",
                IconClass = "bi-thermometer-half",
                IsActive = true,
                IsSystemDefined = false,
                IsTerminalStatus = false,
                IsWorkInProgressStatus = true,
                WorkflowCategory = "Production",
                Description = "Parts are being pre-heated",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobStatusLookup
            {
                StatusCode = "COATING",
                DisplayName = "Coating",
                DisplayOrder = 9,
                ColorClass = "warning",
                IconClass = "bi-paint-bucket",
                IsActive = true,
                IsSystemDefined = false,
                IsTerminalStatus = false,
                IsWorkInProgressStatus = true,
                WorkflowCategory = "Production",
                Description = "Applying powder coating",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobStatusLookup
            {
                StatusCode = "CURING",
                DisplayName = "Curing",
                DisplayOrder = 10,
                ColorClass = "warning",
                IconClass = "bi-fire",
                IsActive = true,
                IsSystemDefined = false,
                IsTerminalStatus = false,
                IsWorkInProgressStatus = true,
                WorkflowCategory = "Production",
                Description = "Curing the powder coating in the oven",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobStatusLookup
            {
                StatusCode = "QUALITY_CHECK",
                DisplayName = "Quality Check",
                DisplayOrder = 11,
                ColorClass = "info",
                IconClass = "bi-search",
                IsActive = true,
                IsSystemDefined = false,
                IsTerminalStatus = false,
                IsWorkInProgressStatus = true,
                WorkflowCategory = "Post-Production",
                Description = "Quality inspection in progress",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobStatusLookup
            {
                StatusCode = "COMPLETED",
                DisplayName = "Completed",
                DisplayOrder = 12,
                ColorClass = "success",
                IconClass = "bi-check2-all",
                IsActive = true,
                IsSystemDefined = true,
                IsTerminalStatus = true,
                IsWorkInProgressStatus = false,
                WorkflowCategory = "Post-Production",
                Description = "Job work is completed",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobStatusLookup
            {
                StatusCode = "READY_FOR_PICKUP",
                DisplayName = "Ready for Pickup",
                DisplayOrder = 13,
                ColorClass = "success",
                IconClass = "bi-box-seam",
                IsActive = true,
                IsSystemDefined = false,
                IsTerminalStatus = false,
                IsWorkInProgressStatus = false,
                WorkflowCategory = "Post-Production",
                Description = "Job is ready for customer pickup",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobStatusLookup
            {
                StatusCode = "DELIVERED",
                DisplayName = "Delivered",
                DisplayOrder = 14,
                ColorClass = "success",
                IconClass = "bi-truck",
                IsActive = true,
                IsSystemDefined = false,
                IsTerminalStatus = true,
                IsWorkInProgressStatus = false,
                WorkflowCategory = "Post-Production",
                Description = "Job has been delivered to customer",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobStatusLookup
            {
                StatusCode = "ON_HOLD",
                DisplayName = "On Hold",
                DisplayOrder = 15,
                ColorClass = "dark",
                IconClass = "bi-pause-circle",
                IsActive = true,
                IsSystemDefined = false,
                IsTerminalStatus = false,
                IsWorkInProgressStatus = false,
                WorkflowCategory = "Other",
                Description = "Job has been paused",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobStatusLookup
            {
                StatusCode = "CANCELLED",
                DisplayName = "Cancelled",
                DisplayOrder = 16,
                ColorClass = "danger",
                IconClass = "bi-x-circle",
                IsActive = true,
                IsSystemDefined = true,
                IsTerminalStatus = true,
                IsWorkInProgressStatus = false,
                WorkflowCategory = "Other",
                Description = "Job has been cancelled",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            }
        };

        await _context.Set<JobStatusLookup>().AddRangeAsync(statuses);
        await _context.SaveChangesAsync();

        return statuses.Count;
    }

    /// <summary>
    /// Seeds the five standard job priority levels (Low, Normal, High, Urgent, Rush) as
    /// lookup rows for a company, each with a Bootstrap colour class and Bootstrap Icon.
    /// </summary>
    /// <remarks>
    /// Like job statuses, priorities are a lookup table so display names and colours can be
    /// adjusted per tenant without a code change.  The <c>PriorityCode</c> strings
    /// (e.g., "NORMAL", "RUSH") are referenced by the job creation UI and report filters
    /// and must not be renamed after seeding.
    ///
    /// Idempotency check: bails early if 5 or more rows already exist for the company.
    ///
    /// Both URGENT and RUSH use the "danger" colour class intentionally — they signal
    /// different urgency levels but both demand immediate visual attention on the shop floor.
    /// The distinction matters for rush-charge calculation: a Rush priority triggers the
    /// rush-charge percentage defined in <see cref="CompanyOperatingCosts"/>.
    /// </remarks>
    /// <param name="company">The tenant company to seed priorities for.</param>
    /// <returns>The number of priority rows created (5), or 0 if already seeded.</returns>
    private async Task<int> SeedJobPriorityLookupsAsync(Company company)
    {
        // Check if job priorities already exist for this company
        var existingCount = await _context.Set<JobPriorityLookup>()
            .IgnoreQueryFilters()
            .CountAsync(p => p.CompanyId == company.Id && !p.IsDeleted);

        if (existingCount >= 5)
        {
            return 0; // Already seeded
        }

        var priorities = new List<JobPriorityLookup>
        {
            new JobPriorityLookup
            {
                PriorityCode = "LOW",
                DisplayName = "Low",
                DisplayOrder = 1,
                ColorClass = "secondary",
                IconClass = "bi-arrow-down",
                IsActive = true,
                IsSystemDefined = false,
                Description = "Low priority - no rush",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobPriorityLookup
            {
                PriorityCode = "NORMAL",
                DisplayName = "Normal",
                DisplayOrder = 2,
                ColorClass = "info",
                IconClass = "bi-dash",
                IsActive = true,
                IsSystemDefined = false,
                Description = "Normal priority - standard turnaround",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobPriorityLookup
            {
                PriorityCode = "HIGH",
                DisplayName = "High",
                DisplayOrder = 3,
                ColorClass = "warning",
                IconClass = "bi-arrow-up",
                IsActive = true,
                IsSystemDefined = false,
                Description = "High priority - expedited processing",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobPriorityLookup
            {
                PriorityCode = "URGENT",
                DisplayName = "Urgent",
                DisplayOrder = 4,
                ColorClass = "danger",
                IconClass = "bi-exclamation-triangle",
                IsActive = true,
                IsSystemDefined = false,
                Description = "Urgent - requires immediate attention",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new JobPriorityLookup
            {
                PriorityCode = "RUSH",
                DisplayName = "Rush",
                DisplayOrder = 5,
                ColorClass = "danger",
                IconClass = "bi-lightning",
                IsActive = true,
                IsSystemDefined = false,
                Description = "Rush order - top priority",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            }
        };

        await _context.Set<JobPriorityLookup>().AddRangeAsync(priorities);
        await _context.SaveChangesAsync();

        return priorities.Count;
    }

    /// <summary>
    /// Seeds the seven standard quote status lookup rows for a company
    /// (Draft, Sent, Approved, Rejected, Expired, Converted, Revised).
    /// </summary>
    /// <remarks>
    /// Quote status uses a lookup table (like job status) so operators can adjust display
    /// names and colours.  The <c>StatusCode</c> strings and the boolean semantic flags
    /// (<c>IsApprovedStatus</c>, <c>IsConvertedStatus</c>, <c>IsDraftStatus</c>,
    /// <c>IsRejectedStatus</c>) are what the application code queries — UI text is cosmetic.
    ///
    /// Idempotency check: if 7+ rows exist the method skips insertion, but it performs
    /// a retroactive fix for the REJECTED status: older seeded databases may have
    /// <c>IsRejectedStatus = false</c> because the field was added after initial release.
    /// The fix is applied on every call when the row already exists and the flag is wrong,
    /// ensuring the quote portal correctly blocks re-approval of rejected quotes.
    ///
    /// Key semantic flags:
    /// - <c>IsApprovedStatus</c>: only APPROVED — triggers quote-to-job conversion eligibility.
    /// - <c>IsConvertedStatus</c>: only CONVERTED — marks quotes that have already become jobs.
    /// - <c>IsDraftStatus</c>: only DRAFT — controls edit permissions (draft quotes are fully editable).
    /// - <c>IsRejectedStatus</c>: only REJECTED — prevents the customer approval portal from
    ///   re-activating a quote the customer already declined.
    /// </remarks>
    /// <param name="company">The tenant company to seed quote statuses for.</param>
    /// <returns>The number of status rows created (7), or 0 if already seeded (retroactive fix may still apply).</returns>
    private async Task<int> SeedQuoteStatusLookupsAsync(Company company)
    {
        // Check if quote statuses already exist for this company
        var existingCount = await _context.Set<QuoteStatusLookup>()
            .IgnoreQueryFilters()
            .CountAsync(s => s.CompanyId == company.Id && !s.IsDeleted);

        if (existingCount >= 7)
        {
            // Retroactive fix: ensure REJECTED status has IsRejectedStatus = true
            var rejectedStatus = await _context.Set<QuoteStatusLookup>()
                .IgnoreQueryFilters()
                .FirstOrDefaultAsync(s => s.CompanyId == company.Id && s.StatusCode == "REJECTED" && !s.IsDeleted);
            if (rejectedStatus != null && !rejectedStatus.IsRejectedStatus)
            {
                rejectedStatus.IsRejectedStatus = true;
                await _context.SaveChangesAsync();
            }
            return 0; // Already seeded
        }

        var statuses = new List<QuoteStatusLookup>
        {
            new QuoteStatusLookup
            {
                StatusCode = "DRAFT",
                DisplayName = "Draft",
                DisplayOrder = 1,
                ColorClass = "secondary",
                IconClass = "bi-pencil",
                IsActive = true,
                IsSystemDefined = true,
                IsDraftStatus = true,
                IsApprovedStatus = false,
                IsConvertedStatus = false,
                Description = "Quote is being prepared",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new QuoteStatusLookup
            {
                StatusCode = "SENT",
                DisplayName = "Sent",
                DisplayOrder = 2,
                ColorClass = "info",
                IconClass = "bi-send",
                IsActive = true,
                IsSystemDefined = false,
                IsDraftStatus = false,
                IsApprovedStatus = false,
                IsConvertedStatus = false,
                Description = "Quote has been sent to customer",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new QuoteStatusLookup
            {
                StatusCode = "APPROVED",
                DisplayName = "Approved",
                DisplayOrder = 3,
                ColorClass = "success",
                IconClass = "bi-check-circle",
                IsActive = true,
                IsSystemDefined = true,
                IsDraftStatus = false,
                IsApprovedStatus = true,
                IsConvertedStatus = false,
                Description = "Quote has been approved by customer",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new QuoteStatusLookup
            {
                StatusCode = "REJECTED",
                DisplayName = "Rejected",
                DisplayOrder = 4,
                ColorClass = "danger",
                IconClass = "bi-x-circle",
                IsActive = true,
                IsSystemDefined = false,
                IsDraftStatus = false,
                IsApprovedStatus = false,
                IsRejectedStatus = true,
                IsConvertedStatus = false,
                Description = "Quote has been rejected by customer",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new QuoteStatusLookup
            {
                StatusCode = "EXPIRED",
                DisplayName = "Expired",
                DisplayOrder = 5,
                ColorClass = "warning",
                IconClass = "bi-clock-history",
                IsActive = true,
                IsSystemDefined = false,
                IsDraftStatus = false,
                IsApprovedStatus = false,
                IsConvertedStatus = false,
                Description = "Quote has passed its expiration date",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new QuoteStatusLookup
            {
                StatusCode = "CONVERTED",
                DisplayName = "Converted",
                DisplayOrder = 6,
                ColorClass = "primary",
                IconClass = "bi-arrow-right-circle",
                IsActive = true,
                IsSystemDefined = true,
                IsDraftStatus = false,
                IsApprovedStatus = false,
                IsConvertedStatus = true,
                Description = "Quote has been converted to a job",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new QuoteStatusLookup
            {
                StatusCode = "REVISED",
                DisplayName = "Revised",
                DisplayOrder = 7,
                ColorClass = "info",
                IconClass = "bi-arrow-repeat",
                IsActive = true,
                IsSystemDefined = false,
                IsDraftStatus = false,
                IsApprovedStatus = false,
                IsConvertedStatus = false,
                Description = "Quote has been revised",
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            }
        };

        await _context.Set<QuoteStatusLookup>().AddRangeAsync(statuses);
        await _context.SaveChangesAsync();

        return statuses.Count;
    }

    /// <summary>
    /// Seeds nine inventory category lookup rows for a company: Powder, Primer, Cleaner,
    /// Masking Supplies, Abrasive Media, Chemicals, Consumables, Tools, and Other.
    /// </summary>
    /// <remarks>
    /// Inventory categories are a lookup table so operators can rename them or add custom
    /// categories.  The <c>CategoryCode</c> strings (e.g., "POWDER", "CLEANER") are used by
    /// <see cref="SeedInventoryItemsAsync"/> to resolve the correct category FK when creating
    /// demo inventory items — they must not be changed without also updating that seeder.
    ///
    /// The <c>IsCoating = true</c> flag on POWDER and PRIMER distinguishes coating materials
    /// from consumables; the pricing engine uses this flag to identify which inventory items
    /// can be selected as powder coats on a quote/job item.
    ///
    /// Idempotency check: bails early if 9 or more rows exist for the company.
    /// </remarks>
    /// <param name="company">The tenant company to seed inventory categories for.</param>
    /// <returns>The number of category rows created (9), or 0 if already seeded.</returns>
    private async Task<int> SeedInventoryCategoryLookupsAsync(Company company)
    {
        // Check if categories already exist for this company
        var existingCount = await _context.Set<InventoryCategoryLookup>()
            .IgnoreQueryFilters()
            .CountAsync(c => c.CompanyId == company.Id && !c.IsDeleted);

        if (existingCount >= 9)
        {
            return 0; // Already seeded
        }

        var categories = new List<InventoryCategoryLookup>
        {
            new InventoryCategoryLookup
            {
                CategoryCode = "POWDER",
                DisplayName = "Powder",
                DisplayOrder = 1,
                Description = "Powder coating materials",
                IsActive = true,
                IsSystemDefined = false,
                IsCoating = true,
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new InventoryCategoryLookup
            {
                CategoryCode = "PRIMER",
                DisplayName = "Primer",
                DisplayOrder = 2,
                Description = "Primer coatings",
                IsActive = true,
                IsSystemDefined = false,
                IsCoating = true,
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new InventoryCategoryLookup
            {
                CategoryCode = "CLEANER",
                DisplayName = "Cleaner",
                DisplayOrder = 3,
                Description = "Cleaning solutions and materials",
                IsActive = true,
                IsSystemDefined = false,
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new InventoryCategoryLookup
            {
                CategoryCode = "MASKING",
                DisplayName = "Masking Supplies",
                DisplayOrder = 4,
                Description = "Masking tape, plugs, and supplies",
                IsActive = true,
                IsSystemDefined = false,
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new InventoryCategoryLookup
            {
                CategoryCode = "ABRASIVE",
                DisplayName = "Abrasive Media",
                DisplayOrder = 5,
                Description = "Sandblasting and abrasive materials",
                IsActive = true,
                IsSystemDefined = false,
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new InventoryCategoryLookup
            {
                CategoryCode = "CHEMICAL",
                DisplayName = "Chemicals",
                DisplayOrder = 6,
                Description = "Chemical supplies and solutions",
                IsActive = true,
                IsSystemDefined = false,
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new InventoryCategoryLookup
            {
                CategoryCode = "CONSUMABLE",
                DisplayName = "Consumables",
                DisplayOrder = 7,
                Description = "General consumable supplies",
                IsActive = true,
                IsSystemDefined = false,
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new InventoryCategoryLookup
            {
                CategoryCode = "TOOL",
                DisplayName = "Tools",
                DisplayOrder = 8,
                Description = "Tools and equipment supplies",
                IsActive = true,
                IsSystemDefined = false,
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new InventoryCategoryLookup
            {
                CategoryCode = "OTHER",
                DisplayName = "Other",
                DisplayOrder = 9,
                Description = "Other miscellaneous inventory items",
                IsActive = true,
                IsSystemDefined = false,
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            }
        };

        await _context.Set<InventoryCategoryLookup>().AddRangeAsync(categories);
        await _context.SaveChangesAsync();

        return categories.Count;
    }

    /// <summary>
    /// Seeds eight standard surface-preparation services for a company: Sandblasting, Chemical
    /// Stripping, Hand Sanding, Media Blasting, Iron Phosphate Wash, Degreasing, Masking, and
    /// Outgassing.
    /// </summary>
    /// <remarks>
    /// Prep services are selectable line-item additions on quote and job items, each adding
    /// labour cost to the pricing calculation.  They are stored per-company so operators can
    /// rename, deactivate, or add custom services (e.g., "Zinc Phosphate Wash") without
    /// affecting other tenants.
    ///
    /// Idempotency check: bails if any rows exist for the company (count > 0), unlike
    /// status lookups which use a minimum-count threshold.  This is intentional: if a
    /// partial seed left only some services, the operator can remove them and re-run to get
    /// the full set.
    ///
    /// Outgassing (pre-bake to release trapped gases from castings) is included because it is
    /// a mandatory step for cast aluminium and cast iron parts and is a common source of
    /// rework if omitted — including it in the default list helps new operators remember to
    /// quote it.
    /// </remarks>
    /// <param name="company">The tenant company to seed prep services for.</param>
    /// <returns>The number of prep service rows created (8), or 0 if any already existed.</returns>
    private async Task<int> SeedPrepServicesAsync(Company company)
    {
        var existingCount = await _context.Set<PrepService>()
            .IgnoreQueryFilters()
            .CountAsync(s => s.CompanyId == company.Id && !s.IsDeleted);

        if (existingCount > 0)
            return 0; // Already seeded

        var services = new List<PrepService>
        {
            new PrepService
            {
                ServiceName = "Sandblasting",
                Description = "Abrasive blasting to remove rust, old coatings, and surface contaminants",
                DisplayOrder = 1,
                IsActive = true,
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new PrepService
            {
                ServiceName = "Chemical Stripping",
                Description = "Chemical bath or application to strip existing paint or coatings",
                DisplayOrder = 2,
                IsActive = true,
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new PrepService
            {
                ServiceName = "Hand Sanding",
                Description = "Manual sanding to smooth surfaces and improve adhesion",
                DisplayOrder = 3,
                IsActive = true,
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new PrepService
            {
                ServiceName = "Media Blasting",
                Description = "Blasting with glass beads, walnut shells, or other media for delicate surfaces",
                DisplayOrder = 4,
                IsActive = true,
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new PrepService
            {
                ServiceName = "Iron Phosphate Wash",
                Description = "Chemical pre-treatment wash to improve powder adhesion and corrosion resistance",
                DisplayOrder = 5,
                IsActive = true,
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new PrepService
            {
                ServiceName = "Degreasing",
                Description = "Solvent or aqueous cleaning to remove oils, grease, and shop soils",
                DisplayOrder = 6,
                IsActive = true,
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new PrepService
            {
                ServiceName = "Masking",
                Description = "Masking of threads, holes, or areas that must remain uncoated",
                DisplayOrder = 7,
                IsActive = true,
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            },
            new PrepService
            {
                ServiceName = "Outgassing",
                Description = "Pre-bake cycle to release trapped gases from castings before coating",
                DisplayOrder = 8,
                IsActive = true,
                CompanyId = company.Id,
                CreatedAt = DateTime.UtcNow
            }
        };

        await _context.Set<PrepService>().AddRangeAsync(services);
        await _context.SaveChangesAsync();

        return services.Count;
    }
}
