using System;
using System.Collections.Generic;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.DCEntityMapper;
using BS.Shared.Core;
using BS.Shared.DataContracts;

namespace BeWo.Service.Plugins
{
	public class InvoiceNumberGenerator : AbstractIDSpecificDefaultClass<InvoiceNumberGenerator>
	{

		public virtual String GetNextInvoiceNumber(int increment, InvoiceBase invoiceBase)
		{
			string next = String.Empty;
			InvoiceNumberDC invoiceNumber = LoadInvoiceNumber();

			if (invoiceNumber != null && invoiceNumber.Use)
			{
				next = ApplyPattern(invoiceNumber.Pattern, invoiceNumber.CurrentNumber + increment, invoiceBase);
			}
			return next;
		}

		public virtual void IncreaseInvoiceNumber(int count)
		{
			if (count != 0)
			{
				var invoiceNumber = this.LoadInvoiceNumber();
				if (invoiceNumber.Use)
				{
					invoiceNumber.CurrentNumber += count;
					this.UpdateInvoiceNumber(invoiceNumber);
				}
			}
		}

		public virtual InvoiceNumberDC LoadInvoiceNumber()
		{
			var inr = DAOFactory.GenericDAO.LoadByID<InvoiceNumber>(1);
			if (inr != null)
				return MapperFactory.InvoiceNumberDC_InvoiceNumber.MapToNewDC(DAOFactory.GenericDAO.LoadByID<InvoiceNumber>(1));
			return null;
		}

		public virtual InvoiceNumberDC UpdateInvoiceNumber(InvoiceNumberDC dc)
		{
			var old = DAOFactory.GenericDAO.LoadByID<InvoiceNumber>(1);
			MapperFactory.InvoiceNumberDC_InvoiceNumber.MergeWithEntity(dc, old);
			DAOFactory.GenericDAO.Update(old);

			return MapperFactory.InvoiceNumberDC_InvoiceNumber.MapToNewDC(old);
		}

		protected virtual String ApplyPattern(String pattern, long number, InvoiceBase invoiceBase)
		{
			string next = pattern;

			if (!String.IsNullOrEmpty(next))
			{
				int pos = next.IndexOf("{n");
				if (pos >= 0)
				{
					int stop = next.IndexOf("}", pos);
					if (stop > pos)
					{
						int nCount = stop - pos - 1;

						String nextNumberStr = number.ToString();

						while (nextNumberStr.Length < nCount)
							nextNumberStr = "0" + nextNumberStr;

						next = next.Replace(next.Substring(pos, stop - pos + 1), nextNumberStr);
					}
				}

				next = next.Replace("{jj}", String.Format("{0:yy}", DateTime.Now.Date));
				next = next.Replace("{jjjj}", String.Format("{0:yyyy}", DateTime.Now.Date));

				int pos2 = next.IndexOf("{", StringComparison.OrdinalIgnoreCase);
				if (pos2 >= 0)
				{
					int stop = next.IndexOf("}", pos2);
					if (stop > pos2)
					{
						var idString = next.Substring(pos2, stop - pos2 + 1);

						if (idString.IndexOf("id", StringComparison.OrdinalIgnoreCase) >= 0)
						{
							String id = String.Empty;
							if (invoiceBase != null && !String.IsNullOrEmpty(invoiceBase.InvoiceId))
							{
								id = invoiceBase.InvoiceId;
							}



							if (idString.Length > 4)
							{
								idString = idString.Replace("id", id);
								idString = idString.Replace("ID", id);
								idString = idString.Replace("Id", id);
								idString = idString.Replace("{", "");
								idString = idString.Replace("}", "");
							}
							else
							{
								idString = id;
							}
							var prefix = String.Empty;
							if (pos2 > 0)
							{
								prefix = next.Substring(0, pos2);
							}
							var suffix = next.Substring(stop + 1);

							next = prefix + idString + suffix;
						}
					}
				}
			}

			return next;
		}
	}
}
