<?php declare(strict_types = 1);

namespace MailPoet\Subscribers;

if (!defined('ABSPATH')) exit;


use MailPoet\Settings\SettingsController;
use MailPoet\Util\License\Features\Subscribers as SubscribersFeature;
use MailPoet\WP\Functions as WPFunctions;

class SubscriberLimitNotificationEvaluator {
  public const SETTINGS_KEY = 'subscriber_limit_threshold_notifications';
  private const THRESHOLDS = [95, 99];

  /** @var SettingsController */
  private $settings;

  /** @var SubscribersFeature */
  private $subscribersFeature;

  /** @var SubscriberLimitNotificationMailer */
  private $mailer;

  /** @var WPFunctions */
  private $wp;

  public function __construct(
    SettingsController $settings,
    SubscribersFeature $subscribersFeature,
    SubscriberLimitNotificationMailer $mailer,
    WPFunctions $wp
  ) {
    $this->settings = $settings;
    $this->subscribersFeature = $subscribersFeature;
    $this->mailer = $mailer;
    $this->wp = $wp;
  }

  public function evaluate(): void {
    $storedState = $this->settings->fetch(self::SETTINGS_KEY, []);
    $state = $this->normalizeState($storedState);
    $limit = $this->subscribersFeature->getSubscriberLimitForNotifications();

    if ($limit === null) {
      if ($storedState) {
        $this->settings->set(self::SETTINGS_KEY, []);
      }
      return;
    }

    if (($state['limit'] ?? null) !== $limit) {
      $state = [
        'limit' => $limit,
        'thresholds' => [],
      ];
    }

    $count = $this->subscribersFeature->getFreshSubscribersCount();
    $stateChanged = false;

    foreach (self::THRESHOLDS as $threshold) {
      $thresholdKey = (string)$threshold;
      $thresholdCount = (int)ceil($limit * $threshold / 100);

      if ($count < $thresholdCount) {
        if (isset($state['thresholds'][$thresholdKey])) {
          unset($state['thresholds'][$thresholdKey]);
          $stateChanged = true;
        }
        continue;
      }

      if (isset($state['thresholds'][$thresholdKey]['sent_at'])) {
        continue;
      }

      if (!$this->mailer->send($threshold, $count, $limit, $this->subscribersFeature->hasValidApiKey())) {
        break;
      }

      $state['thresholds'][$thresholdKey] = [
        'sent_at' => $this->wp->currentTime('mysql', true),
        'count_at_send' => $count,
      ];
      $this->settings->set(self::SETTINGS_KEY, $state);
      $stateChanged = false;
    }

    if ($stateChanged || $this->settings->get(self::SETTINGS_KEY, []) !== $state) {
      $this->settings->set(self::SETTINGS_KEY, $state);
    }
  }

  private function normalizeState($state): array {
    if (!is_array($state)) {
      return [];
    }

    $limit = isset($state['limit']) && is_numeric($state['limit']) ? (int)$state['limit'] : null;
    $thresholds = isset($state['thresholds']) && is_array($state['thresholds']) ? $state['thresholds'] : [];

    return [
      'limit' => $limit,
      'thresholds' => $thresholds,
    ];
  }
}
