using System.ComponentModel.DataAnnotations;
using PowderCoating.Core.Enums;

namespace PowderCoating.Application.DTOs.Wizard;

/// <summary>
/// Tracks the current user's wizard progress (read from CompanyPreferences)
/// </summary>
public class WizardProgressDto
{
    public bool Started { get; set; }
    public bool Completed { get; set; }
    public List<int> DoneSteps { get; set; } = new();
    public List<int> SkippedSteps { get; set; } = new();
    public const int TotalSteps = 5;

    public bool IsStepDone(int step) => DoneSteps.Contains(step);
    public bool IsStepSkipped(int step) => SkippedSteps.Contains(step);
    public bool IsStepTouched(int step) => IsStepDone(step) || IsStepSkipped(step);

    // Capped at TotalSteps so old step data from a larger wizard doesn't overflow the display.
    public int CompletedCount => Math.Min(DoneSteps.Count + SkippedSteps.Count, TotalSteps);
    public int ProgressPercent => TotalSteps == 0 ? 0 : (int)Math.Round((double)CompletedCount / TotalSteps * 100);
}

// ─── Step 1: Company Profile ────────────────────────────────────────────────
public class WizardStep1Dto
{
    [Required, MaxLength(200)]
    [Display(Name = "Company Name")]
    public string CompanyName { get; set; } = string.Empty;

    [MaxLength(200)]
    [Display(Name = "Primary Contact Name")]
    public string? PrimaryContactName { get; set; }

    [EmailAddress, MaxLength(200)]
    [Display(Name = "Primary Contact Email")]
    public string? PrimaryContactEmail { get; set; }

    [Phone, MaxLength(50)]
    [Display(Name = "Phone")]
    public string? Phone { get; set; }

    [MaxLength(300)]
    [Display(Name = "Address")]
    public string? Address { get; set; }

    [MaxLength(100)]
    [Display(Name = "City")]
    public string? City { get; set; }

    [MaxLength(100)]
    [Display(Name = "State")]
    public string? State { get; set; }

    [MaxLength(20)]
    [Display(Name = "ZIP Code")]
    public string? ZipCode { get; set; }

    [MaxLength(100)]
    [Display(Name = "Time Zone")]
    public string? TimeZone { get; set; }

    [MaxLength(10)]
    [Display(Name = "Default Currency")]
    public string DefaultCurrency { get; set; } = "USD";

    [Display(Name = "Use Metric System (metres / kilograms)")]
    public bool UseMetricSystem { get; set; } = false;
}

// ─── Step 2: QuickBooks Migration ───────────────────────────────────────────
public class WizardStep2QbDto
{
    public bool MigratingFromQuickBooks { get; set; } = false;
}

// ─── Step 3: Operating Costs (was Step 2) ───────────────────────────────────
public class WizardStep2Dto
{
    [Range(0, 10000)]
    [Display(Name = "Standard Labor Rate ($/hr)")]
    public decimal StandardLaborRate { get; set; }

    [Range(0, 10000)]
    [Display(Name = "Sandblaster Cost ($/hr)")]
    public decimal SandblasterCostPerHour { get; set; }

    [Range(0, 10000)]
    [Display(Name = "Coating Booth Cost ($/hr)")]
    public decimal CoatingBoothCostPerHour { get; set; }

    [Range(0, 10000)]
    [Display(Name = "Oven Operating Cost ($/hr)")]
    public decimal OvenOperatingCostPerHour { get; set; }

    [Range(0, 1000)]
    [Display(Name = "Powder Coating Cost ($/sq ft)")]
    public decimal PowderCoatingCostPerSqFt { get; set; }

    [Range(0, 100)]
    [Display(Name = "General Markup (%)")]
    public decimal GeneralMarkupPercentage { get; set; }

    [Range(0, 100)]
    [Display(Name = "Tax Rate (%)")]
    public decimal TaxPercent { get; set; }

    [Range(0, 100000)]
    [Display(Name = "Shop Minimum Charge ($)")]
    public decimal ShopMinimumCharge { get; set; }

    [Display(Name = "Shop Capability Tier")]
    public ShopCapabilityTier ShopCapabilityTier { get; set; } = ShopCapabilityTier.Small;

    // Facility Overhead
    [Range(0, 1000000)]
    [Display(Name = "Monthly Rent ($)")]
    public decimal MonthlyRent { get; set; } = 0m;

    [Range(0, 1000000)]
    [Display(Name = "Monthly Utilities ($)")]
    public decimal MonthlyUtilities { get; set; } = 0m;

    [Range(1, 10000)]
    [Display(Name = "Billable Hours/Month")]
    public int MonthlyBillableHours { get; set; } = 160;
}

// ─── Step 3: Branding & Numbering ───────────────────────────────────────────
public class WizardStep3Dto
{
    [MaxLength(10)]
    [Display(Name = "Quote Number Prefix")]
    public string QuoteNumberPrefix { get; set; } = "QT";

    [MaxLength(10)]
    [Display(Name = "Job Number Prefix")]
    public string JobNumberPrefix { get; set; } = "JOB";

    [MaxLength(10)]
    [Display(Name = "Invoice Number Prefix")]
    public string InvoiceNumberPrefix { get; set; } = "INV";

    [MaxLength(7)]
    [Display(Name = "Quote Accent Color")]
    public string QtAccentColor { get; set; } = "#374151";

    [MaxLength(7)]
    [Display(Name = "Invoice Accent Color")]
    public string InAccentColor { get; set; } = "#374151";

    [MaxLength(7)]
    [Display(Name = "Work Order Accent Color")]
    public string WoAccentColor { get; set; } = "#374151";
}

// ─── Step 4: Invoice & Quote Defaults ───────────────────────────────────────
public class WizardStep4Dto
{
    [MaxLength(100)]
    [Display(Name = "Default Payment Terms")]
    public string DefaultPaymentTerms { get; set; } = "Net 30";

    [Range(1, 365)]
    [Display(Name = "Quote Validity (days)")]
    public int DefaultQuoteValidityDays { get; set; } = 30;

    [Range(1, 365)]
    [Display(Name = "Default Turnaround (days)")]
    public int DefaultTurnaroundDays { get; set; } = 7;

    [MaxLength(2000)]
    [Display(Name = "Default Quote Terms & Conditions")]
    public string? QtDefaultTerms { get; set; }

    [MaxLength(500)]
    [Display(Name = "Quote Footer Note")]
    public string? QtFooterNote { get; set; }
}

// ─── Step 5: Job & Workflow ──────────────────────────────────────────────────
public class WizardStep5Dto
{
    [Display(Name = "Default Job Priority")]
    public string DefaultJobPriority { get; set; } = "Normal";

    [Display(Name = "Require Customer PO Number")]
    public bool RequireCustomerPO { get; set; } = false;

    [Display(Name = "Allow Customer Approval via Link")]
    public bool AllowCustomerApproval { get; set; } = true;

}

// ─── Step 6: Chart of Accounts (review only) ────────────────────────────────
public class WizardStep6Dto
{
    public int AccountCount { get; set; }
    public int RevenueAccounts { get; set; }
    public int ExpenseAccounts { get; set; }
    public int AssetAccounts { get; set; }
}

// ─── Step 7: Notification Preferences ───────────────────────────────────────
public class WizardStep7Dto
{
    [Display(Name = "Enable Email Notifications")]
    public bool EmailNotificationsEnabled { get; set; } = true;

    [EmailAddress, MaxLength(200)]
    [Display(Name = "Send Emails From Address")]
    public string? EmailFromAddress { get; set; }

    [MaxLength(200)]
    [Display(Name = "From Display Name")]
    public string? EmailFromName { get; set; }

    [Display(Name = "Notify on New Job Created")]
    public bool NotifyOnNewJob { get; set; } = true;

    [Display(Name = "Notify on New Quote Created")]
    public bool NotifyOnNewQuote { get; set; } = true;

    [Display(Name = "Notify on Job Status Change")]
    public bool NotifyOnJobStatusChange { get; set; } = true;

    [Display(Name = "Notify on Quote Approval")]
    public bool NotifyOnQuoteApproval { get; set; } = true;

    [Display(Name = "Notify on Payment Received")]
    public bool NotifyOnPaymentReceived { get; set; } = true;

    [Display(Name = "Enable Automated Payment Reminders")]
    public bool PaymentRemindersEnabled { get; set; } = false;

    [MaxLength(50)]
    [Display(Name = "Reminder Days (comma-separated, days past due)")]
    public string PaymentReminderDays { get; set; } = "7,14,30";

    // Alert Thresholds
    [Range(0, 90)]
    [Display(Name = "Quote Expiry Warning (days before expiry)")]
    public int QuoteExpiryWarningDays { get; set; } = 3;

    [Range(0, 90)]
    [Display(Name = "Due Date Warning (days before due)")]
    public int DueDateWarningDays { get; set; } = 2;

    [Range(0, 90)]
    [Display(Name = "Maintenance Alert (days before scheduled date)")]
    public int MaintenanceAlertDays { get; set; } = 7;
}

// ─── Step 8: Inventory / Powder Colors ──────────────────────────────────────
public class WizardStep8Dto
{
    /// <summary>JSON array of WizardInventoryItemDto submitted as a hidden field</summary>
    public string? ItemsJson { get; set; }
}

public class WizardInventoryItemDto
{
    public string Name { get; set; } = string.Empty;
    public string? ColorName { get; set; }
    public string? ColorCode { get; set; }
    public string? Manufacturer { get; set; }
    public string? Finish { get; set; }
    public decimal UnitCost { get; set; }
    public decimal QuantityOnHand { get; set; }
}

// ─── Step 9: Team Members ────────────────────────────────────────────────────
public class WizardStep9Dto
{
    /// <summary>JSON array of WizardTeamMemberDto submitted as a hidden field</summary>
    public string? MembersJson { get; set; }
}

public class WizardTeamMemberDto
{
    public string FirstName { get; set; } = string.Empty;
    public string LastName { get; set; } = string.Empty;
    public string Email { get; set; } = string.Empty;
    public string Password { get; set; } = string.Empty;
    public string CompanyRole { get; set; } = "Worker";
}

// ─── Step 10: Vendors & Suppliers ────────────────────────────────────────────
public class WizardStep10Dto
{
    /// <summary>JSON array of WizardVendorDto submitted as a hidden field</summary>
    public string? VendorsJson { get; set; }
}

public class WizardVendorDto
{
    public string CompanyName { get; set; } = string.Empty;
    public string? ContactName { get; set; }
    public string? Email { get; set; }
    public string? Phone { get; set; }
    public string? Website { get; set; }
}

// ─── Step 14: Equipment / Named Ovens + Blast Setups ────────────────────────
public class WizardOvensStepDto
{
    /// <summary>JSON array of WizardOvenDto submitted as a hidden field</summary>
    public string? OvensJson { get; set; }

    /// <summary>JSON array of WizardBlastSetupDto submitted as a hidden field</summary>
    public string? BlastSetupsJson { get; set; }
}

public class WizardOvenDto
{
    public int Id { get; set; }
    public string Label { get; set; } = string.Empty;
    public decimal CostPerHour { get; set; }
    public decimal? MaxLoadSqFt { get; set; }
    public int? DefaultCycleMinutes { get; set; }
}

public class WizardBlastSetupDto
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    /// <summary>Maps to BlastSetupType enum: 0=SiphonCabinet, 1=SiphonPot, 2=PressurePot, 3=WetBlasting</summary>
    public int SetupType { get; set; } = 2;
    public decimal CompressorCfm { get; set; }
    /// <summary>Nozzle orifice number 2–8.</summary>
    public int BlastNozzleSize { get; set; } = 5;
    /// <summary>Maps to BlastSubstrateType enum: 0=Paint, 1=PowderCoat, 2=RustAndScale, 3=Mixed</summary>
    public int PrimarySubstrate { get; set; } = 3;
    public decimal? BlastRateSqFtPerHourOverride { get; set; }
    public bool IsDefault { get; set; }
}

// ─── Step 15: Pricing Tiers ──────────────────────────────────────────────────
public class WizardPricingTiersStepDto
{
    /// <summary>JSON array of WizardPricingTierDto submitted as a hidden field</summary>
    public string? TiersJson { get; set; }
}

public class WizardPricingTierDto
{
    public int Id { get; set; }
    public string TierName { get; set; } = string.Empty;
    public string? Description { get; set; }
    public decimal DiscountPercent { get; set; }
}

// ─── Step 16: Service Catalog ────────────────────────────────────────────────
public class WizardCatalogStepDto
{
    /// <summary>JSON array of WizardCatalogItemDto submitted as a hidden field</summary>
    public string? ItemsJson { get; set; }
}

public class WizardCatalogItemDto
{
    public string Name { get; set; } = string.Empty;
    public string? Description { get; set; }
    public decimal DefaultPrice { get; set; }
    public decimal? ApproximateArea { get; set; }
}
