<?php
/**
 * ASISMA CRM - Modelo Base del MVC
 */
abstract class Model {
    protected $table;
    protected $db;
    protected $primaryKey = 'id';

    public function __construct() {
        $this->db = Database::getInstance();
    }

    /**
     * Obtiene un registro por su ID
     */
    public function getById($id) {
        $sql = "SELECT * FROM `{$this->table}` WHERE `{$this->primaryKey}` = :id LIMIT 1";
        return $this->db->fetchOne($sql, ['id' => $id]);
    }

    /**
     * Obtiene todos los registros con condiciones personalizadas
     */
    public function getAll($where = "1", $params = [], $orderBy = "") {
        $orderSql = !empty($orderBy) ? " ORDER BY {$orderBy} " : "";
        $sql = "SELECT * FROM `{$this->table}` WHERE {$where} {$orderSql}";
        return $this->db->fetchAll($sql, $params);
    }

    /**
     * Cuenta registros bajo ciertas condiciones
     */
    public function count($where = "1", $params = []) {
        return $this->db->count($this->table, $where, $params);
    }

    /**
     * Crea un nuevo registro
     */
    public function create($data) {
        return $this->db->insert($this->table, $data);
    }

    /**
     * Actualiza un registro existente por su ID
     */
    public function update($id, $data) {
        $whereClause = "`{$this->primaryKey}` = :id";
        $whereParams = ['id' => $id];
        return $this->db->update($this->table, $data, $whereClause, $whereParams);
    }

    /**
     * Elimina lógicamente un registro (Soft Delete) si la tabla posee columna 'activo'
     * De lo contrario, ejecuta eliminación física.
     */
    public function delete($id) {
        // Verificar si la tabla tiene columna 'activo' buscando en una consulta de prueba o estructura
        // Por diseño de ASISMA CRM, usaremos eliminación lógica si la columna existe en el modelo.
        // Implementamos verificación simple:
        $schemaCheck = $this->db->fetchOne("SHOW COLUMNS FROM `{$this->table}` LIKE 'activo'");
        
        if ($schemaCheck) {
            return $this->update($id, ['activo' => 0]);
        }
        
        return $this->hardDelete($id);
    }

    /**
     * Elimina físicamente un registro por ID
     */
    public function hardDelete($id) {
        $whereClause = "`{$this->primaryKey}` = :id";
        return $this->db->delete($this->table, $whereClause, ['id' => $id]);
    }

    /**
     * Agrega filtro multi-tenant a una consulta SQL base
     */
    protected function applyTenantFilter($whereClause = "1", $tableAlias = "") {
        if (SessionHelper::isAdmin()) {
            return $whereClause;
        }

        $franquiciadoId = SessionHelper::getFranquiciadoId();
        if (!$franquiciadoId) {
            return "0=1"; // No tiene franquicia asignada, no ve registros
        }

        $prefix = !empty($tableAlias) ? "`{$tableAlias}`." : "";
        $tenantCond = "{$prefix}`franquiciado_id` = " . intval($franquiciadoId);

        if ($whereClause === "1" || empty($whereClause)) {
            return $tenantCond;
        }

        return "({$whereClause}) AND {$tenantCond}";
    }
}
