<?php

namespace PloverCRM\Common;

/**
 * Core-native plugin update integration for the private PloverCRM release feed.
 */
class UpdateChecker
{
  public const PLUGIN_SLUG = 'plover-crm';
  public const PLUGIN_FILE = 'plover-crm/plover-crm.php';
  private const UPDATE_URI_HOST = 'plovercrm.com';
  private const UPDATE_CHECK_ROUTE = '/wp-json/plovercrm-hub/v1/update-check';
  private const PLUGIN_INFO_ROUTE = '/wp-json/plovercrm-hub/v1/plugin-info';
  private const LEGACY_STATE_MIGRATION_OPTION = 'plover_crm_core_updater_enabled';

  public static function init(): void
  {
    add_filter('update_plugins_' . self::UPDATE_URI_HOST, [self::class, 'checkForUpdate'], 10, 4);
    add_filter('plugins_api', [self::class, 'pluginInfo'], 10, 3);
    add_action('admin_init', [self::class, 'cleanupLegacyState']);
  }

  /**
   * Supply update metadata when WordPress core checks plugins with a custom Update URI.
   */
  public static function checkForUpdate($update, array $pluginData, string $pluginFile, array $locales)
  {
    if ($pluginFile !== self::PLUGIN_FILE) {
      return $update;
    }

    $license = LicenseChecker::getLicense();
    $token = trim((string) ($license['token'] ?? ''));
    if ($token === '') {
      return false;
    }

    $response = self::requestHub(self::UPDATE_CHECK_ROUTE, [
      'token' => $token,
      'version' => (string) ($pluginData['Version'] ?? PLOVER_CRM_PLUGIN_VERSION),
      'site_url' => home_url('/'),
      'locale' => get_locale(),
    ]);

    if ($response === null) {
      return false;
    }

    return self::buildUpdatePayload($response) ?: false;
  }

  /**
   * Provide the plugin details modal content shown in wp-admin.
   */
  public static function pluginInfo($result, $action, $args)
  {
    if ($action !== 'plugin_information' || ($args->slug ?? '') !== self::PLUGIN_SLUG) {
      return $result;
    }

    $license = LicenseChecker::getLicense();
    $token = trim((string) ($license['token'] ?? ''));

    $response = self::requestHub(self::PLUGIN_INFO_ROUTE, [
      'token' => $token,
      'version' => PLOVER_CRM_PLUGIN_VERSION,
      'site_url' => home_url('/'),
      'locale' => get_user_locale(),
    ]);

    if ($response === null) {
      return $result;
    }

    $pluginInfo = self::buildPluginInfo($response);

    return $pluginInfo ?: $result;
  }

  private static function requestHub(string $route, array $body): ?array
  {
    $response = wp_remote_post(LicenseChecker::getHubUrl() . $route, [
      'body' => $body,
      'timeout' => 15,
      'headers' => [
        'Accept' => 'application/json',
      ],
    ]);

    if (is_wp_error($response)) {
      return null;
    }

    $data = json_decode(wp_remote_retrieve_body($response), true);
    if (!is_array($data)) {
      return null;
    }

    if (!empty($data['error']) && empty($data['version']) && empty($data['name'])) {
      return null;
    }

    return $data;
  }

  public static function cleanupLegacyState(): void
  {
    if (get_option(self::LEGACY_STATE_MIGRATION_OPTION) === '1') {
      return;
    }

    delete_option('plover_crm_update_last_check');
    delete_option('plover_crm_update_data');
    update_option(self::LEGACY_STATE_MIGRATION_OPTION, '1', false);
  }

  private static function buildUpdatePayload(array $data): ?array
  {
    $version = trim((string) ($data['version'] ?? ''));
    if ($version === '') {
      return null;
    }

    $payload = [
      'slug' => self::PLUGIN_SLUG,
      'version' => $version,
      'url' => trim((string) ($data['url'] ?? LicenseChecker::getHubUrl())),
      'package' => trim((string) ($data['package'] ?? '')),
      'requires' => trim((string) ($data['requires'] ?? '')),
      'requires_php' => trim((string) ($data['requires_php'] ?? '')),
      'tested' => trim((string) ($data['tested'] ?? '')),
    ];

    if (array_key_exists('autoupdate', $data)) {
      $payload['autoupdate'] = (bool) $data['autoupdate'];
    }

    return $payload;
  }

  private static function buildPluginInfo(array $data): ?object
  {
    $version = trim((string) ($data['version'] ?? ''));
    if ($version === '') {
      return null;
    }

    $sections = [];
    foreach ((array) ($data['sections'] ?? []) as $key => $section) {
      $key = sanitize_key((string) $key);
      if ($key === '') {
        continue;
      }

      $section = (string) $section;
      if ($section === '') {
        continue;
      }

      $sections[$key] = $section;
    }

    return (object) [
      'name' => trim((string) ($data['name'] ?? 'PloverCRM')) ?: 'PloverCRM',
      'slug' => self::PLUGIN_SLUG,
      'version' => $version,
      'author' => (string) ($data['author'] ?? '<a href="https://plovercrm.com">PloverCRM</a>'),
      'homepage' => trim((string) ($data['homepage'] ?? LicenseChecker::getHubUrl())),
      'download_link' => trim((string) ($data['download_link'] ?? $data['package'] ?? '')),
      'requires' => trim((string) ($data['requires'] ?? '')),
      'requires_php' => trim((string) ($data['requires_php'] ?? '')),
      'tested' => trim((string) ($data['tested'] ?? '')),
      'last_updated' => trim((string) ($data['last_updated'] ?? '')),
      'sections' => $sections,
      'banners' => is_array($data['banners'] ?? null) ? $data['banners'] : [],
      'icons' => is_array($data['icons'] ?? null) ? $data['icons'] : [],
    ];
  }
}
