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

/**
 * Bloom Iris Agency - Base Controller Hierarchy
 * --------------------------------------------------------------------------
 * MY_Controller        : shared foundation (extends MX_Controller for HMVC)
 *   Public_Controller  : front-end pages (loads public layout data, settings)
 *   Admin_Controller   : back-office (enforces authentication + RBAC)
 * --------------------------------------------------------------------------
 */
/* HMVC dependency chain: Ci.php defines the CI super-object accessor that
 * MX_Controller relies on. Load it (and the module bootstrap) before the
 * MX_Controller class definition. */
require_once APPPATH.'third_party/MX/Modules.php';
require_once APPPATH.'third_party/MX/Base.php';
require_once APPPATH.'third_party/MX/Ci.php';
require_once APPPATH.'third_party/MX/Controller.php';

#[\AllowDynamicProperties]
class MY_Controller extends MX_Controller {

	/** @var array Global settings loaded from the settings table */
	protected $settings = array();

	/** @var array Data passed through to views */
	protected $data = array();

	public function __construct()
	{
		parent::__construct();

		// Core libraries used everywhere
		$this->load->database();
		$this->load->library(array('session'));
		$this->load->helper(array('url', 'form', 'text', 'date', 'bloom', 'ui'));
		$this->load->model('setting_model');

		// Load all settings as a key => value map, available site-wide
		$this->settings = $this->setting_model->all();
		$this->data['settings'] = $this->settings;
		$this->data['s'] = $this->settings; // short alias for views
	}

	/**
	 * Retrieve a single setting value with an optional fallback.
	 */
	protected function setting($key, $default = '')
	{
		return isset($this->settings[$key]) && $this->settings[$key] !== ''
			? $this->settings[$key]
			: $default;
	}
}

/* ========================================================================
 * PUBLIC CONTROLLER — front-end pages
 * ===================================================================== */
#[\AllowDynamicProperties]
class Public_Controller extends MY_Controller {

	public function __construct()
	{
		parent::__construct();

		// Maintenance / Coming-Soon mode (admins bypass it)
		if ($this->setting('maintenance_mode') == '1'
			&& ! $this->session->userdata('admin_logged_in'))
		{
			$this->_render_coming_soon();
		}

		// Models commonly needed for layout partials (footer, sliders)
		$this->load->model(array('partner_model', 'service_model'));

		// Default SEO meta — individual pages may override these
		$this->data['meta'] = array(
			'title'       => $this->setting('site_name', 'Bloom Iris Agency'),
			'description' => $this->setting('meta_description', ''),
			'keywords'    => $this->setting('meta_keywords', ''),
			'image'       => base_url('assets/img/og-default.jpg'),
			'url'         => current_url(),
		);
	}

	/**
	 * Render a public page wrapped in the standard header/footer layout.
	 */
	protected function render($view, $data = array())
	{
		$data = array_merge($this->data, $data);

		// Footer data — partners for slider, services for footer menu
		$data['footer_partners'] = $this->partner_model->active();
		$data['footer_services'] = $this->service_model->active();

		$this->load->view('layouts/public_header', $data);
		$this->load->view($view, $data);
		$this->load->view('layouts/public_footer', $data);
	}

	/**
	 * Merge custom SEO meta into the default block.
	 */
	protected function meta($meta = array())
	{
		$this->data['meta'] = array_merge($this->data['meta'], $meta);
	}

	private function _render_coming_soon()
	{
		$this->load->view('errors/coming_soon', $this->data);
		exit;
	}
}

/* ========================================================================
 * ADMIN CONTROLLER — back-office, enforces auth + RBAC
 * ===================================================================== */
#[\AllowDynamicProperties]
class Admin_Controller extends MY_Controller {

	/** @var array The authenticated admin user row */
	protected $user = array();

	/** Minimum role required for this controller. Override in children. */
	protected $required_role = 'editor';

	public function __construct()
	{
		parent::__construct();

		$this->load->library(array('auth', 'uploader'));
		$this->load->model(array('activity_model'));

		// Enforce login on every admin controller except Login itself
		if ( ! $this->auth->logged_in())
		{
			redirect('admin/login');
		}

		$this->user = $this->auth->user();
		$this->data['user'] = $this->user;

		// Role-based access control
		if ( ! $this->auth->has_role($this->required_role))
		{
			show_error('You do not have permission to access this area.', 403, 'Access Denied');
		}

		// Active menu highlighting helper
		$this->data['active'] = $this->router->fetch_class();
	}

	/**
	 * Render an admin page wrapped in the admin layout.
	 */
	protected function render($view, $data = array())
	{
		$data = array_merge($this->data, $data);
		$data['_content'] = $this->load->view($view, $data, TRUE);
		$this->load->view('admin/_layout', $data);
	}

	/**
	 * Convenience wrapper: upload a single file via the Uploader library.
	 * Returns the relative path on success, or NULL.
	 */
	protected function upload($field, $folder, $types = 'jpg|jpeg|png|webp', $max_size = NULL)
	{
		return $this->uploader->file($field, $folder, $types, $max_size);
	}

	/**
	 * Log an admin action to the activity audit trail.
	 */
	protected function log($action, $detail = '')
	{
		$this->activity_model->record($this->user['id'], $action, $detail);
	}
}
