using foodmarket.Domain.Catalog;
using foodmarket.Domain.Common;

namespace foodmarket.Domain.Inventory;

public enum LossStatus
{
    Draft = 0,
    Posted = 1,
}

/// <summary>Причина списания. Из этого классификатора строятся ABC/XYZ-отчёты
/// и фискальная отчётность (порча/просрочка) в KZ. Не строй наценочную логику
/// поверх этих значений — используй ровно как business reason.</summary>
public enum LossReason
{
    /// <summary>Брак (производственный/транспортный).</summary>
    Defect = 0,
    /// <summary>Просрочка / истёк срок годности.</summary>
    Expired = 1,
    /// <summary>Повреждение (механическое, при хранении/перевозке).</summary>
    Damage = 2,
    /// <summary>Недостача (выявлена инвентаризацией; для оформления свыше — отдельный документ инвентаризации).</summary>
    Shortage = 3,
    /// <summary>Прочая причина (в комментарии).</summary>
    Other = 99,
}

/// <summary>Документ списания со склада: брак, просрочка, недостача, повреждение.
/// При проведении создаёт <see cref="StockMovement"/> с типом
/// <see cref="MovementType.WriteOff"/> и отрицательным Quantity.</summary>
public class Loss : TenantEntity
{
    public string Number { get; set; } = "";
    public DateTime Date { get; set; } = DateTime.UtcNow;
    public LossStatus Status { get; set; } = LossStatus.Draft;

    public Guid StoreId { get; set; }
    public Store Store { get; set; } = null!;

    public Guid CurrencyId { get; set; }
    public Currency Currency { get; set; } = null!;

    public LossReason Reason { get; set; } = LossReason.Other;

    public string? Notes { get; set; }

    /// <summary>Сумма по строкам = Σ Quantity·UnitCost. Балансовая стоимость списания.</summary>
    public decimal Total { get; set; }

    public DateTime? PostedAt { get; set; }
    public Guid? PostedByUserId { get; set; }

    public ICollection<LossLine> Lines { get; set; } = new List<LossLine>();
}

public class LossLine : TenantEntity
{
    public Guid LossId { get; set; }
    public Loss Loss { get; set; } = null!;

    public Guid ProductId { get; set; }
    public Product Product { get; set; } = null!;

    public decimal Quantity { get; set; }
    /// <summary>Балансовая цена единицы (снимок Product.Cost на момент создания строки;
    /// можно переопределить). Используется в Total и в отчётности.</summary>
    public decimal UnitCost { get; set; }
    public decimal LineTotal { get; set; }

    public int SortOrder { get; set; }
}
