namespace PowderCoating.Application.DTOs.AI;

/// <summary>Request payload sent from JS wizard to the AiAnalyzeItem endpoint.</summary>
public class AiAnalyzeItemRequest
{
    /// <summary>TempIds of already-uploaded photos.</summary>
    public List<string> PhotoTempIds { get; set; } = new();

    // User-supplied context
    public string ReferenceDimension { get; set; } = string.Empty;   // e.g. "longest edge is 18 inches"
    public int Quantity { get; set; } = 1;
    public string DesiredColor { get; set; } = string.Empty;
    public int CoatCount { get; set; } = 1;

    /// <summary>Material type — helps AI factor in prep, outgassing, cure time (e.g. "Cast Iron", "Aluminum").</summary>
    public string? MaterialType { get; set; }

    /// <summary>Approximate weight in lbs per piece — used to factor heavy-handling surcharge into time estimate.</summary>
    public decimal? EstimatedWeightLbs { get; set; }

    // Follow-up support (null on first call)
    public List<AiConversationTurn>? ConversationHistory { get; set; }
    public string? FollowUpAnswer { get; set; }

    public int CompanyId { get; set; }

    /// <summary>
    /// Id of the <see cref="CompanyBlastSetup"/> the user selected before analyzing.
    /// When set, the controller loads that setup and passes it to the AI service so the
    /// correct blast rate is injected into the prompt.
    /// </summary>
    public int? BlastSetupId { get; set; }
}

public class AiConversationTurn
{
    public string Role { get; set; } = string.Empty;    // "user" | "assistant"
    public string Content { get; set; } = string.Empty;
}

/// <summary>Result returned to the JS wizard from AI analysis.</summary>
public class AiAnalyzeItemResult
{
    public bool Success { get; set; }
    public string? ErrorMessage { get; set; }

    // When NeedsFollowUp is true, the wizard shows FollowUpQuestion to the user
    public bool NeedsFollowUp { get; set; }
    public string? FollowUpQuestion { get; set; }
    public int FollowUpRound { get; set; }   // 1 or 2

    // Final item data (populated when NeedsFollowUp is false)
    public string? Description { get; set; }
    public decimal SurfaceAreaSqFt { get; set; }
    public string Complexity { get; set; } = "Moderate";     // Simple|Moderate|Complex|Extreme
    public int EstimatedMinutes { get; set; }
    public string? AiReasoning { get; set; }
    public string Confidence { get; set; } = "Medium";       // Low|Medium|High

    // Pricing preview (filled by server using company operating costs)
    public decimal EstimatedUnitPrice { get; set; }
    public decimal EstimatedTotal { get; set; }
    public decimal PowderCostPerLb { get; set; }
    public decimal CoverageSqFtPerLb { get; set; } = 30m;
    public decimal TransferEfficiency { get; set; } = 65m;

    // Raw conversation to pass back for follow-up round 2
    public List<AiConversationTurn> ConversationHistory { get; set; } = new();

    // AI-generated standardized tags from fixed taxonomy
    public List<string> Tags { get; set; } = new();

    // Historical price benchmark from completed jobs
    public AiBenchmarkResult? Benchmark { get; set; }

    // ID of the persisted AiItemPrediction record — returned on final result (not follow-up rounds).
    // The JS wizard stores this per-item so the controller can link prediction to QuoteItem/JobItem on save.
    public int? AiPredictionId { get; set; }

    // Pricing breakdown — helps users understand and sanity-check the estimate
    public AiPricingBreakdown? Breakdown { get; set; }
}

/// <summary>
/// Display-only cost breakdown returned to the client.
/// Contains computed dollar amounts only — rates, percentages, and coverage constants are intentionally excluded.
/// </summary>
public class AiPricingBreakdown
{
    public decimal SurfaceAreaSqFt { get; set; }
    public decimal PowderLbsPerCoat { get; set; }
    public int CoatCount { get; set; }
    public decimal MaterialCost { get; set; }
    public decimal ConsumablesCost { get; set; }
    public int EstimatedMinutes { get; set; }
    /// <summary>Non-zero when a material-type minimum floor exists for this material.</summary>
    public int MaterialMinMinutes { get; set; }
    /// <summary>True when the floor was actually applied (AI returned less than the floor).</summary>
    public bool MinFloorApplied { get; set; }
    public decimal LaborCost { get; set; }
    public int OvenCycleMinutes { get; set; }
    public decimal OvenCost { get; set; }
    public bool RequiresPreheat { get; set; }
    public int PreheatMinutes { get; set; }
    public decimal PreheatCost { get; set; }
    public decimal SubtotalBeforeComplexity { get; set; }
    public string Complexity { get; set; } = string.Empty;
    public decimal ComplexityCharge { get; set; }
    public decimal SubtotalBeforeMarkup { get; set; }
    public decimal MarkupAmount { get; set; }
    public decimal UnitPrice { get; set; }
}

/// <summary>Request to recalculate AI item price when the user overrides sq ft, minutes, or complexity.</summary>
public class AiRecalcPriceRequest
{
    public decimal SurfaceAreaSqFt { get; set; }
    public int EstimatedMinutes { get; set; }
    public string Complexity { get; set; } = "Moderate";
    public int CoatCount { get; set; } = 1;
}

/// <summary>Result of a price recalculation — returns the new unit price and a display-safe breakdown.</summary>
public class AiRecalcPriceResult
{
    public bool Success { get; set; }
    public decimal UnitPrice { get; set; }
    public AiPricingBreakdown? Breakdown { get; set; }
}

/// <summary>Historical price benchmark from completed jobs with similar complexity and size.</summary>
public class AiBenchmarkResult
{
    public int MatchCount { get; set; }
    public decimal MinPrice { get; set; }
    public decimal MaxPrice { get; set; }
    public decimal AvgPrice { get; set; }
    public string ComplexityLevel { get; set; } = string.Empty;
    public decimal SqFtRangeMin { get; set; }
    public decimal SqFtRangeMax { get; set; }
}

/// <summary>
/// Company-specific AI context passed to the quote service on every analysis call.
/// Contains optional free-text profile and recent accepted predictions as few-shot calibration examples.
/// </summary>
public class CompanyAiContext
{
    /// <summary>Free-text description of the shop's specialties and pricing style (from Company Settings).</summary>
    public string? ProfileText { get; set; }

    /// <summary>Recent predictions the user accepted without override — used as few-shot calibration examples.</summary>
    public List<AiFewShotExample> AcceptedExamples { get; set; } = new();
}

/// <summary>A single accepted-prediction record formatted for AI few-shot context.</summary>
public class AiFewShotExample
{
    public string Description { get; set; } = string.Empty;
    public decimal SurfaceAreaSqFt { get; set; }
    public string Complexity { get; set; } = string.Empty;
    public int EstimatedMinutes { get; set; }
    public decimal FinalUnitPrice { get; set; }
    public string? Tags { get; set; }
}

/// <summary>Internal structured response that Claude returns as JSON.</summary>
public class ClaudeQuoteResponse
{
    public string Description { get; set; } = string.Empty;
    public decimal SurfaceAreaSqFt { get; set; }
    public string Complexity { get; set; } = "Moderate";
    public int EstimatedMinutes { get; set; }
    public bool RequiresPreheat { get; set; }
    public int PreheatMinutes { get; set; }
    public string Confidence { get; set; } = "Medium";
    public bool NeedsFollowUp { get; set; }
    public string? FollowUpQuestion { get; set; }
    public string Reasoning { get; set; } = string.Empty;
    public List<string> Tags { get; set; } = new();
}
