using System.Collections.Generic;
using System.Linq;
using System.Web.Services;

using BeWo.Data.Access;
using BeWo.Service.ServiceContracts;
using BeWo.Service.ServiceImplementations;

using BeWoPlanerAndroid.Service;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using NHibernate.Util;

namespace BeWoPlanerAndroid
{
    [WebService(Namespace = "bliblablubb.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // Wenn der Aufruf dieses Webdiensts aus einem Skript mithilfe von ASP.NET AJAX zulässig sein soll, heben Sie die Kommentarmarkierung für die folgende Zeile auf. 
    // [System.Web.Script.Services.ScriptService]
    public class AndroidSoapService : WebService
    {
        protected readonly ICustomerService CustomerService = new MobileSessionFacade().CustomerService;
        protected readonly IUserService     UserService     = new MobileSessionFacade().UserService;
        protected readonly IEmployeeService EmployeeService = new MobileSessionFacade().EmployeeService;

        public static string Tenant;

        [WebMethod(EnableSession = true)]
        public string Login(string pTenant, string pUsername, string pPassword)
        {
            MobileSessionFacade.Tenant = pTenant;
            Tenant = pTenant;

            SoapHibernateSessionManager.ConfigureHibernateSession();

            var s = new UserServiceImp();

            if(s.IsUserValid(pUsername, pPassword, null, "SOAPClient", false) == UserValidationResult.UserValid)
            {
                var user = DAOFactory.UserDAO.FindUserByLoginName(pUsername);

                if(user == null || !DAOFactory.UserDAO.CheckPassword(user, pPassword))
                {
                    return null;
                }

                MobileSessionFacade.LoggedInUser = user;
                
                return user.Employee.Oid.Value + ";" + user.Employee.Person.FirstNameLastName + ";" + user.LoginName + ";" + user.Employee.Person.Oid.Value;
            }

            return null;
        }

        [WebMethod(EnableSession = true)]
        public string TenantNochExistent()
        {
            SoapHibernateSessionManager.ConfigureHibernateSession();

            var customer = CustomerService.GetCompactCustomerDC(46L);

            var result = SerializeObject(customer);

            return result;
        }

        [WebMethod(EnableSession = true)]
        public void UpdateCustomer(string pParam)
        {
            var customerVonAndroidZurueck = JsonConvert.DeserializeObject<CompactCustomerDC>(pParam);

            SoapHibernateSessionManager.ConfigureHibernateSession();
        }

        [WebMethod(EnableSession = true)]
        public string GetServerAddressByToken(string pToken)
        {
            // Token überprüfen -> wenn falsch oder abgelaufen -> null zurückgeben


            return pToken == null ? null : "das-nur-ein-test;demo";
        }

        [WebMethod(EnableSession = true)]
        public string GetContactsForPerson(long pPersonOid)
        {
            // erst mal nur für Mitarbeiter

            // employee oder customer laden
            var employee = DAOFactory.SearchDAO.FindEmployeeWithPersonOid(pPersonOid);
            var customer = DAOFactory.SearchDAO.FindCustomerWithPersonOid(pPersonOid);

            var isEmployee = customer == null;
            // mit den eigenen Klienten und allen anderen Mitarbeitern

            var customerOids = employee.Employee2CustomerList.Select(s => s.CustomerOid.Value);
            var customers = CustomerService.GetCompactCustomersById(customerOids);

            var employees = EmployeeService.GetAllActiveEmployeesCompact().Where(w => !Equals(w.EmployeeOid, employee.Oid.Value));

            var result = employees.Select(emp => new ChatPerson(emp.PersonOid, emp.FirstName + " " + emp.LastName)).ToList();
            result.AddRange(customers.Select(cus => new ChatPerson(cus.PersonOid, cus.FullName)));

            return SerializeObject(result);
        }

        private static string SerializeObject(object obj)
        {
            return JsonConvert.SerializeObject(obj, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new ShouldSerializeContractResolver(), ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
        }

        public class ChatPerson
        {
            public long Oid { get; set; }

            public string Name { get; set; }

            public ChatPerson(long pOid, string pName)
            {
                Oid  = pOid;
                Name = pName;
            }
        }
    }
}
