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

using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.Core;
using BeWo.Service.DCEntityMapper;
using BeWo.Service.ServiceContracts;

using BS.Shared;
using BS.Shared.DataContracts;

namespace BeWo.Service.ServiceImplementations
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
    internal class MailServiceImp : IMailService
    {
        public void DeleteMail(long pEmployeeOid, MailDC pMail)
        {
            this.SetMailActivationType(pEmployeeOid, pMail, ActivationTypeId.Deleted);
        }

        public List<MailDC> GetIncomingMails(long pEmployeeOid)
        {
            try
            {
                var employee = DAOFactory.GenericDAO.LoadByID<Employee>(pEmployeeOid);

                var incomingMail2Receiver = employee.IncomingMail2Receiver;

                return incomingMail2Receiver.Select(m2r => this.CreateMailDC(m2r)).ToList();
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<MailDC> GetOutgoingMails(long pEmployeeOid)
        {
            try
            {
                var employee = DAOFactory.GenericDAO.LoadByID<Employee>(pEmployeeOid);

                return employee.OutgoingMails.Select(mail => MapperFactory.MailDC_Mail.MapToNewDC(mail)).ToList();
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void MoveMailToRecycleBin(long pEmployeeOid, MailDC pMail)
        {
            this.SetMailActivationType(pEmployeeOid, pMail, ActivationTypeId.InRecycleBin);
        }

        public long SendMail(MailDC pMail)
        {
            try
            {
                // SendEMails(pMail);

                // var lMail = MapperFactory.MailDC_Mail.MapToNewEntity(pMail);
                var lMail = new Mail();
                lMail.Oid = pMail.MailOid;

                lMail.Message = pMail.Message;

                var employee = DAOFactory.GenericDAO.LoadByID<Employee>(pMail.Sender.Value);

                lMail.Sender = employee;
                lMail.Subject = pMail.Subject;
                lMail.Version = pMail.MailVersion;
                lMail.Notice = pMail.Description;

                lMail.ReceiverList = pMail.Receiver.Select(receiver => new Mail2Receiver { IsBlind = false, Mail = lMail, Oid = -1, Priority = pMail.Priority ?? Priority.normal, Receiver = receiver.EmployeeOid != null ? DAOFactory.GenericDAO.LoadByID<Employee>(receiver.EmployeeOid.Value) : null, ReceiverEMailAddress = receiver.EmailAddress, Status = Status.unread }).ToList();

                DAOFactory.GenericDAO.Insert(lMail);
                return lMail.Oid.Value;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public bool SendEMail(string subject, string body)
        {
            return Utils.SendMail(subject, body, null);
        }

		public bool SendEMailWithSender(string senderName, string senderEMail, string subject, string body)
        {
            return Utils.SendMail(senderName, senderEMail, subject, body, null);
        }

        private MailDC CreateMailDC(Mail2Receiver m2r)
        {
            MailDC mail = MapperFactory.MailDC_Mail.MapToNewDC(m2r.Mail);

            mail.Priority = m2r.Priority;
            mail.Status = m2r.Status;

            return mail;
        }

        private void SetMailActivationType(long pEmployeeOid, MailDC pMail, ActivationTypeId activationType)
        {
            try
            {
                var mail2Receiver = pMail.Receiver.Where(r => r.EmployeeOid == pEmployeeOid).First();

                // var tmp = MapperFactory.MailReceiverDC_Mail2Receiver.MapToNewEntity(mail2Receiver);
                var mail2ReceiverDAO = DAOFactory.GenericDAO.LoadByID<Mail2Receiver>(mail2Receiver.Mail2ReceiverOid.Value);

                // ServiceLogic.Deactivate<Mail2Receiver>(tmp.Oid.Value, tmp.Version.Value);
                ServiceLogic.SetActivationType<Mail2Receiver>(mail2ReceiverDAO.Oid.Value, mail2ReceiverDAO.Version.Value, activationType);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        // void SendEMails(MailDC mailDC)
        // {
        // SmtpClient client = new SmtpClient();
        // client.DeliveryMethod = SmtpDeliveryMethod.Network;
        // client.Host = "beyondsoft.de";

        // client.Credentials = new System.Net.NetworkCredential("default", "roh2ohYe");

        // try
        // {
        // //// Attachement
        // //Attachment a = new Attachment(filename);
        // //System.Net.Mime.ContentDisposition disposition = a.ContentDisposition;
        // //disposition.CreationDate = System.IO.File.GetCreationTime(filename);
        // //disposition.ModificationDate = System.IO.File.GetLastWriteTime(filename);
        // //disposition.ReadDate = System.IO.File.GetLastAccessTime(filename);
        // //mail.Attachments.Add(a);

        // foreach (var receiver in mailDC.Receiver)
        // {
        // if (!string.IsNullOrEmpty(receiver.EmailAddress))
        // {

        // var mail = new MailMessage(new MailAddress("bewo@beyondsoft.de", mailDC.SenderName), new MailAddress(receiver.EmailAddress))
        // {
        // Subject = mailDC.Subject,
        // Body = mailDC.Message,
        // Priority = PriorityToMailPrority(mailDC.Priority)
        // };

        // client.Send(mail);
        // }
        // }
        // }
        // //catch (SmtpFailedRecipientException ex)
        // //{
        // //    //...
        // //}
        // //catch (SmtpException ex)
        // //{
        // //    //...
        // //}
        // catch (Exception ex)
        // {
        // //...
        // throw ex;
        // }
        // }

        // private MailPriority PriorityToMailPrority(Priority? priority)
        // {
        // switch (priority ?? Priority.normal)
        // {
        // case Priority.high:
        // return MailPriority.High;
        // case Priority.normal:
        // return MailPriority.Normal;
        // case Priority.low:
        // return MailPriority.Low;
        // default:
        // return MailPriority.Normal;
        // }

        // }
    }
}