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

class Catalog_auth
{
	const SESSION_KEY = 'catalog_user';

	/** @var CI_Controller */
	private $ci;
	private $db_gala;
	private $db_catalog;

	public function __construct()
	{
		$this->ci =& get_instance();
		$this->db_catalog = $this->ci->load->database('catalogo_rw', TRUE);
		$this->db_gala = $this->ci->load->database('gala_ro', TRUE);
		$this->ci->load->library('session');
	}

	public function attempt_login($username, $password)
	{
		$user = $this->db_gala
			->select('e.person_id, e.id, e.username, e.password, e.deleted, p.first_name, p.last_name')
			->from('phppos_employees e')
			->join('phppos_people p', 'p.person_id = e.person_id', 'left')
			->where('e.username', $username)
			->where('e.deleted', 0)
			->limit(1)
			->get()
			->row_array();

		if (!$user)
		{
			return array('ok' => FALSE, 'message' => 'Usuario o clave invalida.');
		}

		if (!$this->verify_password($password, $user['password']))
		{
			return array('ok' => FALSE, 'message' => 'Usuario o clave invalida.');
		}

		$session_user = array(
			'person_id' => (int) $user['person_id'],
			'employee_id' => (int) $user['id'],
			'username' => $user['username'],
			'name' => trim($user['first_name'] . ' ' . $user['last_name'])
		);

		$this->ci->session->set_userdata(self::SESSION_KEY, $session_user);
		return array('ok' => TRUE, 'user' => $session_user);
	}

	public function logout()
	{
		$this->ci->session->unset_userdata(self::SESSION_KEY);
	}

	public function user()
	{
		$user = $this->ci->session->userdata(self::SESSION_KEY);
		return is_array($user) ? $user : NULL;
	}

	public function is_logged_in()
	{
		return $this->user() !== NULL;
	}

	public function require_login()
	{
		if (!$this->is_logged_in())
		{
			redirect('catalog/login');
			exit;
		}
	}

	public function permissions()
	{
		$user = $this->user();
		if (!$user)
		{
			return array();
		}

		$person_id = (int) $user['person_id'];
		$row = $this->db_catalog
			->from('catalog_employee_permissions')
			->where('person_id', $person_id)
			->limit(1)
			->get()
			->row_array();

		if ($row)
		{
			$can_manage_links = isset($row['can_manage_links'])
				? ((int) $row['can_manage_links'] === 1)
				: ((int) $row['can_create_links'] === 1);
			$can_view_dashboard = isset($row['can_view_dashboard'])
				? ((int) $row['can_view_dashboard'] === 1)
				: ((int) $row['can_access_panel'] === 1);
			$can_manage_inventory = isset($row['can_manage_inventory'])
				? ((int) $row['can_manage_inventory'] === 1)
				: ((int) $row['can_access_panel'] === 1);
			$can_manage_catalog = isset($row['can_manage_catalog'])
				? ((int) $row['can_manage_catalog'] === 1)
				: ((int) $row['can_access_panel'] === 1);

			return array(
				'can_access_panel' => (int) $row['can_access_panel'] === 1,
				'can_view_dashboard' => $can_view_dashboard,
				'can_manage_links' => $can_manage_links,
				'can_create_links' => $can_manage_links,
				'can_view_orders' => (int) $row['can_view_orders'] === 1,
				'can_manage_inventory' => $can_manage_inventory,
				'can_manage_catalog' => $can_manage_catalog,
				'can_download_reports' => (int) $row['can_download_reports'] === 1,
				'can_manage_permissions' => (int) $row['can_manage_permissions'] === 1
			);
		}

		return $this->build_default_permissions($person_id);
	}

	public function can($permission_key)
	{
		$permissions = $this->permissions();
		return isset($permissions[$permission_key]) ? (bool) $permissions[$permission_key] : FALSE;
	}

	public function require_permission($permission_key)
	{
		if (!$this->can($permission_key))
		{
			show_error('No tienes permiso para esta accion.', 403);
			exit;
		}
	}

	private function verify_password($plain, $stored)
	{
		$plain = (string) $plain;
		$stored = (string) $stored;

		if ($stored === '')
		{
			return FALSE;
		}

		if (strlen($stored) > 40 && substr($stored, 0, 1) === '$')
		{
			return password_verify($plain, $stored);
		}

		if (preg_match('/^[a-f0-9]{32}$/i', $stored))
		{
			return md5($plain) === strtolower($stored);
		}

		if (preg_match('/^[a-f0-9]{40}$/i', $stored))
		{
			return sha1($plain) === strtolower($stored);
		}

		return hash_equals($stored, $plain);
	}

	private function build_default_permissions($person_id)
	{
		$modules = $this->db_gala
			->select('module_id')
			->from('phppos_permissions')
			->where('person_id', (int) $person_id)
			->get()
			->result_array();

		$module_ids = array();
		foreach ($modules as $mod)
		{
			$module_ids[] = $mod['module_id'];
		}

		$has_sales = in_array('sales', $module_ids, TRUE);
		$has_reports = in_array('reports', $module_ids, TRUE);
		$has_config = in_array('config', $module_ids, TRUE);
		$has_items = in_array('items', $module_ids, TRUE);

		$access = $has_sales || $has_reports || $has_items || $has_config;
		if ($person_id === 1)
		{
			$access = TRUE;
		}

		return array(
			'can_access_panel' => $access,
			'can_view_dashboard' => $access,
			'can_manage_links' => $has_sales || $has_config || $person_id === 1,
			'can_create_links' => $has_sales || $has_config || $person_id === 1,
			'can_view_orders' => $has_sales || $has_reports || $has_config || $person_id === 1,
			'can_manage_inventory' => $has_items || $has_config || $person_id === 1,
			'can_manage_catalog' => $has_config || $person_id === 1,
			'can_download_reports' => $has_reports || $has_sales || $has_config || $person_id === 1,
			'can_manage_permissions' => $has_config || $person_id === 1
		);
	}
}
