<?php
// phpcs:disable
namespace flow\social\publisher;
if (!defined('WPINC'))
	die;

/**
 * Flow-Flow Base Publisher.
 *
 * Abstract base class providing common POST-request handling,
 * error parsing, rate-limit detection, and debug logging for all
 * network-specific publisher implementations.
 *
 * @package   FlowFlow
 * @author    Looks Awesome <email@looks-awesome.com>
 * @link      http://looks-awesome.com
 * @copyright Looks Awesome
 */
abstract class FFBasePublisher implements FFPublisherInterface {

	/** @var string OAuth access token */
	protected $token = '';

	/** @var array Accumulated errors */
	protected $errors = [];

	/** Default cURL timeout in seconds. */
	const REQUEST_TIMEOUT = 30;

	/**
	 * Perform an HTTP POST request with JSON body.
	 *
	 * @param string $url     API endpoint URL.
	 * @param array  $body    Payload (will be JSON-encoded).
	 * @param array  $headers Additional HTTP headers (Authorization is added automatically).
	 *
	 * @return array {response: string, http_code: int, error: string}
	 */
	protected function postJson($url, array $body, array $headers = []) {
		$defaultHeaders = [
			'Content-Type: application/json',
			'Authorization: Bearer ' . $this->token,
		];
		$mergedHeaders = array_merge($defaultHeaders, $headers);

		$ch = curl_init();
		curl_setopt_array($ch, [
			CURLOPT_URL            => $url,
			CURLOPT_POST           => true,
			CURLOPT_POSTFIELDS     => json_encode($body),
			CURLOPT_RETURNTRANSFER => true,
			CURLOPT_HTTPHEADER     => $mergedHeaders,
			CURLOPT_TIMEOUT        => static::REQUEST_TIMEOUT,
			CURLOPT_SSL_VERIFYPEER => true,
			CURLOPT_USERAGENT      => 'Flow-Flow-WordPress/1.0',
		]);

		$response = curl_exec($ch);
		$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		$error    = curl_error($ch);
		curl_close($ch);

		return [
			'response'  => $response,
			'http_code' => $httpCode,
			'error'     => $error,
		];
	}

	/**
	 * Perform a multipart/form-data POST request (for media uploads).
	 *
	 * @param string $url     API endpoint URL.
	 * @param array  $fields  Form fields.
	 * @param array  $headers Additional HTTP headers.
	 *
	 * @return array {response: string, http_code: int, error: string}
	 */
	protected function postMultipart($url, array $fields, array $headers = []) {
		$defaultHeaders = [
			'Authorization: Bearer ' . $this->token,
		];
		$mergedHeaders = array_merge($defaultHeaders, $headers);

		$ch = curl_init();
		curl_setopt_array($ch, [
			CURLOPT_URL            => $url,
			CURLOPT_POST           => true,
			CURLOPT_POSTFIELDS     => $fields,
			CURLOPT_RETURNTRANSFER => true,
			CURLOPT_HTTPHEADER     => $mergedHeaders,
			CURLOPT_TIMEOUT        => 120, // longer timeout for media
			CURLOPT_SSL_VERIFYPEER => true,
			CURLOPT_USERAGENT      => 'Flow-Flow-WordPress/1.0',
		]);

		$response = curl_exec($ch);
		$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		$error    = curl_error($ch);
		curl_close($ch);

		return [
			'response'  => $response,
			'http_code' => $httpCode,
			'error'     => $error,
		];
	}

	/**
	 * Build a standardised success result.
	 *
	 * @param string $postId  Remote post ID.
	 * @param string $postUrl Remote permalink.
	 * @param mixed  $raw     Raw API response.
	 *
	 * @return array
	 */
	protected function successResult($postId = '', $postUrl = '', $raw = null) {
		return [
			'success'  => true,
			'post_id'  => $postId,
			'post_url' => $postUrl,
			'error'    => '',
			'raw'      => $raw,
		];
	}

	/**
	 * Build a standardised error result.
	 *
	 * @param string $message Error message.
	 * @param mixed  $raw     Raw API response.
	 *
	 * @return array
	 */
	protected function errorResult($message, $raw = null) {
		return [
			'success'  => false,
			'post_id'  => '',
			'post_url' => '',
			'error'    => $message,
			'raw'      => $raw,
		];
	}

	/**
	 * Write a debug log entry (uses the same log file as the feed system).
	 *
	 * @param string $msg
	 * @param mixed  $data
	 */
	protected function log($msg, $data = null) {
		$logFile = defined('FF_LOG_FILE_DEST') ? FF_LOG_FILE_DEST : false;
		if (!$logFile) return;

		$ts   = date('Y-m-d H:i:s');
		$net  = $this->getNetwork();
		$line = "[{$ts}] [Publisher:{$net}] {$msg}";
		if ($data !== null) {
			$line .= "\nData: " . print_r($data, true);
		}
		$line .= "\n-----------------------------------\n";
		@error_log($line, 3, $logFile);
	}

	/**
	 * Detect common rate-limit indicators in an API error message.
	 *
	 * @param string $message
	 * @return bool
	 */
	protected function isRateLimitError($message) {
		$indicators = [
			'rate limit',
			'too many requests',
			'throttled',
			'quota exceeded',
			'limit reached',
		];
		$lower = strtolower($message);
		foreach ($indicators as $phrase) {
			if (strpos($lower, $phrase) !== false) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Default canPublish — just checks that the token is non-empty.
	 * Network-specific subclasses should override for real validation.
	 */
	public function canPublish($token) {
		return !empty($token);
	}
}

// phpcs:enable
