using Caliburn.Micro;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace Gremlin.MVVM
{
    public class QuoteViewModel : PropertyChangedBase
    {
        private string _quoteType = "ein Analysegerät";
        private string _quotePath;
        private List<LineItemViewModel> _lineItemsVM;
        private ContactViewModel _recipient;
        private ContactViewModel _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? _showBrutto = true;
        private bool? _singlePrices = true;
        private bool? _attachBrochures;
        private bool? _attachDataSheets;
        private bool? _useMailTemplate;
        private bool _quoteContains3PP;
        private bool _quoteContainsRB;
        private bool? _showDiscounts = true;

        public string QuoteType { get => _quoteType; internal set { _quoteType = value; NotifyOfPropertyChange(() => QuoteType); } }
        public string QuotePath { get => _quotePath; internal set { _quotePath = value; NotifyOfPropertyChange(() => QuotePath); } }
        public bool? ShowBrutto { get => _showBrutto; internal set { _showBrutto = value; NotifyOfPropertyChange(() => ShowBrutto); } }
        public string QuoteNumber { get => _quoteNumber; internal set { _quoteNumber = value; NotifyOfPropertyChange(() => QuoteNumber); } }
        public int Warranty { get => _warranty; internal set { _warranty = value; NotifyOfPropertyChange(() => Warranty); } }
        public int Validity { get => _validity; internal set { _validity = value; NotifyOfPropertyChange(() => Validity); } }
        public bool? SinglePrices { get => _singlePrices; internal set { _singlePrices = value; NotifyOfPropertyChange(() => SinglePrices); } }
        public bool? AttachBrochures { get => _attachBrochures; internal set { _attachBrochures = value; NotifyOfPropertyChange(() => AttachBrochures); } }
        public bool? AttachDataSheets { get => _attachDataSheets; internal set { _attachDataSheets = value; NotifyOfPropertyChange(() => AttachDataSheets); } }
        public bool? UseMailTemplate { get => _useMailTemplate; internal set { _useMailTemplate = value; NotifyOfPropertyChange(() => UseMailTemplate); } }
        public bool? ShowDiscounts { get => _showDiscounts; internal set { _showDiscounts = value; NotifyOfPropertyChange(() => ShowDiscounts); } }

        public List<LineItemViewModel> LineItemsViewModel { get => _lineItemsVM; internal set { _lineItemsVM = value; NotifyOfPropertyChange(() => LineItemsViewModel); } }
        public ContactViewModel Recipient { get => _recipient; internal set { _recipient = value; NotifyOfPropertyChange(() => Recipient); } }
        public ContactViewModel SalesRep { get => _salesRep; internal set { _salesRep = value; NotifyOfPropertyChange(() => SalesRep); } }
        public decimal TotalListprice { get => _totalListprice; internal set { _totalListprice = value; NotifyOfPropertyChange(() => TotalListprice); } }
        public decimal AverageDiscount { get => _averageDiscount; internal set { _averageDiscount = value; NotifyOfPropertyChange(() => AverageDiscount); } }
        public decimal TotalNet { get => _totalNet; internal set { _totalNet = value; NotifyOfPropertyChange(() => TotalNet); } }
        public float VAT { get => _vAT; internal set { _vAT = value; NotifyOfPropertyChange(() => VAT); } }
        public bool QuoteContains3PP { get => _quoteContains3PP; internal set { _quoteContains3PP = value; NotifyOfPropertyChange(() => QuoteContains3PP); } }
        public bool QuoteContainsRB { get => _quoteContainsRB; internal set { _quoteContainsRB = value; NotifyOfPropertyChange(() => QuoteContainsRB); } }

        internal QuoteViewModel(ContactViewModel 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 QuoteViewModel() { }

        private QuoteViewModel(string quoteNumber, string quoteType, ContactViewModel recipient, ContactViewModel 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;
            ShowBrutto = brutto;
            VAT = vAT;
            Warranty = warranty;
            Validity = validity;
            QuotePath = quotePath;
            SinglePrices = singlePrices;
            AttachBrochures = brochures;
            AttachDataSheets = dataSheets;
            UseMailTemplate = mailTemplate;
            ShowDiscounts = showDiscounts;
        }

        internal static QuoteViewModel CreateQuote(string quoteNumber, ContactViewModel recipient, ContactViewModel 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;

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

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

            if (lineItemsVM == null) return null;

            foreach (LineItemViewModel 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.LineItemsViewModel.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;
        }

        public void GenerateQuoteNumber()
        {
            Random random = new();
            QuoteNumber = $"DE-83PE89-{DateTime.Now:My}-{random.Next(999999)}";
        }
    }
}
