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

namespace PowderCoating.Core.Entities;

public class Job : BaseEntity
{
    public string JobNumber { get; set; } = string.Empty;
    public int CustomerId { get; set; }
    public int? QuoteId { get; set; }
    public string? AssignedUserId { get; set; }  // Assigned user
    
    public string Description { get; set; } = string.Empty;

    // Lookup foreign keys (replacing enums)
    public int JobStatusId { get; set; }
    public int JobPriorityId { get; set; }
    
    // Dates
    public DateTime? ScheduledDate { get; set; }
    public DateTime? StartedDate { get; set; }
    public DateTime? CompletedDate { get; set; }
    public DateTime? DueDate { get; set; }
    
    // Selected oven (carried over from quote; null = company default rate)
    public int? OvenCostId { get; set; }

    // Oven scheduling (carried over from quote)
    public int OvenBatches { get; set; } = 1;
    public int? OvenCycleMinutes { get; set; }

    // Pricing
    public decimal QuotedPrice { get; set; }
    public decimal FinalPrice { get; set; }
    public decimal OvenBatchCost { get; set; }
    public decimal ShopSuppliesAmount { get; set; }
    public decimal ShopSuppliesPercent { get; set; }

    // Discount & rush (mirrors quote fields; preserved through quote→job conversion and job edits)
    public bool IsRushJob { get; set; }
    public DiscountType DiscountType { get; set; } = DiscountType.None;
    public decimal DiscountValue { get; set; }
    public string? DiscountReason { get; set; }

    // Job Completion Details
    public decimal? ActualTimeSpentHours { get; set; }

    // Additional Information
    public string? CustomerPO { get; set; }
    public string? ProjectName { get; set; }
    public string? SpecialInstructions { get; set; }
    public string? InternalNotes { get; set; }  // Internal notes from quote
    public string? Tags { get; set; }
    public bool RequiresCustomerApproval { get; set; }
    public bool IsCustomerApproved { get; set; }

    // Shop floor QR access token (no login required; scoped to this job only)
    public Guid ShopAccessCode { get; set; } = Guid.NewGuid();

    // Part intake / receiving
    public DateTime? IntakeDate { get; set; }
    public string? IntakeConditionNotes { get; set; }
    public int? IntakePartCount { get; set; }
    public string? IntakeCheckedByUserId { get; set; }

    // Quote snapshot — UpdatedAt of the source quote at the moment this job was created from it.
    // Used to detect when the quote was subsequently edited so the job details page can warn the user.
    public DateTime? QuoteSnapshotUpdatedAt { get; set; }

    // Pricing snapshot — serialized QuotePricingBreakdownDto stored at save time so Details displays
    // the breakdown that was actually calculated, not a re-run against current operating costs.
    public string? PricingBreakdownJson { get; set; }

    // Rework tracking
    public bool IsReworkJob { get; set; }
    public int? OriginalJobId { get; set; }       // Set when this job was created as a rework
    
    // Relationships
    [ForeignKey("IntakeCheckedByUserId")]
    public virtual ApplicationUser? IntakeCheckedBy { get; set; }
    public virtual OvenCost? OvenCost { get; set; }
    public virtual Customer Customer { get; set; } = null!;
    public virtual Quote? Quote { get; set; }
    public virtual ApplicationUser? AssignedUser { get; set; }
    public virtual JobStatusLookup JobStatus { get; set; } = null!;
    public virtual JobPriorityLookup JobPriority { get; set; } = null!;
    public virtual ICollection<JobItem> JobItems { get; set; } = new List<JobItem>();
    public virtual ICollection<JobPhoto> Photos { get; set; } = new List<JobPhoto>();
    public virtual ICollection<JobNote> Notes { get; set; } = new List<JobNote>();
    public virtual ICollection<JobStatusHistory> StatusHistory { get; set; } = new List<JobStatusHistory>();
    public virtual ICollection<JobPrepService> JobPrepServices { get; set; } = new List<JobPrepService>();
    public virtual Invoice? Invoice { get; set; }
    public virtual ICollection<JobTimeEntry> TimeEntries { get; set; } = new List<JobTimeEntry>();
    public virtual ICollection<ReworkRecord> ReworkRecords { get; set; } = new List<ReworkRecord>();
    public virtual Job? OriginalJob { get; set; }
}
