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

/**
 * Pay — Paystack event-ticket checkout and verification.
 * Flow: ticket() creates a pending ticket + initialises Paystack ->
 *       Paystack redirects to callback() -> verify -> mark paid.
 */
#[\AllowDynamicProperties]
class Pay extends Public_Controller {

	public function __construct()
	{
		parent::__construct();
		$this->load->model(array('event_model', 'ticket_model'));
		$this->load->library('paystack');
	}

	/** Create a pending ticket and redirect to Paystack. */
	public function ticket($event_id)
	{
		$event = $this->event_model->get($event_id);
		if ( ! $event || ! $event['is_paid'])
		{
			show_error('This event is not available for ticketing.', 400);
		}

		$this->load->library('form_validation');
		$this->form_validation->set_rules('name', 'Name', 'required|trim');
		$this->form_validation->set_rules('email', 'Email', 'required|trim|valid_email');
		$this->form_validation->set_rules('quantity', 'Quantity', 'required|integer|greater_than[0]|less_than[11]');

		if ($this->form_validation->run() === FALSE)
		{
			$this->session->set_flashdata('error', 'Please complete the ticket form correctly.');
			redirect('events/view/'.$event['slug']);
		}

		$quantity  = (int) $this->input->post('quantity');
		$amount    = $quantity * (float) $event['ticket_price'];
		$reference = $this->paystack->reference('BIA');

		// Persist a pending ticket record.
		$ticket_id = $this->ticket_model->insert(array(
			'event_id'       => $event['id'],
			'name'           => $this->input->post('name', TRUE),
			'email'          => $this->input->post('email', TRUE),
			'phone'          => $this->input->post('phone', TRUE),
			'quantity'       => $quantity,
			'amount'         => $amount,
			'reference'      => $reference,
			'payment_status' => 'pending',
		));

		// Initialise the Paystack transaction.
		$response = $this->paystack->initialize(
			$this->input->post('email', TRUE),
			$amount,
			$reference,
			base_url('pay/callback'),
			array('event' => $event['title'], 'ticket_id' => $ticket_id)
		);

		if ( ! empty($response['status']) && ! empty($response['data']['authorization_url']))
		{
			redirect($response['data']['authorization_url']);
		}

		$this->session->set_flashdata('error',
			'We could not start the payment. '.($response['message'] ?? 'Please try again.'));
		redirect('events/view/'.$event['slug']);
	}

	/** Paystack redirects here after payment. */
	public function callback()
	{
		$reference = $this->input->get('reference', TRUE)
			?: $this->input->get('trxref', TRUE);

		if ( ! $reference)
		{
			show_error('No payment reference supplied.', 400);
		}

		$ticket = $this->ticket_model->by_reference($reference);
		if ( ! $ticket)
		{
			show_error('Ticket record not found.', 404);
		}

		$event = $this->event_model->get($ticket['event_id']);

		// Verify with Paystack.
		$result = $this->paystack->verify($reference);
		$paid = ! empty($result['status'])
			&& ! empty($result['data']['status'])
			&& $result['data']['status'] === 'success';

		if ($paid && $ticket['payment_status'] !== 'paid')
		{
			$code = 'BIA-'.strtoupper(bin2hex(random_bytes(4)));
			$this->ticket_model->mark_paid($ticket['id'], $code);
			$ticket['ticket_code']    = $code;
			$ticket['payment_status'] = 'paid';

			// Email the ticket confirmation.
			$this->load->library('mailer');
			$this->mailer->send(
				$ticket['email'],
				'Your ticket is confirmed — '.$event['title'],
				'Your ticket is confirmed!',
				'<p>Hi '.html_escape($ticket['name']).',</p>'
				.'<p>Your payment was successful. Here is your ticket:</p>'
				.'<p style="font-size:22px;font-weight:bold;letter-spacing:2px;color:#631A6C;">'
				.html_escape($code).'</p>'
				.'<p><strong>Event:</strong> '.html_escape($event['title']).'<br>'
				.'<strong>Date:</strong> '.nice_date($event['event_date'], 'l, d M Y').'<br>'
				.'<strong>Tickets:</strong> '.$ticket['quantity'].'</p>'
				.'<p>Please present this code at the entrance. We look forward to seeing you!</p>'
			);
		}
		elseif ( ! $paid)
		{
			$this->ticket_model->update($ticket['id'], array('payment_status' => 'failed'));
		}

		$this->meta(array('title' => 'Payment '.($paid ? 'Confirmed' : 'Failed').' — Bloom Iris Agency'));
		$this->render('pay/result', array(
			'paid'   => $paid,
			'ticket' => $ticket,
			'event'  => $event,
		));
	}
}
