using System.ComponentModel.DataAnnotations;

namespace JobsMedical.Web.Models;

/// <summary>
/// An open shift at a facility. The heart of the platform.
/// Dates are stored as UTC <see cref="DateOnly"/>/<see cref="TimeOnly"/> and displayed as Jalali.
/// </summary>
public class Shift
{
    public int Id { get; set; }

    public int FacilityId { get; set; }
    public Facility Facility { get; set; } = null!;

    public int RoleId { get; set; }                  // نقش مورد نیاز (پزشک/پرستار/ماما/...)
    public Role Role { get; set; } = null!;

    public DateOnly Date { get; set; }               // تاریخ شیفت (در نمایش به شمسی تبدیل می‌شود)
    public TimeOnly StartTime { get; set; }          // ساعت شروع
    public TimeOnly EndTime { get; set; }            // ساعت پایان

    [MaxLength(100)]
    public string SpecialtyRequired { get; set; } = "پزشک عمومی";

    public ShiftType ShiftType { get; set; } = ShiftType.Day;

    public long? PayAmount { get; set; }             // مبلغ مقطوع (تومان)؛ null اگر فقط درصدی/توافقی
    public int? SharePercent { get; set; }           // سهم درآمد (٪)؛ مثلاً ۵۰. می‌تواند همراه مبلغ هم باشد
    public PayType PayType { get; set; } = PayType.PerShift;

    public Gender GenderRequirement { get; set; } = Gender.Any;  // جنسیت مورد نیاز

    [MaxLength(1500)]
    public string? Description { get; set; }         // توضیحات

    public ShiftStatus Status { get; set; } = ShiftStatus.Open;
    public ShiftSource Source { get; set; } = ShiftSource.Admin;

    [MaxLength(500)]
    public string? SourceUrl { get; set; }           // لینک منبع در صورت جمع‌آوری از کانال

    // APPROXIMATE coords from the source ad (Divar's privacy-fuzzed center) for aggregated shifts
    // whose facility has no address. Shown as a «محدودهٔ تقریبی» circle, never a precise pin.
    public double? Lat { get; set; }
    public double? Lng { get; set; }

    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;

    public ICollection<Application> Applications { get; set; } = new List<Application>();

    /// <summary>Contact channels harvested from the source ad (aggregated shifts). When empty, the
    /// detail page falls back to the facility's phone.</summary>
    public ICollection<ContactMethod> Contacts { get; set; } = new List<ContactMethod>();

    // Transient: distance (km) from the visitor when "near me" is active. Not persisted.
    [System.ComponentModel.DataAnnotations.Schema.NotMapped]
    public double? DistanceKm { get; set; }

    // Convenience (not mapped): duration in hours, handles overnight shifts.
    public double DurationHours
    {
        get
        {
            var span = EndTime.ToTimeSpan() - StartTime.ToTimeSpan();
            if (span <= TimeSpan.Zero) span += TimeSpan.FromDays(1); // شیفت شب که به روز بعد می‌رسد
            return span.TotalHours;
        }
    }
}
