<?php
defined('BASEPATH') OR exit('No direct script access allowed');

/**
 * Paystack — thin wrapper around the Paystack REST API for event ticketing.
 * Keys are read from the bloomiris config. Replace test keys with live keys
 * in application/config/bloomiris.php before going live.
 */
#[\AllowDynamicProperties]
class Paystack {

	protected $CI;
	protected $secret;
	protected $public;
	protected $base;

	public function __construct()
	{
		$this->CI =& get_instance();
		$this->CI->config->load('bloomiris', TRUE, TRUE);
		$cfg = $this->CI->config->item('bloomiris');

		// Fall back to flat config items if the group isn't present.
		$this->secret = $this->CI->config->item('paystack_secret_key');
		$this->public = $this->CI->config->item('paystack_public_key');
		$this->base   = $this->CI->config->item('paystack_base_url') ?: 'https://api.paystack.co';
	}

	/** The public key — safe to expose in the browser. */
	public function public_key()
	{
		return $this->public;
	}

	/**
	 * Initialise a transaction. Amount is in the major unit (GHS); Paystack
	 * expects the minor unit (pesewas), so we multiply by 100.
	 * Returns the decoded response array (with data.authorization_url).
	 */
	public function initialize($email, $amount, $reference, $callback_url, $metadata = array())
	{
		$payload = array(
			'email'        => $email,
			'amount'       => (int) round($amount * 100),
			'currency'     => 'GHS',
			'reference'    => $reference,
			'callback_url' => $callback_url,
			'metadata'     => $metadata,
		);
		return $this->request('POST', '/transaction/initialize', $payload);
	}

	/**
	 * Verify a transaction by reference. Returns the decoded response;
	 * a successful payment has data.status === 'success'.
	 */
	public function verify($reference)
	{
		return $this->request('GET', '/transaction/verify/'.rawurlencode($reference));
	}

	/** Generate a unique transaction reference. */
	public function reference($prefix = 'BIA')
	{
		return $prefix.'-'.strtoupper(bin2hex(random_bytes(6))).'-'.time();
	}

	/* --------------------------------------------------------------------
	 * Internal HTTP request via cURL.
	 * ----------------------------------------------------------------- */
	protected function request($method, $path, $body = NULL)
	{
		$ch = curl_init($this->base.$path);
		$headers = array(
			'Authorization: Bearer '.$this->secret,
			'Content-Type: application/json',
			'Cache-Control: no-cache',
		);

		curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
		curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
		curl_setopt($ch, CURLOPT_TIMEOUT, 30);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);

		if ($method === 'POST')
		{
			curl_setopt($ch, CURLOPT_POST, TRUE);
			curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
		}

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

		if ($error)
		{
			return array('status' => FALSE, 'message' => 'Connection error: '.$error);
		}

		$decoded = json_decode($response, TRUE);
		if ( ! is_array($decoded))
		{
			return array('status' => FALSE, 'message' => 'Invalid gateway response.', 'http' => $status);
		}

		return $decoded;
	}
}
