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

class MY_Controller extends CI_Controller
{
	protected string $layout = 'layouts/main';
	protected array $layoutData = [];
	protected string $theme = 'dark';
	protected array $styles = array('assets/css/app.css');
	protected array $scripts = array('assets/js/app.js');
	protected bool $requireAuth = true;
	protected array $allowedRoles = []; // empty = any authenticated user
	public bool $capture_render_table = false;
	public $last_render_table_output = null;

	public function __construct()
	{
		parent::__construct();
		$this->bootstrapComposer();

		$this->guard();

		// Load core app config and modules once per request.
		$this->bootstrapAppConfig();

		// UI data for authenticated users
		if ($this->requireAuth && $this->session->userdata('loggedin')) {
			$this->prime_user_context();
		}
	}

	/**
	 * Hydrate common user vars (cached) for quicker loads.
	 */
	protected function prime_user_context(): void
	{
		$userId = (int) ($this->session->userdata('user_id') ?? 0);
		if (!$userId) {
			return;
		}
		$userType = (int) ($this->session->userdata('user_type') ?? 0);
		$contextKey = 'user_chrome_context_' . $userId . '_' . $userType;
		$cachedContext = $this->cache->get($contextKey);
		if (is_array($cachedContext)) {
			$this->load->vars($cachedContext);
			return;
		}

		// Unread notifications count (cache 60s)
		$notifKey = 'unread_notif_count_' . $userId;
		$unread = $this->cache->get($notifKey);
		if ($unread === FALSE) {
			$unread = (int) $this->db
				->where(['to_user_id' => $userId, 'read' => 0])
				->count_all_results('tbl_notifications');
			$this->cache->save($notifKey, $unread, 60);
		}

		// Default currency symbol (cache 5 min)
		$currencyKey = 'default_currency_symbol';
		$symbol = $this->cache->get($currencyKey);
		if ($symbol === FALSE) {
			$defaultCurrency = config_item('default_currency');
			$symbolRow = $this->db
				->where('code', $defaultCurrency)
				->get('tbl_currencies')
				->row();
			$symbol = $symbolRow->symbol ?? '';
			$this->cache->save($currencyKey, $symbol, 300);
		}
		$this->load->model(['Menu_model']);
		if ($userType === 2) {
			$menu_tree = $this->Menu_model->get_active_tree(false, true);
		} else {
			$menu_tree = $this->Menu_model->get_active_tree();
		}
		$current_user_profile = profile($userId);
		$chromeContext = [
			'unread_notifications' => $unread,
			'd_currency' => $symbol,
			'menu_tree' => $menu_tree,
			'current_user_profile' => $current_user_profile,
		];
		$this->cache->save($contextKey, $chromeContext, 300);
		$this->load->vars($chromeContext);
	}

	/**
	 * Basic session/role guard (fast, session-only).
	 */
	protected function guard(): void
	{

		if (!$this->requireAuth) {
			return;
		}

		$controller = strtolower($this->router->class ?? '');
		if (in_array($controller, ['login', 'install'])) {
			return;
		}

		if (!$this->session->userdata('loggedin')) {
			// Try "remember me" once per request when no session exists.
			$this->load->model('Login_model', 'auth');
			$this->auth->resume_from_remember();
		}

		if (!$this->session->userdata('loggedin')) {
			$this->session->set_userdata('url', uri_string());
			redirect('login');
		}

		if (!empty($this->allowedRoles)) {
			$role = (int) ($this->session->userdata('user_type') ?? 0);
			if (!in_array($role, $this->allowedRoles, true)) {
				show_error('Unauthorized', 403);
			}
		}
	}

	/**
	 * Load modules and cached config/lang early for all controllers (including Login).
	 */
	protected function bootstrapAppConfig(): void
	{
		// Load required helpers/libraries once.
		$this->load->driver('cache', ['adapter' => 'file']);
		$this->load->model('admin_model');

		// Module loading is handled via hooks; keep this lean for faster bootstrap.

		// Load app config from cache or DB.
		$config_data = $this->cache->get('app_config_data');
		if (!$config_data) {
			$config_data = $this->db->get('tbl_config')->result();
			$this->cache->save('app_config_data', $config_data, 300); // 5 minutes
		}
		if (!empty($config_data)) {
			foreach ($config_data as $row) {
				if (isset($row->config_key)) {
					$this->config->set_item($row->config_key, $row->value ?? null);
				}
			}
		}

		// Load language files based on system language.
		$langCacheKey = 'system_lang_' . ((int) ($this->session->userdata('user_id') ?? 0));
		$system_lang = $this->cache->get($langCacheKey);
		if ($system_lang === FALSE) {
			$system_lang = $this->admin_model->get_lang();
			$this->cache->save($langCacheKey, $system_lang, 300);
		}
		if ($system_lang) {
			$this->config->set_item('language', $system_lang);
		}

		if (method_exists($this->admin_model, 'all_files')) {
			$files = $this->cache->get('app_lang_file_map');
			if ($files === FALSE) {
				$files = $this->admin_model->all_files();
				$this->cache->save('app_lang_file_map', $files, 86400);
			}
			$langToUse = $system_lang ?: 'english';
			if (!empty($files)) {
				foreach ($files as $file => $altpath) {
					$shortfile = str_replace("_lang.php", "", $file);
					$this->lang->load($shortfile, $langToUse);
				}
			}
		}
	}

	protected function add_style(string $href): void
	{
		$this->styles[] = $href;
	}

	protected function add_script(string $src, bool $defer = true): void
	{
		$this->scripts[] = ['src' => $src, 'defer' => $defer];
	}
	private function bootstrapComposer(): void
	{
		$autoload = realpath(APPPATH . '../vendor/autoload.php');
		if ($autoload && file_exists($autoload)) {
			require_once $autoload;
		}
	}

	// protected function navItems()
	// {
	// 	return array(
	// 		array('id' => 'dashboard', 'label' => 'Dashboard', 'icon' => 'layout-dashboard'),
	// 		array('id' => 'analytics', 'label' => 'Analytics', 'icon' => 'pie-chart'),
	// 		array('id' => 'ecommerce', 'label' => 'E-commerce', 'icon' => 'shopping-cart'),
	// 		array('id' => 'fintech', 'label' => 'Fintech', 'icon' => 'credit-card'),
	// 		array(
	// 			'id' => 'crm',
	// 			'label' => 'CRM',
	// 			'icon' => 'users',
	// 			'children' => array(
	// 				array('id' => 'leads', 'label' => 'Leads'),
	// 				array('id' => 'customers', 'label' => 'Customers'),
	// 				array('id' => 'deals', 'label' => 'Deals Pipeline'),
	// 			),
	// 		),
	// 		array('id' => 'projects', 'label' => 'Projects', 'icon' => 'briefcase'),
	// 		array('id' => 'messaging', 'label' => 'Messaging', 'icon' => 'message-square'),
	// 		array(
	// 			'id' => 'hr',
	// 			'label' => 'HR & Team',
	// 			'icon' => 'users-2',
	// 			'children' => array(
	// 				array('id' => 'employees', 'label' => 'Employees'),
	// 				array('id' => 'recruitment', 'label' => 'Recruitment'),
	// 				array('id' => 'leave', 'label' => 'Leave Mgmt'),
	// 				array('id' => 'payrolls', 'label' => 'Payrolls'),
	// 			),
	// 		),
	// 		array(
	// 			'id' => 'finance',
	// 			'label' => 'Finance',
	// 			'icon' => 'file-text',
	// 			'children' => array(
	// 				array('id' => 'invoices', 'label' => 'Invoices'),
	// 				array('id' => 'expenses', 'label' => 'Expenses'),
	// 			),
	// 		),
	// 		array('id' => 'inventory', 'label' => 'Inventory', 'icon' => 'package'),
	// 		array(
	// 			'id' => 'pos',
	// 			'label' => 'Restaurant POS',
	// 			'icon' => 'utensils',
	// 			'children' => array(
	// 				array('id' => 'pos-menu', 'label' => 'Menu Items'),
	// 				array('id' => 'pos-floor', 'label' => 'Floor Plan'),
	// 				array('id' => 'pos-terminal', 'label' => 'POS Terminal'),
	// 				array('id' => 'pos-orders', 'label' => 'Kitchen Orders'),
	// 			),
	// 		),
	// 		array('id' => 'calendar', 'label' => 'Calendar', 'icon' => 'calendar'),
	// 		array('id' => 'settings', 'label' => 'Settings', 'icon' => 'settings'),
	// 		array('id' => 'help', 'label' => 'Help Center', 'icon' => 'help-circle'),
	// 	);
	// }

	/**
	 * Render a view inside the default layout, passing along shared data.
	 */
	protected function render($view, array $data = array())
	{
		$data = array_merge($this->layoutData, $data);
		$data['styles'] = array_unique($this->styles);
		$data['scripts'] = array_unique($this->scripts);
		$data['subview'] = $this->load->view($view, $data, true);
		$this->load->view($this->layout, $data);
	}

	protected function capture_datatable_preload(callable $callback)
	{
		$originalPost = $_POST;
		$originalHeader = $_SERVER['HTTP_X_REQUESTED_WITH'] ?? null;
		$this->capture_render_table = true;
		$this->last_render_table_output = null;

		if (!isset($_POST['length'])) {
			$_POST['length'] = config_item('tables_pagination_limit') ?: 10;
		}
		if (!isset($_POST['start'])) {
			$_POST['start'] = 0;
		}
		if (!isset($_POST['draw'])) {
			$_POST['draw'] = 1;
		}
		if (!isset($_POST['search'])) {
			$_POST['search'] = array('value' => '', 'regex' => 'false');
		}
		$_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';

		try {
			call_user_func($callback);
			return is_array($this->last_render_table_output) ? $this->last_render_table_output : null;
		} finally {
			$this->capture_render_table = false;
			$this->last_render_table_output = null;
			$_POST = $originalPost;
			if ($originalHeader === null) {
				unset($_SERVER['HTTP_X_REQUESTED_WITH']);
			} else {
				$_SERVER['HTTP_X_REQUESTED_WITH'] = $originalHeader;
			}
		}
	}
}
