using Bp.Sync.Domain.Elastics.BaseEntities;
using Bp.Sync.Domain.Entities.Inventories;
using Bp.Sync.Domain.Entities.Inventories.Bills;
using System;
using System.ComponentModel.DataAnnotations.Schema;

namespace Bp.Sync.Domain.Elastics.Inventories.Bills
{
    public class InboundBillElastic : ElasticBaseEntityWithKey<long>
    {
        /// <summary>
        /// Mã phiếu
        /// </summary>
        public long BillId { get; set; }

        /// <summary>
        /// Id sản phẩm
        /// </summary>
        public long ProductId { get; set; }

        /// <summary>
        /// Id đơn vị tính
        /// </summary>
        public int UnitId { get; set; }

        /// <summary>
        /// Id vị trí
        /// </summary>
        public long LocationId { get; set; }

        /// <summary>
        /// Mã lưu kho
        /// </summary>
        public string InventoryCode { get; set; }

        /// <summary>
        /// Ngày nhập từ NCC ở phiếu nhập từ NCC
        /// </summary>
        public DateTimeOffset? InventoryCodeInboundCreatedTime { get; set; }

        /// <summary>
        /// Phiếu nhập từ NCC
        /// </summary>
        public long? InventoryCodeBillId { get; set; }

        /// <summary>
        /// Số lượng
        /// </summary>
        public decimal Quantity { get; set; }

        /// <summary>
        /// Giá nhập
        /// </summary>
        public decimal CostPrice { get; set; }

        /// <summary>
        /// Giá nhập vận hành
        /// </summary>
        public decimal OpsCostPrice
        {
            get
            {
                decimal discountAmount = 0;
                decimal taxAmount = 0;
                decimal amount = Quantity > 0 ? CostPrice * Quantity : CostPrice;

                if (Tax > 0)
                {
                    taxAmount += amount * Tax / 100;
                }
                if (TaxConfig > 0)
                {
                    if (PrepaidDiscount > 0)
                    {
                        taxAmount += ((amount - (amount * PrepaidDiscount / 100)) * TaxConfig) / 100;
                    }
                    else
                    {
                        taxAmount += amount * TaxConfig / 100;
                    }
                }
                if (PrepaidDiscount > 0)
                {
                    discountAmount += amount * PrepaidDiscount / 100;
                }
                if (PostpaidDiscount > 0)
                {
                    if (PostpaidDiscountType == PostpaidDiscountType.BeforeTax)
                    {
                        discountAmount += amount * PostpaidDiscount / 100;
                    }
                    else if (PostpaidDiscountType == PostpaidDiscountType.AfterTax)
                    {
                        discountAmount += ((amount + (amount * TaxConfig / 100)) * PostpaidDiscount) / 100;
                    }
                    else
                    {
                        discountAmount += amount * PostpaidDiscount / 100;
                    }
                }
                return Quantity > 0 ? (amount + taxAmount - discountAmount) / Quantity / Exchange : amount + taxAmount - discountAmount;
            }
        }

        /// <summary>
        /// Giá bình quân đã xuất trước đó cho chi nhánh
        /// </summary>
        public decimal PreCostPrice { get; set; }

        /// <summary>
        /// Giá bán lẻ
        /// </summary>
        public decimal Price { get; set; }

        /// <summary>
        /// Giá bán sỉ
        /// </summary>
        public decimal WholeSalePrice { get; set; }

        /// <summary>
        /// Chiết khấu
        /// </summary>
        public decimal Discount { get; set; }

        /// <summary>
        /// Thuế VAT
        /// </summary>
        public decimal Tax { get; set; }

        /// <summary>
        /// Trạng thái nhập kho
        /// </summary>
        public InboundStatus InboundStatus { get; set; } = InboundStatus.WaitToPrint;

        ///// <summary>
        ///// Mã tài khoản nợ
        ///// </summary>
        //public string DebitAccountCode { get; set; }
        ///// <summary>
        ///// Mã tài khoản thuế
        ///// </summary>
        //public string TaxAccountCode { get; set; }
        ///// <summary>
        ///// Mã tài khoản có
        ///// </summary>
        //public string CreditAccountCode { get; set; }
        /// <summary>
        /// Chiết khấu trả trước (%)
        /// </summary>
        [Column(TypeName = "decimal(18, 5)")]
        public decimal PrepaidDiscount { get; set; }

        /// <summary>
        /// Chiết khấu trả sau (%)
        /// </summary>
        [Column(TypeName = "decimal(18, 5)")]
        public decimal PostpaidDiscount { get; set; }

        /// <summary>
        /// Thời gian nhập kho
        /// </summary>
        public DateTimeOffset? CompletedTime { get; set; }

        /// <summary>
        /// Đã nhận được tiền chiết khấu (true)
        /// </summary>
        public bool? IsReceivedDiscount { get; set; }

        /// <summary>
        /// Loại chiết khấu trả sau (có trong cấu hình giá nhập)
        /// </summary>
        public PostpaidDiscountType PostpaidDiscountType { get; set; }

        /// <summary>
        /// Thuế VAT(%) trong cấu hình giá nhập kho
        /// </summary>
        [Column(TypeName = "decimal(18, 5)")]
        public decimal TaxConfig { get; set; }

        //tính toán
        //giá nhập
        public decimal TotalCostPrice => Quantity * CostPrice;

        //bo logic ngay 5/12
        //{
        //    get
        //    {
        //        var a = CostPrice * Quantity;
        //        if (Discount > 0) a *= 1 - Discount / 100m;
        //        if (Tax > 0) a *= 1 + Tax / 100m;
        //        return a;
        //    }
        //}
        /// <summary>
        /// Tổng tiền vận hành
        /// </summary>
        public decimal TotalOpsCostPrice => Quantity * OpsCostPrice;

        /// <summary>
        /// Tổng giá nhập chưa tính vat, chiết khấu...
        /// </summary>
        public decimal TotalNonPrice => CostPrice * Quantity;

        //nhập theo giá bình quân
        public decimal TotalPreCostPrice => PreCostPrice * Quantity;

        //giá bán dự kiến
        public decimal Amount => Price * Quantity;

        //Lợi nhuận dự kiến
        public decimal Revenue => Amount - CostPrice * Quantity;

        public decimal PreRevenue => Amount - PreCostPrice * Quantity;

        /// <summary>
        /// Phần trăm chênh lệch so với lần nhập gần nhất
        /// </summary>
        public decimal DifPriceRate
        {
            get
            {
                decimal value = 0;
                decimal dif = CostPrice - PreCostPrice;
                if (dif != 0 && PreCostPrice != 0) value = (decimal)dif * 100 / PreCostPrice;
                return value;
            }
        }

        //bổ sung

        public string ProductName { get; set; }
        public string ProductCode { get; set; }

        //đơn vị hiện tại
        public string UnitName { get; set; }

        //đơn vị nhỏ nhất
        public long? ProductUnitId { get; set; }

        public string ProductUnitName { get; set; }

        /// <summary>
        /// Giá trị quy đổi so với đơn vị nhỏ nhất
        /// </summary>
        public decimal Exchange { get; set; } = 1;

        /// <summary>
        /// Số lượng đơn vị nhỏ nhất
        /// </summary>
        public decimal ProductUnitQuantity { get; set; }

        /// <summary>
        /// Giá nhập DVNN
        /// </summary>
        public decimal ProductUnitCostPrice => ProductUnitQuantity != 0 ? TotalCostPrice / ProductUnitQuantity : 0;

        public decimal ProductUnitOpsCostPrice => ProductUnitQuantity != 0 ? TotalOpsCostPrice / ProductUnitQuantity : 0;

        public decimal ProductUnitPrice => ProductUnitQuantity != 0 ? TotalNonPrice / ProductUnitQuantity : 0;

        public int BranchId { get; set; }
        public int DestBranchId { get; set; }
        public int SupplierId { get; set; }
        public int CustomerId { get; set; }
        public BillType? BillType { get; set; }
        public string BillCode { get; set; }
        public bool BillIsDeleted { get; set; }
        public bool BillIsMedrepReturn { get; set; }
        public int? BillIdMedrepReturn { get; set; }
        public SaleType BillRelateSaleTypeReturn { get; set; }
        public string BillRelateCode { get; set; }
        public int? BillRelateCustomerId { get; set; }
        public int? BillRelateCustomerManagerId { get; set; }
        public Entities.Inventories.Customers.CustomerType? BillRelateCustomerType { get; set; }
        public BillStatus? BillStatus { get; set; }
        public DateTimeOffset? BillCreatedTime { get; set; }
        public DateTimeOffset? BillRelateCreatedTime { get; set; }
        public DateTimeOffset? ExpiryDate { get; set; }
        public string BatchName { get; set; }
        public string BillInvoiceCode { get; set; }
        public DateTimeOffset? BillVocherDate { get; set; }
    }
}