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

class Configuracion extends CI_Controller
{
	public function __construct()
	{
		parent::__construct();

		if ($this->session->userdata('logged_in') !== TRUE) {
			redirect('login');
		}

		$this->load->model('Usuario_model');
		$this->load->model('Tema_model');
		$this->load->model('App_config_model');
		$this->load->model('Parametro_trabajo_model');
	}

	public function index()
	{
		$this->empleados();
	}

	public function empleados()
	{
		$data = $this->datos_base('empleados');
		$data['empleados'] = $this->Usuario_model->obtener_todos();
		$this->load->view('configuracion/index', $data);
	}

	public function general()
	{
		$data = $this->datos_base('general');
		$data['empleados'] = array();
		$this->load->view('configuracion/index', $data);
	}

	public function temas()
	{
		$data = $this->datos_base('temas');
		$data['empleados'] = array();
		$this->load->view('configuracion/index', $data);
	}

	public function parametros_trabajo()
	{
		$data = $this->datos_base('parametros');
		$data['empleados'] = array();
		$this->load->view('configuracion/index', $data);
	}

	public function guardar_general()
	{
		$this->form_validation->set_rules('app_name', 'Nombre de la app', 'trim|required|max_length[100]');

		if ($this->form_validation->run() !== TRUE) {
			$this->session->set_flashdata('error', validation_errors('<div>', '</div>'));
			redirect('configuracion/general');
		}

		$app_name = trim((string) $this->input->post('app_name', TRUE));
		$actual = $this->App_config_model->obtener();
		$logo_path = NULL;

		if (!empty($_FILES['logo']['name'])) {
			$upload_dir = FCPATH.'uploads/branding/';
			if (!is_dir($upload_dir)) {
				@mkdir($upload_dir, 0755, TRUE);
			}

			$config = array(
				'upload_path' => $upload_dir,
				'allowed_types' => 'jpg|jpeg|png|gif|webp',
				'max_size' => 2048,
				'encrypt_name' => TRUE
			);

			$this->load->library('upload', $config);
			if (!$this->upload->do_upload('logo')) {
				$this->session->set_flashdata('error', $this->upload->display_errors('<div>', '</div>'));
				redirect('configuracion/general');
			}

			$uploaded = $this->upload->data();
			$logo_path = 'uploads/branding/'.$uploaded['file_name'];

			if (!empty($actual['logo_path'])) {
				$old_abs = FCPATH.ltrim($actual['logo_path'], '/\\');
				$old_abs_norm = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $old_abs);
				$branding_root = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, FCPATH.'uploads'.DIRECTORY_SEPARATOR.'branding');
				if (is_file($old_abs_norm) && strpos($old_abs_norm, $branding_root) === 0) {
					@unlink($old_abs);
				}
			}
		}

		$this->App_config_model->guardar($app_name, $logo_path);
		$this->session->set_flashdata('ok', 'Configuracion general actualizada.');
		redirect('configuracion/general');
	}

	public function guardar_parametros_trabajo()
	{
		$this->form_validation->set_rules('monto_mano_obra', 'Monto mano de obra', 'trim|required|numeric|greater_than_equal_to[0]');

		if ($this->form_validation->run() !== TRUE) {
			$this->session->set_flashdata('error', validation_errors('<div>', '</div>'));
			redirect('configuracion/parametros-trabajo');
		}

		$mano_obra = 'Mano de obra';
		$monto = (float) $this->input->post('monto_mano_obra', TRUE);
		$this->Parametro_trabajo_model->guardar($mano_obra, $monto);

		$this->session->set_flashdata('ok', 'Parametros de trabajo guardados.');
		redirect('configuracion/parametros-trabajo');
	}

	public function guardar_empleado()
	{
		$this->form_validation->set_rules('nombre', 'Nombre', 'trim|required|max_length[100]');
		$this->form_validation->set_rules('username', 'Usuario', 'trim|required|max_length[50]|is_unique[usuarios.username]');
		$this->form_validation->set_rules('password', 'Contrasena', 'trim|required|min_length[6]|max_length[72]');

		if ($this->form_validation->run() === TRUE) {
			$this->Usuario_model->crear_usuario(
				$this->input->post('nombre', TRUE),
				$this->input->post('username', TRUE),
				$this->input->post('password', TRUE)
			);
			$this->session->set_flashdata('ok', 'Usuario de empleado creado correctamente.');
		} else {
			$this->session->set_flashdata('error', validation_errors('<div>', '</div>'));
		}

		redirect('configuracion/empleados');
	}

	public function editar_empleado()
	{
		$id = (int) $this->input->post('empleado_id', TRUE);
		$actual = $this->Usuario_model->obtener_por_id($id);
		if (!$actual) {
			$this->session->set_flashdata('error', 'El usuario no existe.');
			redirect('configuracion/empleados');
		}

		if (!$this->puede_gestionar_usuario($actual)) {
			$this->session->set_flashdata('error', 'No tienes permiso para editar este usuario.');
			redirect('configuracion/empleados');
		}

		$this->form_validation->set_rules('nombre', 'Nombre', 'trim|required|max_length[100]');
		$this->form_validation->set_rules('username', 'Usuario', 'trim|required|max_length[50]');
		$this->form_validation->set_rules('password', 'Contrasena', 'trim|min_length[6]|max_length[72]');

		if ($this->form_validation->run() !== TRUE) {
			$this->session->set_flashdata('error', validation_errors('<div>', '</div>'));
			redirect('configuracion/empleados');
		}

		$username = (string) $this->input->post('username', TRUE);
		if ($this->Usuario_model->existe_username_otro($username, $id)) {
			$this->session->set_flashdata('error', 'El usuario ya existe.');
			redirect('configuracion/empleados');
		}

		$data = array(
			'nombre' => (string) $this->input->post('nombre', TRUE),
			'username' => $username
		);

		$password = trim((string) $this->input->post('password', TRUE));
		if ($password !== '') {
			$data['password'] = password_hash($password, PASSWORD_BCRYPT);
		}

		$ok = $this->Usuario_model->actualizar_usuario($id, $data);
		if ($ok) {
			$this->session->set_flashdata('ok', 'Usuario actualizado correctamente.');
		} else {
			$this->session->set_flashdata('error', 'No se pudo actualizar el usuario.');
		}

		redirect('configuracion/empleados');
	}

	public function eliminar_empleado()
	{
		$id = (int) $this->input->post('empleado_id', TRUE);
		$actual = $this->Usuario_model->obtener_por_id($id);
		if (!$actual) {
			$this->session->set_flashdata('error', 'El usuario no existe.');
			redirect('configuracion/empleados');
		}

		$user_id_actual = (int) $this->session->userdata('user_id');
		if ($user_id_actual > 0 && $user_id_actual === (int) $actual->id) {
			$this->session->set_flashdata('error', 'No puedes eliminar tu propio usuario.');
			redirect('configuracion/empleados');
		}

		if (!$this->puede_gestionar_usuario($actual)) {
			$this->session->set_flashdata('error', 'No tienes permiso para eliminar este usuario.');
			redirect('configuracion/empleados');
		}

		$ok = $this->Usuario_model->eliminar_usuario($id);
		if ($ok) {
			$this->session->set_flashdata('ok', 'Usuario eliminado correctamente.');
		} else {
			$this->session->set_flashdata('error', 'No se pudo eliminar el usuario.');
		}

		redirect('configuracion/empleados');
	}

	public function guardar_tema()
	{
		$tema = $this->input->post('tema', TRUE);
		$permitidos = array('claro', 'oscuro', 'rosado', 'fuccia', 'verde', 'rojo', 'azul_claro', 'azul_rey');

		if (strpos((string) $tema, 'custom_') === 0) {
			$id = (int) str_replace('custom_', '', (string) $tema);
			$custom = $this->Tema_model->obtener_por_id($id);
			if ($custom) {
				$this->session->set_userdata('theme', 'custom_'.$custom->id);
				$this->session->set_userdata('theme_custom_vars', $this->normalizar_tema_fila($custom));
				$this->session->set_flashdata('ok', 'Tema personalizado activado.');
				redirect('configuracion/temas');
			}
		}

		if (!in_array($tema, $permitidos, TRUE)) {
			$tema = 'claro';
		}

		$this->session->set_userdata('theme', $tema);
		$this->session->unset_userdata('theme_custom_vars');
		$this->session->set_flashdata('ok', 'Tema actualizado a '.ucfirst(str_replace('_', ' ', $tema)).'.');
		redirect('configuracion/temas');
	}

	public function agregar_tema()
	{
		$data = $this->leer_campos_tema_desde_post();
		if (!$data) {
			$this->session->set_flashdata('error', 'Datos de tema invalidos.');
			redirect('configuracion/temas');
		}

		$this->Tema_model->crear($data);
		$this->session->set_flashdata('ok', 'Tema personalizado creado.');
		redirect('configuracion/temas');
	}

	public function editar_tema()
	{
		$id = (int) $this->input->post('tema_id', TRUE);
		$actual = $this->Tema_model->obtener_por_id($id);
		if (!$actual) {
			$this->session->set_flashdata('error', 'El tema no existe.');
			redirect('configuracion/temas');
		}

		$data = $this->leer_campos_tema_desde_post();
		if (!$data) {
			$this->session->set_flashdata('error', 'Datos de tema invalidos.');
			redirect('configuracion/temas');
		}

		$this->Tema_model->actualizar($id, $data);

		$theme_session = (string) $this->session->userdata('theme');
		if ($theme_session === 'custom_'.$id) {
			$actualizado = $this->Tema_model->obtener_por_id($id);
			if ($actualizado) {
				$this->session->set_userdata('theme_custom_vars', $this->normalizar_tema_fila($actualizado));
			}
		}

		$this->session->set_flashdata('ok', 'Tema personalizado actualizado.');
		redirect('configuracion/temas');
	}

	public function eliminar_tema()
	{
		$id = (int) $this->input->post('tema_id', TRUE);
		$actual = $this->Tema_model->obtener_por_id($id);
		if (!$actual) {
			$this->session->set_flashdata('error', 'El tema no existe.');
			redirect('configuracion/temas');
		}

		$this->Tema_model->eliminar($id);

		$theme_session = (string) $this->session->userdata('theme');
		if ($theme_session === 'custom_'.$id) {
			$this->session->set_userdata('theme', 'claro');
			$this->session->unset_userdata('theme_custom_vars');
		}

		$this->session->set_flashdata('ok', 'Tema personalizado eliminado.');
		redirect('configuracion/temas');
	}

	private function datos_base($tab)
	{
		$theme = $this->session->userdata('theme');
		$base = array('claro', 'oscuro', 'rosado', 'fuccia', 'verde', 'rojo', 'azul_claro', 'azul_rey');

		if (strpos((string) $theme, 'custom_') === 0) {
			$id = (int) str_replace('custom_', '', (string) $theme);
			$custom = $this->Tema_model->obtener_por_id($id);
			if ($custom) {
				$this->session->set_userdata('theme_custom_vars', $this->normalizar_tema_fila($custom));
			} else {
				$theme = 'claro';
				$this->session->set_userdata('theme', 'claro');
				$this->session->unset_userdata('theme_custom_vars');
			}
		} elseif (!in_array($theme, $base, TRUE)) {
			$theme = 'claro';
			$this->session->set_userdata('theme', 'claro');
			$this->session->unset_userdata('theme_custom_vars');
		}

		return array(
			'tab' => $tab,
			'theme' => $theme,
			'temas_custom' => $this->Tema_model->obtener_todos(),
			'app_config' => $this->App_config_model->obtener(),
			'parametros_trabajo' => $this->Parametro_trabajo_model->obtener()
		);
	}

	private function leer_campos_tema_desde_post()
	{
		$nombre = trim((string) $this->input->post('nombre', TRUE));
		if ($nombre === '') {
			return FALSE;
		}

		$fields = array(
			'bg' => $this->input->post('bg', TRUE),
			'card' => $this->input->post('card', TRUE),
			'text' => $this->input->post('text', TRUE),
			'muted' => $this->input->post('muted', TRUE),
			'linea' => $this->input->post('linea', TRUE),
			'primary_color' => $this->input->post('primary_color', TRUE),
			'ok_bg' => $this->input->post('ok_bg', TRUE),
			'ok_text' => $this->input->post('ok_text', TRUE)
		);

		foreach ($fields as $k => $v) {
			if (!preg_match('/^#[0-9a-fA-F]{6}$/', (string) $v)) {
				return FALSE;
			}
			$fields[$k] = strtolower((string) $v);
		}

		return array_merge(array('nombre' => $nombre), $fields);
	}

	private function normalizar_tema_fila($t)
	{
		return array(
			'bg' => $t->bg,
			'card' => $t->card,
			'text' => $t->text,
			'muted' => $t->muted,
			'line' => $t->linea,
			'primary' => $t->primary_color,
			'ok_bg' => $t->ok_bg,
			'ok_text' => $t->ok_text
		);
	}

	private function es_admin_actual()
	{
		return strtolower((string) $this->session->userdata('username')) === 'admin';
	}

	private function es_usuario_admin($usuario)
	{
		if (!$usuario) {
			return FALSE;
		}
		$by_username = isset($usuario->username) && strtolower((string) $usuario->username) === 'admin';
		$by_id = isset($usuario->id) && (int) $usuario->id === 1;
		return $by_username || $by_id;
	}

	private function puede_gestionar_usuario($usuario_obj)
	{
		if ($this->es_admin_actual()) {
			return TRUE;
		}
		return !$this->es_usuario_admin($usuario_obj);
	}
}
