<?php
namespace PayCal\Core;

defined('ABSPATH') || exit;

class Plugin {
  private static array $admin_notices = [];

  public static function init(): void {
    self::includes();

    if (class_exists(\PayCal\Connector\ConnectorStore::class)) {
      \PayCal\Connector\ConnectorStore::maybe_migrate();
    }

    if (class_exists(\PayCal\Licensing\Cron::class)) {
      add_action('admin_init', [\PayCal\Licensing\Cron::class, 'maybe_schedule']);
      add_action('paycal_license_revalidate', [\PayCal\Licensing\Cron::class, 'revalidate_now']);
    } else {
      self::register_admin_notice('PayCal: License cron is unavailable. License checks will retry after the plugin package is restored.');
    }

    if (class_exists(\PayCal\Core\AdminMenu::class)) {
      add_action('admin_menu', [\PayCal\Core\AdminMenu::class, 'register']);
    } else {
      self::register_admin_notice('PayCal: Admin menu is unavailable because a required file did not load.');
    }

    if (class_exists(\PayCal\Admin\Page_Payments::class)) {
      add_action('admin_menu', [\PayCal\Admin\Page_Payments::class, 'register_menu']);
    }

    if (class_exists(\PayCal\Core\Assets::class)) {
      add_action('admin_enqueue_scripts', [\PayCal\Core\Assets::class, 'enqueue']);
    }

    add_action('admin_notices', [__CLASS__, 'render_admin_notices']);

    if (class_exists(\PayCal\Connector\MerchantDashboard::class)) {
      add_action('init', [\PayCal\Connector\MerchantDashboard::class, 'init']);
    }

    if (class_exists(\PayCal\Gateway\HostedGateway::class)) {
      \PayCal\Gateway\HostedGateway::init();
    } else {
      self::register_admin_notice('PayCal: Hosted gateway is unavailable because a required file did not load.');
    }

    if (class_exists(\PayCal\Modules\Bit\BitModule::class)) {
      add_action('plugins_loaded', [\PayCal\Modules\Bit\BitModule::class, 'init'], 20);
    }

    if (class_exists(\PayCal\Modules\Invoices\InvoicesModule::class)) {
      add_action('plugins_loaded', [\PayCal\Modules\Invoices\InvoicesModule::class, 'init'], 21);
    }
  }

  private static function includes(): void {
    self::safe_require('includes/Core/AdminMenu.php', 'Admin menu');
    self::safe_require('includes/Core/Assets.php', 'Assets');
    self::safe_require('includes/Core/Notices.php', 'Notices');

    self::safe_require('includes/Licensing/LicenseStore.php', 'License store');
    self::safe_require('includes/Licensing/LicenseClient.php', 'License client');
    self::safe_require('includes/Licensing/Gate.php', 'License gate');
    self::safe_require('includes/Licensing/Cron.php', 'License cron');

    self::safe_require('includes/Connector/ConnectorStore.php', 'Connector store');
    self::safe_require('includes/Connector/EventClient.php', 'Connector event client');
    self::safe_require('includes/Gateway/HostedGateway.php', 'Hosted gateway');
    self::safe_require('includes/Connector/SyncClient.php', 'Sync client');
    self::safe_require('includes/Connector/MerchantDashboard.php', 'Merchant dashboard');
    self::safe_require('includes/Connector/DashboardClient.php', 'Dashboard client');

    $permissions_store_loaded = self::safe_require('includes/Permissions/PermissionsStore.php', 'Permissions store');
    $permissions_access_loaded = self::safe_require('includes/Permissions/Access.php', 'Permissions access');

    if (!$permissions_store_loaded || !$permissions_access_loaded) {
      self::safe_require('includes/Core/PermissionFallback.php', 'Permissions fallback');
      self::register_admin_notice('PayCal: מודול ההרשאות נטען במצב בטוח כי חסר קובץ מערכת. האתר ממשיך לפעול, אבל מומלץ להעלות שוב את כל קבצי התוסף.');
    }

    self::safe_require('includes/Admin/Page_Dashboard.php', 'Dashboard page');
    self::safe_require('includes/Admin/Page_Marketplace.php', 'Marketplace page');
    self::safe_require('includes/Admin/Page_License.php', 'License page');
    self::safe_require('includes/Admin/Page_Wizard.php', 'Setup page');
    self::safe_require('includes/Admin/Page_Permissions.php', 'Permissions page');
    self::safe_require('includes/Admin/Page_Connector.php', 'Connector page');
    self::safe_require('includes/Admin/Page_Payments.php', 'Payments dashboard page');

    self::safe_require('includes/Admin/Page_Bit.php', 'Bit page');
    self::safe_require('includes/Admin/Page_Invoices.php', 'Invoices page');

    self::safe_require('includes/Modules/Bit/BitModule.php', 'Bit module');
    self::safe_require('includes/Modules/Invoices/InvoicesModule.php', 'Invoices module');
  }

  public static function safe_require(string $relative_path, string $module_name = ''): bool {
    $file = PAYCAL_PATH . ltrim($relative_path, '/');

    if (file_exists($file)) {
      try {
        require_once $file;
        return true;
      } catch (\Throwable $e) {
        $label = $module_name !== '' ? $module_name : $relative_path;
        self::register_admin_notice(sprintf('PayCal: %s failed to load safely. Check the server error log and reinstall the plugin package if needed.', $label));
        \paycal_debug_log('[PayCal] Failed loading file ' . $relative_path . ': ' . $e->getMessage());
        return false;
      }
    }

    $label = $module_name !== '' ? $module_name : $relative_path;
    self::register_admin_notice(sprintf('PayCal: %s לא נטען כי הקובץ חסר (%s).', $label, $relative_path));
    \paycal_debug_log('[PayCal] Missing file: ' . $relative_path);
    return false;
  }

  public static function register_admin_notice(string $message): void {
    if (!in_array($message, self::$admin_notices, true)) {
      self::$admin_notices[] = $message;
    }
  }

  public static function render_admin_notices(): void {
    if (empty(self::$admin_notices) || !current_user_can('manage_options')) {
      return;
    }

    foreach (self::$admin_notices as $message) {
      echo '<div class="notice notice-warning"><p>' . esc_html($message) . '</p></div>';
    }
  }
}
