package de.htwsaar.webshop.service.impl;

import de.htwsaar.webshop.repository.AccountRepository;
import de.htwsaar.webshop.repository.SessionRepository;
import de.htwsaar.webshop.repository.entities.Account;
import de.htwsaar.webshop.repository.entities.Session;
import de.htwsaar.webshop.service.SessionService;
import de.htwsaar.webshop.util.TimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;


@Service
@Slf4j
public class SessionServiceImpl implements SessionService {
    private final SessionRepository sessionRepository;
    private final AccountRepository accountRepository;

    @Autowired
    public SessionServiceImpl(SessionRepository sessionRepository, AccountRepository accountRepository) {
        this.sessionRepository = sessionRepository;
        this.accountRepository = accountRepository;
    }

    @Override
    public Session create(Account account) {
        long timeout = TimeUtil.nowPlusDays(7);
        UUID token = UUID.randomUUID();
        log.info("Creating session with account {} and token {} with timeout {} ", account, token, timeout);
        return sessionRepository.save(new Session(null, token, timeout, account));
    }

    @Override
    public void delete(Session session) {
        sessionRepository.delete(session);
    }

    @Override
    public Session findByAccount(Account account) {
        return sessionRepository.findByAccount(account);
    }

    @Override
    public Session getByToken(UUID token) {
        return sessionRepository.getSessionByToken(token);
    }

    @Override
    public boolean isValid(Session session, String email) {
        if (session == null || email == null) {
            return false;
        }
        Account accountEmail = accountRepository.getAccountByEmail(email);
        if (!session.getAccount().equals(accountEmail)) {
            return false;
        }
        if (session.getTimeout() >= System.currentTimeMillis()) {
            log.info("Session with email {} is expired", email);
            delete(session);
            return false;
        }
        log.info("Session with email {} is valid", email);
        return true;
    }

    @Override
    public boolean isValid(UUID token, String email) {
        return isValid(getByToken(token), email);
    }

    @Override
    public boolean isAdmin(UUID token, String email) {
        if(token == null || email == null) {
            return false;
        }
        if(!isValid(token, email)) {
            log.warn("Invalid Session with email {} trying to access Admin Services", email);
            return false;
        }
        Account account = accountRepository.getAccountByEmail(email);
        if(account == null) {
            log.error("Account with email {} has valid session but not found. Huh??", email);
            return false;
        }
        if(!account.getAdmin()) {
            log.warn("Session with email {} trying to access Admin Services", email);
            return false;
        }
        log.info("Session with email {} allowed to access Admin Services", email);
        return true;
    }
}
