using Gremlin.ViewModels;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace Gremlin.GremlinUI.ViewModels
{
    internal class QuoteVM : BaseVM
    {
        private string _quoteType = "ein Analysegerät";
        private string _quotePath;
        private List<LineItemVM> _lineItemsVM;
        private ContactVM _recipient;
        private ContactVM _salesRep;
        private string _quoteNumber;
        private int _warranty = 12;
        private int _validity = 60;
        private decimal _totalListprice;
        private decimal _averageDiscount;
        private decimal _totalNet;
        private float _vAT = 19f;
        private bool? _brutto = true;
        private bool? _singlePrices = true;
        private bool? _brochures = false;
        private bool? _dataSheets = false;
        private bool? _mailTemplate = false;
        private bool _quoteContains3PP = false;
        private bool _quoteContainsRB = false;
        private bool? _showDiscounts = true;

        public string QuoteType
        {
            get => _quoteType;

            internal set
            {
                _quoteType = value;
                OnPropertyChanged("QuoteType");
            }
        }

        public string QuotePath
        {
            get => _quotePath;
            internal set
            {
                _quotePath = value;
                OnPropertyChanged("QuotePath");
            }
        }

        public List<LineItemVM> LineItemsVM { get => _lineItemsVM; private set => _lineItemsVM = value; }
        public ContactVM Recipient { get => _recipient; internal set => _recipient = value; }
        public ContactVM SalesRep { get => _salesRep; private set => _salesRep = value; }
        public string QuoteNumber { get => _quoteNumber; internal set => _quoteNumber = value; }
        public int Warranty { get => _warranty; internal set => _warranty = value; }
        public int Validity { get => _validity; internal set => _validity = value; }
        public decimal TotalListprice { get => _totalListprice; private set => _totalListprice = value; }
        public decimal AverageDiscount { get => _averageDiscount; private set => _averageDiscount = value; }
        public decimal TotalNet { get => _totalNet; private set => _totalNet = value; }
        public float VAT { get => _vAT; private set => _vAT = value; }
        public bool? Brutto { get => _brutto; internal set => _brutto = value; }
        public bool? SinglePrices { get => _singlePrices; internal set => _singlePrices = value; }
        public bool? Brochures { get => _brochures; internal set => _brochures = value; }
        public bool? DataSheets { get => _dataSheets; internal set => _dataSheets = value; }
        public bool? MailTemplate { get => _mailTemplate; internal set => _mailTemplate = value; }
        public bool QuoteContains3PP { get => _quoteContains3PP; private set => _quoteContains3PP = value; }
        public bool QuoteContainsRB { get => _quoteContainsRB; private set => _quoteContainsRB = value; }
        public bool? ShowDiscounts { get => _showDiscounts; internal set => _showDiscounts = value; }

        internal QuoteVM(ContactVM salesRep)
        {
            Random random = new();
            SalesRep = salesRep;
            QuoteNumber = SalesRep.LastName switch
            {
                "Woitschetzki" => $"DE-83PE89-{DateTime.Now:My}-{random.Next(999999)}",
                "Welsch" => $"DE-83RE32-{DateTime.Now:My}-{random.Next(999999)}",
                _ => $"DE-XXYYXX-{DateTime.Now:My}-{random.Next(999999)}",
            };
        }

        public QuoteVM() { }

        private QuoteVM(string quoteNumber, string quoteType, ContactVM recipient, ContactVM salesRep, bool? brutto, float vAT, int warranty, int validity, string quotePath, bool? singlePrices, bool? brochures, bool? dataSheets, bool? mailTemplate, bool? showDiscounts)
        {
            QuoteNumber = quoteNumber;
            QuoteType = quoteType;
            Recipient = recipient;
            SalesRep = salesRep;
            Brutto = brutto;
            VAT = vAT;
            Warranty = warranty;
            Validity = validity;
            QuotePath = quotePath;
            SinglePrices = singlePrices;
            Brochures = brochures;
            DataSheets = dataSheets;
            MailTemplate = mailTemplate;
            ShowDiscounts = showDiscounts;
        }

        internal static QuoteVM CreateQuote(string quoteNumber, ContactVM recipient, ContactVM salesRep, float vAT = 19f, string quoteType = "ein Analysegerät", bool? brutto = true, int warranty = 12, bool? singlePrices = true, bool? brochures = true, bool? dataSheets = true, bool? mailTemplate = true, string quotePath = "", int validity = 60, bool? showDiscounts = true)
        {
            decimal totalListprice = 0, totalDiscount = 0, calcTotalNet = 0;
            bool quoteContains3PP = false, quoteContainsRB = false;

            QuoteVM quoteVM = new(quoteNumber, quoteType, recipient, salesRep, brutto, vAT, warranty, validity, quotePath, singlePrices, brochures, dataSheets, mailTemplate, showDiscounts);
            quoteVM.LineItemsVM = new();

            ObservableCollection<LineItemVM> lineItemsVM = LineItemVM.ReadLineItemsFromClipboard();

            if (lineItemsVM == null) return null;

            foreach (LineItemVM lineItemVM in lineItemsVM)
            {
                totalListprice += lineItemVM.ListPrice;
                totalDiscount += lineItemVM.TotalDiscount;
                calcTotalNet += lineItemVM.CalcTotalNet; //Use calculated values

                switch (lineItemVM.ProductLine)
                {
                    case "RB":
                        if (lineItemVM.ProductNumber != "R2005A") //kein wirkliches RB-Produkt
                        {
                            quoteContainsRB = true;
                        }

                        break;
                    case "3PP":
                        quoteContains3PP = true; break;
                }

                if (lineItemVM.OptionNumber.StartsWith("8D"))
                {
                    quoteVM.Warranty = int.Parse(lineItemVM.OptionNumber.Last().ToString()) * 12;
                }

                quoteVM.LineItemsVM.Add(lineItemVM);
            }

            quoteVM.TotalListprice = totalListprice;
            if (lineItemsVM.Count != 0)
            {
                quoteVM.AverageDiscount = (decimal)MathF.Round((float)(totalDiscount / lineItemsVM.Count), 3);
            }
            quoteVM.TotalNet = calcTotalNet; //Use calculated values
            quoteVM.QuoteContainsRB = quoteContainsRB;
            quoteVM.QuoteContains3PP = quoteContains3PP;

            return quoteVM;
        }
    }
}
