<?php

/**
 * SquareAuthController
 *
 * REST endpoints for saving, checking and clearing the Square OAuth token.
 * Persists tokens, verifies Apple-Pay domain and provisions Square webhooks
 * via the central PAT proxy (handled by WebhookManager).
 *
 * @package Pixeldev\SquareWooSync\REST
 */

namespace Pixeldev\SquareWooSync\REST;

use Pixeldev\SquareWooSync\Abstracts\RESTController;
use Pixeldev\SquareWooSync\Payments\ApplePayDomainVerifier;
use Pixeldev\SquareWooSync\Security\SquareTokenManager;
use Pixeldev\SquareWooSync\Setup\WebhookManager;
use Pixeldev\SquareWooSync\Square\SquareHelper;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;
use WP_Error;

defined('ABSPATH') || exit;

/**
 * Class SquareAuthController
 */
class SquareAuthController extends RESTController
{

  /**
   * Route base (e.g. /sws/v1/square/*).
   *
   * @var string
   */
  protected $base = 'square';

  /**
   * Webhook events always required by the plugin.
   *
   * @var string[]
   */
  private const WEBHOOK_EVENTS = [
    'catalog.version.updated',
    'inventory.count.updated',
    'customer.updated',
    'customer.created',
    'order.created',
    'order.fulfillment.updated',
  ];

  /**
   * Register REST routes.
   *
   * @return void
   */
  public function register_routes(): void
  {

    register_rest_route(
      $this->namespace,
      '/' . $this->base . '/save-token',
      [
        'methods'             => WP_REST_Server::CREATABLE,
        'callback'            => [$this, 'save_access_token'],
        'permission_callback' => [$this, 'check_permission'],
      ]
    );

    register_rest_route(
      $this->namespace,
      '/' . $this->base . '/check-token',
      [
        'methods'             => WP_REST_Server::READABLE,
        'callback'            => [$this, 'check_access_token'],
        'permission_callback' => [$this, 'check_permission'],
      ]
    );

    register_rest_route(
      $this->namespace,
      '/' . $this->base . '/clear-token',
      [
        'methods'             => WP_REST_Server::DELETABLE,
        'callback'            => [$this, 'clear_access_token'],
        'permission_callback' => [$this, 'check_permission'],
      ]
    );
  }

  /* ─────────────────────────────────────────────────────────────
	 *  SAVE TOKEN
	 * ──────────────────────────────────────────────────────────── */

  /**
   * Persist access/refresh tokens, verify domain & set up webhooks.
   *
   * @param WP_REST_Request $request Incoming request.
   * @return WP_REST_Response|WP_Error
   */
  public function save_access_token(WP_REST_Request $request)
  {

    if (! current_user_can('manage_options')) {
      return new WP_Error('forbidden', 'Insufficient permissions', ['status' => 403]);
    }

    $access  = $request->get_param('access_token');
    $refresh = $request->get_param('refresh_token');

    if (! $access || ! $refresh) {
      return new WP_Error('bad_request', 'Missing token(s)', ['status' => 400]);
    }

    try {
      SquareTokenManager::save($access, $refresh);
    } catch (\Exception $e) {
      return new WP_Error('save_failed', $e->getMessage(), ['status' => 500]);
    }

    $settings = get_option('square-woo-sync_settings', []);
    $env      = ($settings['environment'] ?? 'live') === 'sandbox' ? 'sandbox' : 'live';

    $domain_verified = ApplePayDomainVerifier::verify($access, $env);

    $cache_key = 'sws_square_token_status';
    $helper    = new SquareHelper();
    $resp      = $helper->square_api_request('/merchants/me', 'GET', null, $access);

    $merchant_name = 'SquareSync for Woo Pro';
    $merchant_id   = '';

    if ($resp['success']) {
      $merchant_name = $resp['data']['merchant']['business_name'] ?? '';
      $merchant_id   = $resp['data']['merchant']['id'] ?? '';
      error_log("merchand id: $merchant_id");
      update_option(
        $cache_key,
        [
          'valid'    => true,
          'merchant' => $merchant_name,
          'merchant_id' => $merchant_id,
          'checked'  => time(),
        ],
        false
      );
    }

    if (isset($settings['access_token'])) {
      // Remove legacy webhooks.
      /** @var array<int, array<string, mixed>> $active_legacy_webhooks */
      $active_legacy_webhooks = $helper->get_webhook_subscriptions();

      foreach ($active_legacy_webhooks as $subscription) {
        if (!empty($subscription['id']) && !empty($subscription['enabled'])) {
          $subscription_id = $subscription['id'];
          // Only disable if currently enabled
          if ($subscription['enabled'] === true) {
            $helper->update_webhook_subscription_status($subscription_id, false);
          }
        }
      }
    }

    delete_transient('sws_square_locations');
    delete_transient('sws_square_modifiers');
    delete_transient('sws_square_categories');
    delete_transient('sws_square_groups_segments');


    return new WP_REST_Response(
      [
        'message'                 => 'Access token saved',
        'env'                     => $env,
        'domain_verified'         => $domain_verified,
        'merchant_name'           => $merchant_name,
        'merchant_id'             => $merchant_id,
      ],
      200
    );
  }

  // /**
  //  * Ask the remote PAT-proxy to create missing webhooks.
  //  *
  //  * @param string $merchant_id Square merchant ID.
  //  * @param string $env         live|sandbox.
  //  * @return bool True when proxy responds 201/200.
  //  */
  // private function kickoff_webhook_setup(string $merchant_id, string $merchant_name, string $env): bool
  // {

  //   $callback_url = rest_url('sws/v1/square-inventory/update');
  //   $wm           = new WebhookManager();

  //   $proxy = $wm->create(
  //     $merchant_id,
  //     $merchant_name,
  //     $callback_url,
  //     self::WEBHOOK_EVENTS,
  //     $env
  //   );

  //   if (! $proxy['success']) {
  //     error_log('[SquareWooSync] Webhook provisioning failed: ' . ($proxy['error'] ?? 'unknown'));
  //   }

  //   /* Square (via the proxy) responded with:
  //  * { subscription: { id: 'wbhk_...' , ... } }
  //  */
  //   $sub_id = $create['data']['subscription']['id'] ?? '';
  //   if ($sub_id) {
  //     $this->persist_webhook_id($env, $sub_id);
  //   }

  //   return $proxy['success'];
  // }

  /**
   * Persist the subscription-ID inside the main settings array so
   * later CRUD calls (pause/delete) can fetch it instantly.
   *
   * @param string $env     live|sandbox
   * @param string $sub_id  Square subscription UUID
   * @return void
   */
  private function persist_webhook_id(string $env, string $sub_id): void
  {
    $key       = $env === 'sandbox' ? 'webhook_id_sandbox' : 'webhook_id_live';
    $settings  = get_option('square-woo-sync_settings', []);
    $settings[$key] = $sub_id;
    update_option('square-woo-sync_settings', $settings, false);
  }

  /* ─────────────────────────────────────────────────────────────
	 *  CHECK TOKEN
	 * ──────────────────────────────────────────────────────────── */

  public function check_access_token(WP_REST_Request $request)
  { // phpcs:ignore

    $token = SquareTokenManager::get();
    if (! $token) {
      return new WP_REST_Response(['exists' => false], 200);
    }

    $cache_key = 'sws_square_token_status';
    $cached    = get_option($cache_key);

    if ($cached && (time() - $cached['checked']) < HOUR_IN_SECONDS) {
      return new WP_REST_Response(
        [
          'exists'   => $cached['valid'],
          'merchant' => $cached['merchant'] ?? '',
          'merchant_id' => $cached['merchant_id'] ?? '',
        ],
        200
      );
    }

    $helper = new SquareHelper();
    $resp   = $helper->square_api_request('/merchants/me', 'GET', null, $token);

    if ($resp['success']) {
      $merchant_name = $resp['data']['merchant']['business_name'] ?? '';
      $merchant_id   = $resp['data']['merchant']['id'] ?? '';
      update_option(
        $cache_key,
        [
          'valid'    => true,
          'merchant' => $merchant_name,
          'merchant_id' => $merchant_id,
          'checked'  => time(),
        ],
        false
      );

      return new WP_REST_Response(
        [
          'exists'   => true,
          'merchant' => $merchant_name,
          'merchant_id' => $merchant_id,
        ],
        200
      );
    }

    SquareTokenManager::clear();
    update_option(
      $cache_key,
      [
        'valid'   => false,
        'checked' => time(),
      ],
      false
    );

    return new WP_REST_Response(['exists' => false], 200);
  }

  /* ─────────────────────────────────────────────────────────────
	 *  CLEAR TOKEN
	 * ──────────────────────────────────────────────────────────── */

  public function clear_access_token(WP_REST_Request $request)
  {

    $cache_key = 'sws_square_token_status';

    /* read env + merchant_id before you delete them */
    $settings     = get_option('square-woo-sync_settings', []);
    $env          = ($settings['environment'] ?? 'live') === 'sandbox' ? 'sandbox' : 'live';

    $helper    = new SquareHelper();
    $resp   = $helper->square_api_request('/merchants/me', 'GET');
    $merchant_id = '';

    if ($resp['success']) {
      $merchant_id   = $resp['data']['merchant']['id'] ?? '';
    }
    
    /* clear local tokens/cache */
    SquareTokenManager::clear();
    update_option($cache_key, ['valid' => false, 'checked' => time()], false);
    delete_transient('sws_square_locations');
    delete_transient('sws_square_modifiers');
    delete_transient('sws_square_categories');
    delete_transient('sws_square_groups_segments');

    /* inform the remote proxy */
    if ($merchant_id) {
      wp_remote_request(
        'https://proxy.squaresyncforwoo.com/wp-json/square-oauth/v1/remove-mapping',
        [
          'method'  => 'DELETE',
          'headers' => ['Content-Type' => 'application/json'],
          'body'    => wp_json_encode([
            'env'         => $env,
            'merchant_id' => $merchant_id,
          ]),
          'timeout' => 8,
          'blocking' => false,   // fire-and-forget
        ]
      );
    }

    return new WP_REST_Response(
      ['message' => 'Access token cleared successfully'],
      200
    );
  }
}
