<?php declare(strict_types=1);
/**
 * @author Ryan Spaeth <rspaeth@spaethtech.com>
 * @copyright 2025 - Spaeth Technologies, Archous Networks
 */

namespace SpaethTech\UCRM\SDK\Controllers;

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class ServicesSyncController extends BaseController
{

  public function sync(Request $request, Response $response): Response
  {
    try {
      // No authentication required for this endpoint
      // The worst case is someone tries to DoS with sync requests
      // which is rate-limited at the infrastructure level

      // NOTE: If we ever need to add auth checks in the future,
      // we should use the nms-session cookies from UISP rather than
      // exposing API tokens in client-side JavaScript

      $body = $request->getParsedBody();

      // Extract service IDs if provided
      $ids = [];
      if (isset($body["ids"])) {
        if (!is_array($body["ids"])) {
          return $this->json(
            $response,
            "Parameter 'ids' must be an array",
            400
          );
        }
        $ids = array_filter($body["ids"], "is_numeric");
      }

      // Get auth token from plugin auth
      $auth = $this->plugin->getAuth();
      if (!$auth) {
        return $this->json($response, "Unable to get authentication", 500);
      }

      $authToken = $auth->getXAuthToken();
      if (empty($authToken)) {
        return $this->json($response, "Authentication token not configured", 500);
      }

      // Get the provisioner URL from config
      $config = $this->plugin->getConfig();
      $provisionerUrl = $config->get('provisioner_url');

      if (empty($provisionerUrl)) {
        return $this->json($response, "Provisioner URL not configured", 500);
      }

      // Prepare request to provisioner's /api/v2/configs/sync
      $syncData = [
        "ids" => $ids,
        "source" => "uisp_admin_sync"
      ];

      error_log("[PAPI] (services/sync) Calling provisioner at $provisionerUrl with " . count($ids) . " IDs");

      try {
        // Make the request to the provisioner
        $provisionerResponse = $this->client->request(
          'POST',
          $provisionerUrl . '/api/v2/configs/sync',
          [
            'json' => $syncData,
            'headers' => [
              'X-Auth-Token' => $authToken,
              'Content-Type' => 'application/json'
            ],
            'timeout' => 30,
            'http_errors' => false
          ]
        );

        $statusCode = $provisionerResponse->getStatusCode();
        $responseBody = (string) $provisionerResponse->getBody();
        $responseData = json_decode($responseBody, true);

        if ($statusCode !== 200) {
          error_log("[PAPI] (services/sync) Provisioner returned error: $statusCode - $responseBody");
          return $this->json(
            $response,
            $responseData['error'] ?? "Provisioner sync failed",
            $statusCode
          );
        }

        error_log("[PAPI] (services/sync) Sync completed successfully");
        return $this->json($response, $responseData);

      } catch (\GuzzleHttp\Exception\RequestException $e) {
        error_log("[PAPI] (services/sync) Request to provisioner failed: " . $e->getMessage());
        return $this->json($response, "Failed to connect to provisioner", 503);
      }

    } catch (\Exception $e) {
      // error_log("[PAPI] (services/sync) Error: " . $e->getMessage());
      return $this->json($response, "Internal server error", 500);
    }
  }
}