using Grand.Business.Core.Extensions;
using Grand.Business.Core.Interfaces.Common.Directory;
using Grand.Domain.Catalog;
using Grand.Domain.Common;
using Grand.Domain.Courses;
using Grand.Domain.Customers;
using Grand.Domain.Localization;
using Grand.Domain.Pages;
using Grand.Web.Models.Catalog;
using Grand.Web.Models.Common;
using Grand.Web.Models.Course;
using Grand.Web.Models.Pages;
using Grand.Web.Models.Vendors;
using System.Globalization;

namespace Grand.Web.Extensions
{
    public static class MappingExtensions
    {
        //category
        public static CategoryModel ToModel(this Category entity, Language language)
        {
            if (entity == null)
                return null;

            var model = new CategoryModel {
                Id = entity.Id,
                ParentCategoryId = entity.ParentCategoryId,
                Name = entity.GetTranslation(x => x.Name, language.Id),
                Description = entity.GetTranslation(x => x.Description, language.Id),
                BottomDescription = entity.GetTranslation(x => x.BottomDescription, language.Id),
                MetaKeywords = entity.GetTranslation(x => x.MetaKeywords, language.Id),
                MetaDescription = entity.GetTranslation(x => x.MetaDescription, language.Id),
                MetaTitle = entity.GetTranslation(x => x.MetaTitle, language.Id),
                SeName = entity.GetSeName(language.Id),
                Flag = entity.GetTranslation(x => x.Flag, language.Id),
                FlagStyle = entity.FlagStyle,
                Icon = entity.Icon,
                UserFields = entity.UserFields
            };
            return model;
        }
        //brand
        public static BrandModel ToModel(this Brand entity, Language language)
        {
            if (entity == null)
                return null;

            var model = new BrandModel {
                Id = entity.Id,
                Name = entity.GetTranslation(x => x.Name, language.Id),
                Description = entity.GetTranslation(x => x.Description, language.Id),
                BottomDescription = entity.GetTranslation(x => x.BottomDescription, language.Id),
                MetaKeywords = entity.GetTranslation(x => x.MetaKeywords, language.Id),
                MetaDescription = entity.GetTranslation(x => x.MetaDescription, language.Id),
                MetaTitle = entity.GetTranslation(x => x.MetaTitle, language.Id),
                SeName = entity.GetSeName(language.Id),
                Icon = entity.Icon,
                UserFields = entity.UserFields
            };
            return model;
        }
        //collection
        public static CollectionModel ToModel(this Collection entity, Language language)
        {
            if (entity == null)
                return null;

            var model = new CollectionModel {
                Id = entity.Id,
                Name = entity.GetTranslation(x => x.Name, language.Id),
                Description = entity.GetTranslation(x => x.Description, language.Id),
                BottomDescription = entity.GetTranslation(x => x.BottomDescription, language.Id),
                MetaKeywords = entity.GetTranslation(x => x.MetaKeywords, language.Id),
                MetaDescription = entity.GetTranslation(x => x.MetaDescription, language.Id),
                MetaTitle = entity.GetTranslation(x => x.MetaTitle, language.Id),
                SeName = entity.GetSeName(language.Id),
                Icon = entity.Icon,
                UserFields = entity.UserFields
            };
            return model;
        }

        //course
        public static CourseModel ToModel(this Course entity, Language language)
        {
            if (entity == null)
                return null;

            var model = new CourseModel {
                Id = entity.Id,
                Name = entity.GetTranslation(x => x.Name, language.Id),
                Description = entity.GetTranslation(x => x.Description, language.Id),
                ShortDescription = entity.GetTranslation(x => x.ShortDescription, language.Id),
                MetaKeywords = entity.GetTranslation(x => x.MetaKeywords, language.Id),
                MetaDescription = entity.GetTranslation(x => x.MetaDescription, language.Id),
                MetaTitle = entity.GetTranslation(x => x.MetaTitle, language.Id),
                SeName = entity.GetSeName(language.Id),
                UserFields = entity.UserFields
            };
            return model;
        }


        //page
        public static PageModel ToModel(this Page entity, Language language, IDateTimeService dateTimeService, string password = "")
        {
            var model = new PageModel {
                Id = entity.Id,
                SystemName = entity.SystemName,
                IncludeInSitemap = entity.IncludeInSitemap,
                IsPasswordProtected = entity.IsPasswordProtected,
                Password = entity.Password == password ? password : "",
                Title = entity.IsPasswordProtected && entity.Password != password ? "" : entity.GetTranslation(x => x.Title, language.Id),
                Body = entity.IsPasswordProtected && entity.Password != password ? "" : entity.GetTranslation(x => x.Body, language.Id),
                MetaKeywords = entity.GetTranslation(x => x.MetaKeywords, language.Id),
                MetaDescription = entity.GetTranslation(x => x.MetaDescription, language.Id),
                MetaTitle = entity.GetTranslation(x => x.MetaTitle, language.Id),
                SeName = entity.GetSeName(language.Id),
                PageLayoutId = entity.PageLayoutId,
                Published = entity.Published,
                StartDate = entity.StartDateUtc.HasValue ? dateTimeService.ConvertToUserTime(entity.StartDateUtc.Value) : default,
                EndDate = entity.EndDateUtc.HasValue ? dateTimeService.ConvertToUserTime(entity.EndDateUtc.Value) : default
            };
            return model;

        }

        public static Address ToEntity(this AddressModel model, Customer customer, AddressSettings addressSettings, bool trimFields = true)
        {
            if (model == null)
                return null;

            var entity = new Address();
            entity = ToEntity(model, entity, trimFields);
            if (addressSettings.DisallowUsersToChangeEmail)
            {
                entity.Email = customer.Email;
            }
            return entity;
        }

        public static Address ToEntity(this AddressModel model, bool trimFields = true)
        {
            if (model == null)
                return null;

            var entity = new Address();
            return ToEntity(model, entity, trimFields);
        }

        public static Address ToEntity(this AddressModel model, Address destination, Customer customer, AddressSettings addressSettings, bool trimFields = true)
        {
            var entity = ToEntity(model, destination, trimFields);
            if (addressSettings.DisallowUsersToChangeEmail)
            {
                entity.Email = customer.Email;
            }
            return entity;
        }

        public static Address ToEntity(this AddressModel model, Address destination, bool trimFields = true)
        {
            if (model == null)
                return destination;

            if (trimFields)
            {

                if (model.Name != null)
                    model.Name = model.Name.Trim();
                if (model.FirstName != null)
                    model.FirstName = model.FirstName.Trim();
                if (model.LastName != null)
                    model.LastName = model.LastName.Trim();
                if (model.Email != null)
                    model.Email = model.Email.Trim();
                if (model.Company != null)
                    model.Company = model.Company.Trim();
                if (model.VatNumber != null)
                    model.VatNumber = model.VatNumber.Trim();
                if (model.City != null)
                    model.City = model.City.Trim();
                if (model.Address1 != null)
                    model.Address1 = model.Address1.Trim();
                if (model.Address2 != null)
                    model.Address2 = model.Address2.Trim();
                if (model.ZipPostalCode != null)
                    model.ZipPostalCode = model.ZipPostalCode.Trim();
                if (model.PhoneNumber != null)
                    model.PhoneNumber = model.PhoneNumber.Trim();
                if (model.FaxNumber != null)
                    model.FaxNumber = model.FaxNumber.Trim();
            }
            destination.Name = model.Name;
            destination.FirstName = model.FirstName;
            destination.LastName = model.LastName;
            destination.Email = model.Email;
            destination.Company = model.Company;
            destination.VatNumber = model.VatNumber;
            destination.CountryId = !string.IsNullOrEmpty(model.CountryId) ? model.CountryId : "";
            destination.StateProvinceId = !string.IsNullOrEmpty(model.StateProvinceId) ? model.StateProvinceId : "";
            destination.City = model.City;
            destination.Address1 = model.Address1;
            destination.Address2 = model.Address2;
            destination.ZipPostalCode = model.ZipPostalCode;
            destination.PhoneNumber = model.PhoneNumber;
            destination.FaxNumber = model.FaxNumber;
            destination.Note = model.Note;
            destination.AddressType = (AddressType)model.AddressTypeId;

            return destination;
        }

        public static Address ToEntity(this VendorAddressModel model, Address destination, bool trimFields = true)
        {
            if (model == null)
                return destination;

            if (trimFields)
            {
                if (model.Company != null)
                    model.Company = model.Company.Trim();
                if (model.City != null)
                    model.City = model.City.Trim();
                if (model.Address1 != null)
                    model.Address1 = model.Address1.Trim();
                if (model.Address2 != null)
                    model.Address2 = model.Address2.Trim();
                if (model.ZipPostalCode != null)
                    model.ZipPostalCode = model.ZipPostalCode.Trim();
                if (model.PhoneNumber != null)
                    model.PhoneNumber = model.PhoneNumber.Trim();
                if (model.FaxNumber != null)
                    model.FaxNumber = model.FaxNumber.Trim();
            }
            destination.Company = model.Company;
            destination.CountryId = !string.IsNullOrEmpty(model.CountryId) ? model.CountryId : "";
            destination.StateProvinceId = !string.IsNullOrEmpty(model.StateProvinceId) ? model.StateProvinceId : "";
            destination.City = model.City;
            destination.Address1 = model.Address1;
            destination.Address2 = model.Address2;
            destination.ZipPostalCode = model.ZipPostalCode;
            destination.PhoneNumber = model.PhoneNumber;
            destination.FaxNumber = model.FaxNumber;
            destination.Note = model.Note;

            return destination;
        }

        public static void ParseReservationDates(this Product product, string reservationDatepickerFrom,string reservationDatepickerTo,
            out DateTime? startDate, out DateTime? endDate)
        {
            startDate = null;
            endDate = null;

            try
            {
                //currently we support only this format (as in the \Views\Product\_RentalInfo.cshtml file)
                const string datePickerFormat = "MM/dd/yyyy";
                startDate = DateTime.ParseExact(reservationDatepickerFrom, datePickerFormat, CultureInfo.InvariantCulture);
                endDate = DateTime.ParseExact(reservationDatepickerTo, datePickerFormat, CultureInfo.InvariantCulture);
            }
            catch
            {
                // ignored
            }
        }
    }
}