<?php

namespace PortalPeople\AuthRedirect\Helper;

use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\HTTP\PhpEnvironment\RemoteAddress;
use Magento\Framework\Stdlib\DateTime\DateTime;
use Psr\Log\LoggerInterface;

class SimpleLoginAttemptHelper extends AbstractHelper
{
    const MAX_ATTEMPTS = 5;
    const RATE_LIMIT_WINDOW = 900; // 15 minutes

    private $remoteAddress;
    private $dateTime;
    private $logger;

    public function __construct(
        Context $context,
        RemoteAddress $remoteAddress,
        DateTime $dateTime,
        LoggerInterface $logger
    ) {
        parent::__construct($context);
        $this->remoteAddress = $remoteAddress;
        $this->dateTime = $dateTime;
        $this->logger = $logger;
    }

    public function logAttempt($email, $isSuccessful)
    {
        try {
            $objectManager = ObjectManager::getInstance();
            $loginAttemptLogFactory = $objectManager->get(\PortalPeople\AuthRedirect\Model\LoginAttemptLogFactory::class);
            $loginAttemptResource = $objectManager->get(\PortalPeople\AuthRedirect\Model\ResourceModel\LoginAttemptLog::class);
            
            $attempt = $loginAttemptLogFactory->create();
            $attempt->setEmail($email);
            $attempt->setIpAddress($this->remoteAddress->getRemoteAddress());
            $attempt->setIsSuccessful($isSuccessful ? 1 : 0);
            $attempt->setAttemptTime($this->dateTime->gmtDate());
            
            $loginAttemptResource->save($attempt);
            
            $this->logger->info('Login attempt logged', [
                'email' => $email,
                'ip' => $this->remoteAddress->getRemoteAddress(),
                'successful' => $isSuccessful
            ]);
            
        } catch (\Exception $e) {
            $this->logger->error('Failed to log login attempt: ' . $e->getMessage(), [
                'email' => $email,
                'exception' => $e
            ]);
        }
    }

    public function isRateLimited($email)
    {
        try {
            $objectManager = ObjectManager::getInstance();
            $collectionFactory = $objectManager->get(\PortalPeople\AuthRedirect\Model\ResourceModel\LoginAttemptLog\CollectionFactory::class);
            
            $timeThreshold = $this->dateTime->gmtDate('Y-m-d H:i:s', time() - self::RATE_LIMIT_WINDOW);
            
            $collection = $collectionFactory->create();
            $collection->addFieldToFilter('email', $email)
                      ->addFieldToFilter('is_successful', 0)
                      ->addFieldToFilter('attempt_time', ['gteq' => $timeThreshold])
                      ->setOrder('attempt_time', 'DESC');

            $count = $collection->getSize();
            
            $this->logger->info('Rate limit check', [
                'email' => $email,
                'failed_attempts' => $count,
                'threshold' => self::MAX_ATTEMPTS,
                'is_limited' => $count >= self::MAX_ATTEMPTS
            ]);

            return $count >= self::MAX_ATTEMPTS;
            
        } catch (\Exception $e) {
            $this->logger->error('Failed to check rate limit: ' . $e->getMessage(), [
                'email' => $email,
                'exception' => $e
            ]);
            return false;
        }
    }

    public function getFailedAttemptCount($email)
    {
        try {
            $objectManager = ObjectManager::getInstance();
            $collectionFactory = $objectManager->get(\PortalPeople\AuthRedirect\Model\ResourceModel\LoginAttemptLog\CollectionFactory::class);
            
            $timeThreshold = $this->dateTime->gmtDate('Y-m-d H:i:s', time() - self::RATE_LIMIT_WINDOW);
            
            $collection = $collectionFactory->create();
            $collection->addFieldToFilter('email', $email)
                      ->addFieldToFilter('is_successful', 0)
                      ->addFieldToFilter('attempt_time', ['gteq' => $timeThreshold]);

            return $collection->getSize();
            
        } catch (\Exception $e) {
            $this->logger->error('Failed to get failed attempt count: ' . $e->getMessage(), [
                'email' => $email,
                'exception' => $e
            ]);
            return 0;
        }
    }
}
