using foodmarket.Domain.Common;

namespace foodmarket.Domain.Catalog;

public class Product : TenantEntity
{
    public string Name { get; set; } = null!;
    public string? Article { get; set; }             // артикул
    public string? Description { get; set; }

    public Guid UnitOfMeasureId { get; set; }
    public UnitOfMeasure? UnitOfMeasure { get; set; }

    // Ставка НДС в процентах, decimal(5,2) — например 16.00 или 0.00. Дефолт
    // при создании берётся из Country.VatRate организации, пользователь может
    // менять для исключений (хлеб = 0.00 и т.п.) — но только если в настройках
    // включена галка «Указывать ставку НДС на товаре». VatEnabled управляет
    // лишь видимостью поля Vat в UI: снята — поле скрыто, включена — поле
    // с текущей ставкой. Семантика «в том числе/сверху» — на уровне документа.
    public decimal Vat { get; set; }
    public bool VatEnabled { get; set; } = true;

    public Guid ProductGroupId { get; set; }
    public ProductGroup? ProductGroup { get; set; }

    public Guid? DefaultSupplierId { get; set; }     // основной поставщик
    public Counterparty? DefaultSupplier { get; set; }

    public Guid? CountryOfOriginId { get; set; }     // страна происхождения
    public Country? CountryOfOrigin { get; set; }

    public bool IsService { get; set; }              // услуга, а не физический товар
    public Packaging Packaging { get; set; } = Packaging.Piece; // фасовка (штучный/весовой/разливной)
    public bool IsMarked { get; set; }               // маркируемый (Datamatrix)

    public decimal? MinStock { get; set; }           // минимальный остаток (для уведомлений)
    public decimal? MaxStock { get; set; }           // максимальный остаток (для автозаказа)

    /// <summary>«Эталонная» (справочная) цена закупа. Не обязательная.
    /// Автоматически заполняется UnitPrice'ом первой проведённой приёмки.
    /// Через 30 дней без новых приёмок Hangfire-job переписывает на текущую Cost.</summary>
    public decimal? ReferencePrice { get; set; }
    public DateTime? ReferencePriceUpdatedAt { get; set; }
    public Guid? PurchaseCurrencyId { get; set; }
    public Currency? PurchaseCurrency { get; set; }

    /// <summary>Себестоимость по скользящему среднему. Пересчитывается на каждой
    /// проведённой приёмке: (qty_old * cost_old + qty_in * price_in) / (qty_old + qty_in).
    /// Хранится с 4 знаками для точности; UI показывает 2.</summary>
    public decimal Cost { get; set; }

    /// <summary>UTC-метка последней проведённой приёмки. Используется
    /// 30-дневной job для перезаписи ReferencePrice на текущую Cost.</summary>
    public DateTime? LastSupplyAt { get; set; }

    public string? ImageUrl { get; set; }            // основное изображение (остальные в ProductImage)

    public ICollection<ProductPrice> Prices { get; set; } = [];
    public ICollection<ProductBarcode> Barcodes { get; set; } = [];
    public ICollection<ProductImage> Images { get; set; } = [];
}
