using System;
using System.Collections.Generic;
using System.Linq;

using BS.Shared;
using BS.Shared.DataContracts;
using BeWo.Data.Entities;
using BeWo.Data.Access;

namespace BeWo.Report.ReportObjects
{
    public class InvoiceCustomerRO : AbstractBeWoReportObject<InvoiceCustomerRO>
    {
        public string AccountingPeriod { get; set; }

        public DateTime? AccountingPeriodEnd { get; set; }

        public DateTime? AccountingPeriodStart { get; set; }

        public string CreatorFirstName { get; set; }

        public string CreatorLastName { get; set; }

        public string CustomerReferenceNumber { get; set; }

        public string InvoiceDate { get; set; }

        public List<InvoiceItemRO> InvoiceItems { get; set; }

        public string InvoiceNumber { get; set; }

        public string Notice { get; set; }

        public string RecipientFirstName { get; set; }

        public string RecipientLastName { get; set; }

        public string RecipientPostCode { get; set; }

        public string RecipientSalutation { get; set; }

        public string RecipientStreet { get; set; }

        public string RecipientTown { get; set; }

		public string CustomerFirstName { get; set; }

		public string CustomerLastName { get; set; }

		public string CustomerPostCode { get; set; }

		public string CustomerSalutation { get; set; }

		public string CustomerStreet { get; set; }

		public string CustomerTown { get; set; }

		public DateTime? CustomerBirthdate { get; set; }

        public string SenderDivision { get; set; }

        public string SenderFax { get; set; }

        public string SenderFirstName { get; set; }

        public string SenderLastName { get; set; }

        public string SenderPhone { get; set; }

        public string TotalClaim { get; set; }
        
        public string RecipientSalutationAddressField { get; set; }

        public string RecipientDivision { get; set; }

        public string RecipientOrganisation { get; set; }

        public string RecipientDebitorNumber { get; set; }

        public string RecipientCostCenter { get; set; }

        public DateTime InvoiceDateTime { get; set; }

        public static InvoiceCustomerRO Create(InvoiceBaseDC pDC)
        {
            var result = new InvoiceCustomerRO();

            result.AccountingPeriod = pDC.AccountingPeriodStart.Value.ToShortDateString() + " bis " + pDC.AccountingPeriodEnd.Value.ToShortDateString();
            result.CreatorFirstName = pDC.CreatorFirstName;
            result.CreatorLastName = pDC.CreatorLastName;
            result.CustomerReferenceNumber = GetCustomerReferenceNumber(pDC);
            result.InvoiceDateTime = pDC.InvoiceDate.Value;
            result.InvoiceDate = pDC.InvoiceDate.Value.ToShortDateString();
            result.InvoiceItems = pDC.InvoiceItems.Select(ii => InvoiceItemRO.Create(ii)).ToList();
            result.InvoiceNumber = pDC.InvoiceNumber;
            result.Notice = pDC.Notice;
            result.RecipientFirstName = pDC.RecipientPersonFirstName;
            result.RecipientLastName = pDC.RecipientPersonLastName;
            result.RecipientPostCode = pDC.RecipientPostCode;
            result.RecipientStreet = pDC.RecipientStreet;
            result.RecipientTown = pDC.RecipientTown;
            result.RecipientDivision = pDC.RecipientDivision;
            result.RecipientOrganisation = pDC.RecipientOrganisation;
            result.SenderDivision = pDC.SenderDivision;
            result.SenderFirstName = pDC.SenderFirstName;
            result.SenderLastName = pDC.SenderLastName;
            result.TotalClaim = string.Format("{0:c}", pDC.InvoiceItems.Sum(ii => ii.AmountTotal));

            Person p = null;
            if (pDC.RecipientPersonOid.HasValue)
            {
                p = DAOFactory.GenericDAO.LoadByID<Person>(pDC.RecipientPersonOid.Value);
            }
            else if (pDC.RecipientCustomerOid.HasValue)
            {
                Customer c = DAOFactory.GenericDAO.LoadByID<Customer>(pDC.RecipientCustomerOid.Value);
                result.RecipientDebitorNumber = c.DebitorNumber;
                result.RecipientCostCenter = c.CostCenter;

                p = c.Person;
            }

            result.RecipientSalutation = "Sehr geehrte(r)";

            if (p != null)
            {
                if (p.InvoiceAddress != null && !String.IsNullOrEmpty(p.InvoiceAddress.AddressLine1))
                {
                    result.RecipientFirstName = p.InvoiceAddress.AddressLine1;
                    result.RecipientLastName = "";
                }
                else
                {

                    if (p.Sex == Sex.Male)
                    {
                        result.RecipientSalutationAddressField = "Herrn";
                        result.RecipientSalutation = "Sehr geehrter Herr";
                    }
                    else
                    {
                        result.RecipientSalutationAddressField = "Frau";
                        result.RecipientSalutation = "Sehr geehrte Frau";
                    }
                }
				result.CustomerSalutation = p.Sex == Sex.Male ? "Herr" : "Frau";
				if (p.Address != null)
				{
					result.CustomerStreet = p.Address.Street;
					result.CustomerTown = p.Address.Town;
					result.CustomerPostCode = p.Address.PostalCode;
				}
				result.CustomerFirstName = p.FirstName;
				result.CustomerLastName = p.LastName;
				result.CustomerBirthdate = p.DateOfBirth;
            }

            foreach (ContactDC iContactDC in pDC.SenderContactInformations)
            {
                if (iContactDC.ContactType == ContactType.business_Fax)
                {
                    result.SenderFax = "Fax: " + iContactDC.ContactValue;
                }

                if (iContactDC.ContactType == ContactType.business_Phone)
                {
                    result.SenderPhone = "Tel.: " + iContactDC.ContactValue;
                }
            }

            if (pDC.InvoiceItems != null && pDC.InvoiceItems.Count > 0)
            {
                foreach (InvoiceItemDC item in pDC.InvoiceItems)
                {
                    if (item.ItemPeriodStart != null)
                    {
                        if (result.AccountingPeriodStart == null || result.AccountingPeriodStart > item.ItemPeriodStart)
                        {
                            result.AccountingPeriodStart = item.ItemPeriodStart;
                        }
                    }

                    if (item.ItemPeriodEnd != null)
                    {
                        if (result.AccountingPeriodEnd == null || result.AccountingPeriodEnd < item.ItemPeriodEnd)
                        {
                            result.AccountingPeriodEnd = item.ItemPeriodEnd;
                        }
                    }
                }
            }
            return result;
        }

		private static string GetCustomerReferenceNumber(InvoiceBaseDC pDC)
		{
			if (!String.IsNullOrEmpty(pDC.CustomerReferenceNumber))
			{
				return pDC.CustomerReferenceNumber;
			}
			if (pDC.SupportConceptOid.HasValue)
			{
				var sc = DAOFactory.GenericDAO.GetByID<SupportConcept>(pDC.SupportConceptOid.Value);

				foreach (var costBearer2SupportConcept in sc.CostBearer2SupportConceptList)
				{
					if (!String.IsNullOrEmpty(costBearer2SupportConcept.CustomerReferenceNumber))
						return costBearer2SupportConcept.CustomerReferenceNumber;
				}
				
			}
			return null;
		}
    }

    public class InvoiceItemRO : AbstractBeWoReportObject<InvoiceItemRO>
    {
        public string AccountingPeriodEnd { get; set; }

        public string AccountingPeriodStart { get; set; }

		public DateTime? AccountingPeriodEndDateTime { get; set; }

		public DateTime? AccountingPeriodStartDateTime { get; set; }

        public string AmountSum { get; set; }

        public string ItemDescription { get; set; }

        public decimal UnitCount { get; set; }

        public string UnitPrice { get; set; }

        public static InvoiceItemRO Create(InvoiceItemDC pDC)
        {
            var ii = new InvoiceItemRO
                   {
					   AccountingPeriodStartDateTime = pDC.ItemPeriodStart,
					   AccountingPeriodEndDateTime = pDC.ItemPeriodEnd,
                       ItemDescription = pDC.ItemDescription,
                       UnitPrice = string.Format("{0:c}", pDC.AmountPerUnit),
                       AmountSum = string.Format("{0:c}", pDC.AmountTotal),
                   };

	        if (pDC.ItemPeriodStart.HasValue)
	        {
		        ii.AccountingPeriodStart = pDC.ItemPeriodStart.Value.ToShortDateString();
	        }
	        if (pDC.ItemPeriodEnd.HasValue)
	        {
		        ii.AccountingPeriodEnd = pDC.ItemPeriodEnd.Value.ToShortDateString();
	        }
	        if (pDC.UnitCount.HasValue)
	        {
		        ii.UnitCount = pDC.UnitCount.Value;
	        }
	        return ii;
        }
    }
}