<?php

namespace Drupal\miniorange_2fa\Services;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\miniorange_2fa\UsersAPIHandler;
use Drupal\miniorange_2fa\MiniorangeCustomerProfile;
use Drupal\miniorange_2fa\MoAuthUtilities;
use Drupal\miniorange_2fa\MoAuthConstants;

/**
 * License Manager Service for handling license operations.
 */
class LicenseManager {

  /**
   * The config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * The logger factory.
   *
   * @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
   */
  protected $loggerFactory;

  /**
   * Constructor.
   */
  public function __construct(ConfigFactoryInterface $config_factory, LoggerChannelFactoryInterface $logger_factory) {
    $this->configFactory = $config_factory;
    $this->loggerFactory = $logger_factory;
  }

  /**
   * Check if license fetch is needed (24 hours interval).
   *
   * @return bool
   *   TRUE if license needs to be fetched.
   */
  public function shouldFetchLicense(): bool {
    $config = $this->configFactory->get('miniorange_2fa.settings');
    $last_fetch = $config->get('mo_auth_license_fetch_at') ?? 0;
    $current_time = time();
    
    return ($current_time - $last_fetch) >= 86400;
  }

  /**
   * Fetch license information from API.
   *
   * @return object|null
   *   License response object or NULL on failure.
   */
  public function fetchLicense() {
    try {
      $customer = new MiniorangeCustomerProfile();
      $user_api_handler = new UsersAPIHandler($customer->getCustomerID(), $customer->getAPIKey());
      $response = $user_api_handler->fetchLicense();

      if (is_object($response) && $response->status == 'SUCCESS') {
        $this->updateLicenseConfig($response);
        return $response;
      }

      $this->loggerFactory->get('miniorange_2fa')->warning('Failed to fetch license: @message', [
        '@message' => isset($response->message) ? $response->message : 'Unknown error'
      ]);
      
      return NULL;
    }
    catch (\Exception $e) {
      $this->loggerFactory->get('miniorange_2fa')->error('Exception in fetchLicense: @message', [
        '@message' => $e->getMessage()
      ]);
      return NULL;
    }
  }

  /**
   * Update license configuration.
   *
   * @param object $license_response
   *   License response from API.
   */
  protected function updateLicenseConfig($license_response) {
    $utilities = new MoAuthUtilities();
    $license_type = $license_response->licenseType ?? 'DRUPAL_2FA';
    $license_plan = ($license_type == MoAuthConstants::LICENSE_TYPE || $license_type == 'DRUPAL8_2FA_MODULE') 
                   ? $license_response->licensePlan : 'DRUPAL_2FA';
    $variables_and_values = [
      'mo_auth_2fa_license_type' => $license_type,
      'mo_auth_2fa_license_plan' => $license_plan,
      'mo_auth_2fa_license_no_of_users' => $license_response->noOfUsers ?? 1,
      'mo_auth_2fa_ivr_remaining' => $license_response->ivrRemaining ?? '-',
      'mo_auth_2fa_sms_remaining' => $license_response->smsRemaining ?? '-',
      'mo_auth_2fa_email_remaining' => $license_response->emailRemaining ?? '-',
      'mo_auth_2fa_license_expiry' => isset($license_response->licenseExpiry) 
        ? date('Y-M-d H:i:s', strtotime($license_response->licenseExpiry)) : '-',
      'mo_auth_2fa_support_expiry' => isset($license_response->supportExpiry) 
        ? date('Y-M-d H:i:s', strtotime($license_response->supportExpiry)) : '-',
      'mo_auth_license_fetch_at' => time(),
    ];

    $utilities->miniOrange_set_get_configurations($variables_and_values, 'SET');
  }

  /**
   * Check if license is expired.
   *
   * @return bool
   *   TRUE if license is expired.
   */
  public function isLicenseExpired(): bool {
    $config = $this->configFactory->get('miniorange_2fa.settings');
    $license_expiry = $config->get('mo_auth_2fa_license_expiry');
    
    if (!$license_expiry || $license_expiry === '-') {
      return FALSE;
    }

    return time() > strtotime($license_expiry);
  }

  /**
   * Get remaining days until license expiry.
   *
   * @return int
   *   Number of days remaining. Negative if expired.
   */
  public function getRemainingDays(): int {
    $config = $this->configFactory->get('miniorange_2fa.settings');
    $license_expiry = $config->get('mo_auth_2fa_license_expiry');
    
    if (!$license_expiry || $license_expiry === '-') {
      return 0;
    }

    return intval((strtotime($license_expiry) - time()) / (60 * 60 * 24));
  }

}
