﻿using System;
using Slagen.Data;
using Slagen.Domain.Entities;
using Slagen.Domain.Services;
using Slagen.Domain.ValueObjects;
using Slagen.Web.Api.Infrastructure.Exceptions;
using Slagen.Web.Api.Requests;
using Slagen.Web.Api.Responses;
using Nancy;
using Nancy.ModelBinding;

namespace Slagen.Web.Api.Modules
{
    public class LoginModule : NancyModule
    {
        public LoginModule(IPasswordEncryptor passwordEncryptor, IReadOnlyRepository readOnlyRepository,
                           IUserSessionFactory userSessionFactory)
        {
            Post["/login"] =
                _ =>
                    {
                        var loginInfo = this.Bind<LoginRequest>();
                        if (loginInfo.Email == null) throw new UserInputPropertyMissingException("Email");
                        if (loginInfo.Password == null) throw new UserInputPropertyMissingException("Password");

                        EncryptedPassword encryptedPassword = passwordEncryptor.Encrypt(loginInfo.Password);

                        try
                        {
                            var user =
                                readOnlyRepository.First<User>(
                                    x => x.Email == loginInfo.Email && x.EncryptedPassword == encryptedPassword.Password);

                            UserLoginSession userLoginSession = userSessionFactory.Create(user);

                            return new SuccessfulLoginResponse<Guid>(userLoginSession.Id, user.Name, userLoginSession.Expires);
                        }
                        catch (ItemNotFoundException<User>)
                        {
                            throw new UnauthorizedAccessException();
                        }
                    };
        }
    }
}