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

class Tags_model extends CI_Model
{

    public function __construct()
    {
        parent::__construct();
        $this->load->database();
        $this->table = 'tags';
    }

    /**
     * Obtiene listado de TAGs con información relacionada
     */
    public function get_all_tags($limit_offset_order_and_filters)
    {
        $this->db->select('t.id, t.numero_tag, t.saldo, t.fecha_activacion, t.fecha_vencimiento, t.status,
            tne.fecha_asignacion, tne.fecha_baja,
            ne.numero_economico, 
            ne.modalidad_nombre, ne.codigo');
        $this->db->from($this->table . ' t');
        $this->db->join('tags_numeros_economicos tne', 't.id = tne.tag_id', 'LEFT');
        $this->db->join('numeros_economicos ne', 'tne.numero_economico_id = ne.id', 'LEFT');

        if (isset($limit_offset_order_and_filters['filters'])) {
            foreach ($limit_offset_order_and_filters['filters'] as $key => $value) {
                if ($key === 't.status') {
                    $this->db->where('t.status', $value);
                }
                if ($key === 't.numero_tag') {
                    $this->db->like('t.numero_tag', $value);
                }
            }
        }

        // Aplicar filtro por categoría de saldo
        if (isset($limit_offset_order_and_filters['saldo_categoria'])) {
            if ($limit_offset_order_and_filters['saldo_categoria'] === 'sin_saldo') {
                $this->db->where('t.saldo', 0);
            } else if ($limit_offset_order_and_filters['saldo_categoria'] === 'con_saldo') {
                $this->db->where('t.saldo >', 0);
            }
        }

        // Aplicar filtro por asignación
        if (isset($limit_offset_order_and_filters['asignacion'])) {
            if ($limit_offset_order_and_filters['asignacion'] === 'sin_asignar') {
                $this->db->where('ne.numero_economico IS NULL');
            } else if ($limit_offset_order_and_filters['asignacion'] === 'asignados') {
                $this->db->where('ne.numero_economico IS NOT NULL');
            }
        }

        if (isset($limit_offset_order_and_filters['order'])) {
            foreach ($limit_offset_order_and_filters['order'] as $key => $value) {
                $this->db->order_by($key, $value);
            }
        } else {
            // Ordenamiento por defecto
            $this->db->order_by('t.numero_tag', 'ASC');
        }

        if (
            isset($limit_offset_order_and_filters['limit']) &&
            $limit_offset_order_and_filters['limit'] > 0 &&
            isset($limit_offset_order_and_filters['offset']) &&
            $limit_offset_order_and_filters['offset'] >= 0
        ) {
            $this->db->limit($limit_offset_order_and_filters['limit'], $limit_offset_order_and_filters['offset']);
        }

        $result = $this->db->get();
        return $result->result_array();
    }
    /**
     * Obtiene todos los TAGs sin paginación, solo filtrando por saldo
     */
    public function get_all_tags_by_saldo($saldo_categoria, $status = 1)
    {
        $this->db->select('t.id, t.numero_tag, t.saldo, t.fecha_activacion, t.fecha_vencimiento, t.status,
            tne.fecha_asignacion, tne.fecha_baja,
            ne.numero_economico, 
            ne.modalidad_nombre, ne.codigo');
        $this->db->from($this->table . ' t');
        $this->db->join('tags_numeros_economicos tne', 't.id = tne.tag_id', 'LEFT');
        $this->db->join('numeros_economicos ne', 'tne.numero_economico_id = ne.id', 'LEFT');

        // Filtrar por status
        $this->db->where('t.status', $status);

        // Filtrar por categoría de saldo
        if ($saldo_categoria === 'sin_saldo') {
            $this->db->where('t.saldo', 0);
        } else if ($saldo_categoria === 'con_saldo') {
            $this->db->where('t.saldo >', 0);
        }

        // Ordenar por número de TAG
        $this->db->order_by('t.numero_tag', 'ASC');

        $result = $this->db->get();
        return $result->result_array();
    }

    /**
     * Obtiene todos los TAGs sin paginación, filtrando por estado de asignación
     */
    public function get_all_tags_by_asignacion($asignacion, $status = 1)
    {
        $this->db->select('t.id, t.numero_tag, t.saldo, t.fecha_activacion, t.fecha_vencimiento, t.status,
            tne.fecha_asignacion, tne.fecha_baja,
            ne.numero_economico, 
            ne.modalidad_nombre, ne.codigo');
        $this->db->from($this->table . ' t');
        $this->db->join('tags_numeros_economicos tne', 't.id = tne.tag_id', 'LEFT');
        $this->db->join('numeros_economicos ne', 'tne.numero_economico_id = ne.id', 'LEFT');

        // Filtrar por status
        $this->db->where('t.status', $status);

        // Filtrar por asignación
        if ($asignacion === 'sin_asignar') {
            $this->db->where('ne.numero_economico IS NULL');
        } else if ($asignacion === 'asignados') {
            $this->db->where('ne.numero_economico IS NOT NULL');
        }

        // Ordenar por número de TAG
        $this->db->order_by('t.numero_tag', 'ASC');

        $result = $this->db->get();
        return $result->result_array();
    }

    /**
     * Cuenta total de registros para paginación
     */
    public function count_all_tags($limit_offset_order_and_filters)
    {
        $this->db->select('COUNT(*) as numrows');
        $this->db->from($this->table . ' t');
        $this->db->join('tags_numeros_economicos tne', 't.id = tne.tag_id', 'LEFT');
        $this->db->join('numeros_economicos ne', 'tne.numero_economico_id = ne.id', 'LEFT');

        if (isset($limit_offset_order_and_filters['filters'])) {
            foreach ($limit_offset_order_and_filters['filters'] as $key => $value) {
                if ($key === 't.status') {
                    $this->db->where('t.status', $value);
                }
                if ($key === 't.numero_tag') {
                    $this->db->like('t.numero_tag', $value);
                }
            }
        }

        // Aplicar filtro por categoría de saldo
        if (isset($limit_offset_order_and_filters['saldo_categoria'])) {
            if ($limit_offset_order_and_filters['saldo_categoria'] === 'sin_saldo') {
                $this->db->where('t.saldo', 0);
            } else if ($limit_offset_order_and_filters['saldo_categoria'] === 'con_saldo') {
                $this->db->where('t.saldo >', 0);
            }
        }

        // Aplicar filtro por asignación
        if (isset($limit_offset_order_and_filters['asignacion'])) {
            if ($limit_offset_order_and_filters['asignacion'] === 'sin_asignar') {
                $this->db->where('ne.numero_economico IS NULL');
            } else if ($limit_offset_order_and_filters['asignacion'] === 'asignados') {
                $this->db->where('ne.numero_economico IS NOT NULL');
            }
        }

        $result = $this->db->get();
        $row = $result->row_array();
        return $row['numrows'];
    }
    /**
     * Obtiene información detallada de un TAG
     */
    public function get_tag_by_id($id)
    {
        $this->db->select('t.id, t.numero_tag, t.saldo, t.fecha_activacion, t.fecha_vencimiento, t.status,
            tne.fecha_asignacion, tne.fecha_baja, tne.comentario_asignacion, tne.comentario_baja,
            ne.numero_economico,
            ne.modalidad_nombre, ne.codigo');
        $this->db->from($this->table . ' t');
        $this->db->join('tags_numeros_economicos tne', 't.id = tne.tag_id', 'LEFT');
        $this->db->join('numeros_economicos ne', 'tne.numero_economico_id = ne.id', 'LEFT');
        $this->db->where('t.id', $id);

        $result = $this->db->get();

        if ($result->num_rows() > 0) {
            return $result->row_array();
        }
        return NULL;
    }

    /**
     * Verifica si un número económico ya tiene un TAG activo
     */
    public function check_numero_economico_has_active_tag($numero_economico_id)
    {
        $this->db->select('t.id');
        $this->db->from('tags_numeros_economicos tne');
        $this->db->join($this->table . ' t', 't.id = tne.tag_id', 'INNER');
        $this->db->where('tne.numero_economico_id', $numero_economico_id);
        $this->db->where('tne.fecha_baja IS NULL');
        $this->db->where('tne.status', 1);
        $this->db->where('t.status', 1);
        $result = $this->db->get();
        return $result->row_array();
    }

    /**
     * Inserta un nuevo TAG
     */
    public function insert($data)
    {
        if ($this->db->insert($this->table, $data)) {
            $id = $this->db->insert_id();
            if (create_log($this->table, $id, $data)) {
                return $id;
            }
        }
        return FALSE;
    }

    /**
     * Actualiza un TAG existente
     */
    public function update($id, $data)
    {
        if ($this->db->update($this->table, $data, array('id' => $id))) {
            if (create_log($this->table, $id, $data)) {
                return TRUE;
            }
        }
        return FALSE;
    }

    /**
     * Asigna un TAG a un número económico
     */
    public function assign_to_numero_economico($tag_id, $numero_economico_id, $data)
    {
        $data['tag_id'] = $tag_id;
        $data['numero_economico_id'] = $numero_economico_id;
        $data['status'] = 1;
        $data['created_at'] = date('Y-m-d H:i:s');

        if ($this->db->insert('tags_numeros_economicos', $data)) {
            $id = $this->db->insert_id();
            if (create_log('tags_numeros_economicos', $id, $data)) {
                return $id;
            }
        }
        return FALSE;
    }

    /**
     * Recarga TAG (versión modificada para integrar con el módulo de Caja)
     */
    public function recharge_tag($tag_id, $data)
    {
        $this->db->trans_begin();

        // Obtener el saldo actual
        $this->db->select('saldo');
        $this->db->from($this->table);
        $this->db->where('id', $tag_id);
        $current_balance = $this->db->get()->row()->saldo;

        // Calcular nuevo saldo
        $new_balance = $current_balance + $data['monto'];

        // Actualizar el saldo del TAG
        $update_data = array(
            'saldo' => $new_balance,
            'updated_at' => date('Y-m-d H:i:s')
        );

        $this->db->where('id', $tag_id);
        $this->db->update($this->table, $update_data);

        // Registrar el movimiento de recarga
        $recharge_data = array(
            'tag_id' => $tag_id,
            'tipo_movimiento' => 'RECARGA',
            'monto' => $data['monto'],
            'saldo_anterior' => $current_balance,
            'saldo_nuevo' => $new_balance,
            'referencia' => 'RC-' . date('YmdHis'),
            'comentario' => $data['comentario'],
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s')
        );

        $this->db->insert('tags_movimientos', $recharge_data);
        $movimiento_id = $this->db->insert_id();

        // Registrar en la caja (si hay una caja abierta)
        $this->load->model('caja_model');
        $caja_actual = $this->caja_model->get_caja_actual();

        if ($caja_actual) {
            $saldo_anterior = $caja_actual['saldo'];
            $saldo_nuevo = $saldo_anterior + $data['monto'];

            $caja_movimiento = array(
                'caja_id' => $caja_actual['id'],
                'tipo_movimiento' => 'RECARGA',
                'monto' => $data['monto'],
                'saldo_anterior' => $saldo_anterior,
                'saldo_nuevo' => $saldo_nuevo,
                'referencia' => $recharge_data['referencia'],
                'detalle_id' => $movimiento_id,
                'tag_id' => $tag_id,
                'usuario_id' => get_current_user_id(),
                'fecha_movimiento' => date('Y-m-d H:i:s'),
                'created_at' => date('Y-m-d H:i:s')
            );

            $this->caja_model->registrar_movimiento($caja_movimiento);
        }

        if ($this->db->trans_status() === FALSE) {
            $this->db->trans_rollback();
            return FALSE;
        } else {
            $this->db->trans_commit();
            return TRUE;
        }
    }

    /**
     * Da de baja la asignación de un TAG
     */
    public function unassign_tag($tag_id, $data_unassign, $data_tag)
    {
        $this->db->trans_begin();

        // Actualizar tags_numeros_economicos
        $this->db->where('tag_id', $tag_id);
        $this->db->where('fecha_baja IS NULL');
        $this->db->where('status', 1);
        $this->db->update('tags_numeros_economicos', $data_unassign);

        // Actualizar tags
        $this->db->where('id', $tag_id);
        $this->db->update($this->table, $data_tag);

        if ($this->db->trans_status() === FALSE) {
            $this->db->trans_rollback();
            return FALSE;
        } else {
            $this->db->trans_commit();
            return TRUE;
        }
    }
    /**
     * Verifica si un número de TAG ya existe
     */
    public function tag_exists($numero_tag)
    {
        $this->db->select('id');
        $this->db->from($this->table);
        $this->db->where('numero_tag', $numero_tag);
        $result = $this->db->get();
        return $result->num_rows() > 0;
    }
}
