<?php
/**
 * ASISMA CRM - Franquiciados Controller
 */
class FranquiciadosController extends Controller {

    public function index() {
        $db = Database::getInstance();

        $sql = "SELECT f.*, ef.nombre_fantasia, ef.razon_social, ef.rut, ef.email, ef.telefono,
                       ef.control_empresas_id,
                       r.nombre as region_nombre, v.nombre as vertical_nombre
                FROM franquiciados f
                INNER JOIN empresas_franquiciados ef ON f.empresa_madre_id = ef.id
                INNER JOIN regiones r ON f.region_id = r.id
                INNER JOIN verticales v ON f.vertical_id = v.id
                ORDER BY ef.nombre_fantasia ASC";

        $franquiciados = $db->fetchAll($sql);

        // Resumen de autorización de venta: marcas completas + productos sueltos
        foreach ($franquiciados as $k => $f) {
            $marcasF = $db->fetchAll(
                "SELECT m.nombre FROM franquiciado_marcas fm
                 INNER JOIN marcas m ON fm.marca_id = m.id
                 WHERE fm.franquiciado_id = :fid ORDER BY m.nombre ASC",
                ['fid' => $f['id']]
            );
            $nombres = array();
            foreach ($marcasF as $mf) $nombres[] = $mf['nombre'];
            $franquiciados[$k]['marcas_asignadas'] = $nombres;

            $productosF = $db->fetchAll(
                "SELECT p.nombre FROM franquiciado_productos fp
                 INNER JOIN productos p ON fp.producto_id = p.id
                 WHERE fp.franquiciado_id = :fid ORDER BY p.nombre ASC",
                ['fid' => $f['id']]
            );
            $nombresP = array();
            foreach ($productosF as $pf) $nombresP[] = $pf['nombre'];
            $franquiciados[$k]['productos_asignados'] = $nombresP;
        }

        $regiones = $db->fetchAll("SELECT * FROM regiones WHERE activa = 1 ORDER BY nombre ASC");
        $verticales = $db->fetchAll("SELECT * FROM verticales WHERE activa = 1 ORDER BY nombre ASC");
        $marcasTodas = $db->fetchAll("SELECT id, vertical_id, nombre FROM marcas WHERE activa = 1 ORDER BY nombre ASC");

        // Comunas con los IDs reales de Control Empresas; si el catalogo esta
        // vacio se intenta sincronizar al vuelo (necesita CE configurado)
        $comunas = $db->fetchAll("SELECT id, nombre, ciudad FROM comunas_ce ORDER BY nombre ASC");
        if (empty($comunas)) {
            IntegracionesHelper::sincronizarComunasControlEmpresas();
            $comunas = $db->fetchAll("SELECT id, nombre, ciudad FROM comunas_ce ORDER BY nombre ASC");
        }

        $this->render('franquiciados/index', [
            'title' => 'Gestión de Franquiciados',
            'franquiciados' => $franquiciados,
            'regiones' => $regiones,
            'verticales' => $verticales,
            'marcasTodas' => $marcasTodas,
            'comunas' => $comunas
        ]);
    }

    /**
     * GET: autorización de venta del franquiciado para el modal — marcas de su
     * vertical con sus productos, marcando qué marcas están COMPLETAS y qué
     * productos están autorizados SUELTOS.
     */
    public function marcasData() {
        $id = (int)$this->input('id');
        if ($id <= 0) $this->json(['success' => false, 'message' => 'ID inválido.']);

        $db = Database::getInstance();
        $franq = $db->fetchOne("SELECT id, vertical_id FROM franquiciados WHERE id = :id", ['id' => $id]);
        if (!$franq) $this->json(['success' => false, 'message' => 'Franquiciado no encontrado.']);

        $marcasCompletas  = AlcanceHelper::marcasIds($id);
        $productosSueltos = AlcanceHelper::productosSueltosIds($id);

        $disponibles = $db->fetchAll(
            "SELECT id, nombre FROM marcas WHERE vertical_id = :vid AND activa = 1 ORDER BY nombre ASC",
            ['vid' => $franq['vertical_id']]
        );
        foreach ($disponibles as $k => $marca) {
            $disponibles[$k]['productos'] = $db->fetchAll(
                "SELECT id, nombre FROM productos WHERE marca_id = :mid AND activo = 1 ORDER BY nombre ASC",
                ['mid' => $marca['id']]
            );
        }

        $this->json(['success' => true, 'data' => [
            'asignadas'         => $marcasCompletas,
            'productos_sueltos' => $productosSueltos,
            'disponibles'       => $disponibles
        ]]);
    }

    /**
     * POST: guarda la autorización de venta del franquiciado (solo matriz).
     * Recibe marcas[] (marcas COMPLETAS, incluyen productos futuros) y
     * productos[] (productos SUELTOS de marcas no completas).
     */
    public function marcasGuardar() {
        if (!SessionHelper::isAdmin()) {
            $this->json(['success' => false, 'message' => 'Solo la matriz puede asignar la autorización de venta.'], 403);
        }

        $id = (int)$this->input('id');
        $marcas    = isset($_POST['marcas']) && is_array($_POST['marcas']) ? array_map('intval', $_POST['marcas']) : array();
        $productos = isset($_POST['productos']) && is_array($_POST['productos']) ? array_map('intval', $_POST['productos']) : array();

        if ($id <= 0) $this->json(['success' => false, 'message' => 'ID inválido.']);

        $db = Database::getInstance();
        $franq = $db->fetchOne("SELECT id, vertical_id FROM franquiciados WHERE id = :id", ['id' => $id]);
        if (!$franq) $this->json(['success' => false, 'message' => 'Franquiciado no encontrado.']);

        // Solo marcas de SU vertical
        $marcasValidas = array();
        foreach ($marcas as $mid) {
            if ($mid <= 0) continue;
            $m = $db->fetchOne("SELECT id FROM marcas WHERE id = :id AND vertical_id = :vid AND activa = 1",
                               ['id' => $mid, 'vid' => $franq['vertical_id']]);
            if ($m) $marcasValidas[] = $mid;
        }

        // Solo productos de marcas de SU vertical y que NO estén ya completas
        $productosValidos = array();
        foreach ($productos as $pid) {
            if ($pid <= 0) continue;
            $p = $db->fetchOne(
                "SELECT p.id, p.marca_id FROM productos p
                 INNER JOIN marcas m ON m.id = p.marca_id
                 WHERE p.id = :id AND m.vertical_id = :vid AND p.activo = 1",
                ['id' => $pid, 'vid' => $franq['vertical_id']]);
            if ($p && !in_array((int)$p['marca_id'], $marcasValidas)) $productosValidos[] = $pid;
        }

        $db->beginTransaction();
        try {
            $db->delete('franquiciado_marcas', "franquiciado_id = :fid", ['fid' => $id]);
            $db->delete('franquiciado_productos', "franquiciado_id = :fid", ['fid' => $id]);
            foreach ($marcasValidas as $mid) {
                $db->insert('franquiciado_marcas', ['franquiciado_id' => $id, 'marca_id' => $mid]);
            }
            foreach ($productosValidos as $pid) {
                $db->insert('franquiciado_productos', ['franquiciado_id' => $id, 'producto_id' => $pid]);
            }
            AuditHelper::log('asignar_venta_franquiciado', 'franquiciado_marcas', $id, null,
                ['marcas_completas' => $marcasValidas, 'productos_sueltos' => $productosValidos]);
            $db->commit();
            $this->json(['success' => true, 'message' =>
                count($marcasValidas) . ' marca(s) completa(s) y ' . count($productosValidos) . ' producto(s) suelto(s) autorizados.']);
        } catch (Exception $e) {
            $db->rollBack();
            error_log('Error asignando autorización de venta: ' . $e->getMessage());
            $this->json(['success' => false, 'message' => 'Error al guardar la autorización.']);
        }
    }

    /**
     * Crear franquiciado + empresa madre (AJAX POST)
     */
    public function crear() {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->json(['success' => false, 'message' => 'Método no soportado.'], 405);
        }

        $razonSocial  = $this->input('razon_social', '');
        $nombreFant   = $this->input('nombre_fantasia', '');
        $rut          = normalizar_rut($this->input('rut', ''));
        $email        = $this->input('email', '');
        $telefono     = $this->input('telefono', '');
        $direccion    = $this->input('direccion', '');
        $giro         = $this->input('giro', '');
        $comunaId     = (int)$this->input('comuna_id');
        $nombreContacto = $this->input('nombre_contacto', '');
        $regionId     = (int)$this->input('region_id');
        $verticalId   = (int)$this->input('vertical_id');
        $tiempoToma   = (int)$this->input('tiempo_toma_lead', 300);
        $prioridad    = (int)$this->input('prioridad', 0);
        $maxLeads     = (int)$this->input('max_leads_activos', 0);
        $estado       = $this->input('estado', 'activo');

        if (empty($razonSocial) || empty($rut) || $regionId <= 0 || $verticalId <= 0) {
            $this->json(['success' => false, 'message' => 'Razón social, RUT, región y vertical son obligatorios.']);
        }
        $this->validarDatosFacturacion($email, $telefono, $direccion, $giro, $comunaId);

        $db = Database::getInstance();

        // Verificar RUT duplicado
        $existe = $db->fetchOne("SELECT id FROM empresas_franquiciados WHERE rut = :rut", ['rut' => $rut]);
        if ($existe) {
            $this->json(['success' => false, 'message' => 'Ya existe un franquiciado registrado con ese RUT.']);
        }

        $db->beginTransaction();
        try {
            $empresaId = $db->insert('empresas_franquiciados', [
                'razon_social'   => $razonSocial,
                'nombre_fantasia' => $nombreFant ?: $razonSocial,
                'rut'            => $rut,
                'email'          => $email,
                'telefono'       => $telefono,
                'direccion'      => $direccion,
                'giro'           => $giro,
                'comuna_id'      => $comunaId,
                'nombre_contacto' => $nombreContacto,
                'api_key_leads'  => 'asisma_lead_' . bin2hex(openssl_random_pseudo_bytes(20)),
                'activa'         => 1
            ]);

            $franqId = $db->insert('franquiciados', [
                'empresa_madre_id'  => $empresaId,
                'region_id'         => $regionId,
                'vertical_id'       => $verticalId,
                'estado'            => $estado,
                'tiempo_toma_lead'  => $tiempoToma,
                'prioridad'         => $prioridad,
                'max_leads_activos' => $maxLeads
            ]);

            AuditHelper::log('create_franquiciado', 'franquiciados', $franqId, null, ['empresa_id' => $empresaId]);

            $db->commit();

        } catch (Exception $e) {
            $db->rollBack();
            error_log("Error al crear franquiciado: " . $e->getMessage());
            $this->json(['success' => false, 'message' => 'Error de base de datos al registrar franquiciado.']);
        }

        // Provisión en Control Empresas SIEMPRE fuera de la transacción (es HTTP)
        $resultadoCE = $this->provisionarEnControlEmpresas($empresaId, $franqId);

        $this->json([
            'success'    => true,
            'message'    => 'Franquiciado creado exitosamente.',
            'detalle_ce' => $resultadoCE['detalle'],
            'ce_ok'      => $resultadoCE['success']
        ]);
    }

    /**
     * Valida que esten TODOS los datos necesarios para facturar en Control
     * Empresas. La comuna se valida contra el catalogo espejo comunas_ce
     * (IDs reales de CE) — jamas contra una lista escrita a mano.
     */
    private function validarDatosFacturacion($email, $telefono, $direccion, $giro, $comunaId) {
        $faltan = array();
        if (empty($email))     $faltan[] = 'email';
        if (empty($telefono))  $faltan[] = 'teléfono';
        if (empty($direccion)) $faltan[] = 'dirección';
        if (empty($giro))      $faltan[] = 'giro';
        if ($comunaId <= 0)    $faltan[] = 'comuna';
        if (!empty($faltan)) {
            $this->json(['success' => false, 'message' =>
                'Para poder facturar en Control Empresas faltan estos datos: ' . implode(', ', $faltan) . '.']);
        }

        $db = Database::getInstance();
        $comuna = $db->fetchOne("SELECT id FROM comunas_ce WHERE id = :id", [':id' => $comunaId]);
        if (!$comuna) {
            $this->json(['success' => false, 'message' =>
                'La comuna seleccionada no existe en el catálogo de Control Empresas. Sincroniza las comunas e intenta de nuevo.']);
        }
    }

    /**
     * POST (solo matriz): actualiza el catalogo de comunas desde Control Empresas.
     */
    public function sincronizarComunas() {
        if (!SessionHelper::isAdmin()) {
            $this->json(['success' => false, 'message' => 'Solo la matriz puede sincronizar las comunas.'], 403);
        }
        $resultado = IntegracionesHelper::sincronizarComunasControlEmpresas();
        AuditHelper::log('sincronizar_comunas_ce', 'comunas_ce', null, null, $resultado);
        $this->json(['success' => $resultado['success'], 'message' => $resultado['detalle']]);
    }

    /**
     * Crea la empresa del franquiciado en Control Empresas y guarda el ID
     * resultante en empresas_franquiciados. Devuelve el resultado del helper.
     */
    private function provisionarEnControlEmpresas($empresaId, $franqId) {
        $db = Database::getInstance();
        $empresa = $db->fetchOne("SELECT * FROM empresas_franquiciados WHERE id = :id", ['id' => $empresaId]);

        $resultado = IntegracionesHelper::provisionarFranquiciadoControlEmpresas($empresa);

        if ($resultado['success'] && !empty($resultado['nuevo_id'])) {
            $db->update('empresas_franquiciados', [
                'control_empresas_id' => (int)$resultado['nuevo_id'],
                'ce_empresa_rut'      => $empresa['rut']
            ], "id = :id", ['id' => $empresaId]);
        }

        // Además, el franquiciado queda como CLIENTE de la matriz ASISMA en CE
        // (de su lista de precios salen los precios de productos que él ve)
        $resCliente = IntegracionesHelper::registrarFranquiciadoComoClienteMatriz($empresa);
        if ($resCliente['success'] && !empty($resCliente['cliente_id'])) {
            $db->update('empresas_franquiciados', [
                'ce_cliente_matriz_id' => (int)$resCliente['cliente_id'],
                'ce_lista_precio_id'   => (int)$resCliente['lista_id']
            ], "id = :id", ['id' => $empresaId]);
        }
        $resultado['detalle'] .= ' ' . $resCliente['detalle'];

        AuditHelper::log('provision_ce_franquiciado', 'empresas_franquiciados', $empresaId, null, [
            'franquiciado_id' => $franqId,
            'success'         => $resultado['success'],
            'detalle'         => $resultado['detalle']
        ]);

        return $resultado;
    }

    /**
     * POST: provisiona en Control Empresas un franquiciado existente que aún
     * no tiene empresa creada allá (solo matriz).
     */
    public function provisionarCE() {
        if (!SessionHelper::isAdmin()) {
            $this->json(['success' => false, 'message' => 'Solo la matriz puede provisionar en Control Empresas.'], 403);
        }

        $id = (int)$this->input('id');
        if ($id <= 0) $this->json(['success' => false, 'message' => 'ID inválido.']);

        $db = Database::getInstance();
        $franq = $db->fetchOne("SELECT id, empresa_madre_id FROM franquiciados WHERE id = :id", ['id' => $id]);
        if (!$franq) $this->json(['success' => false, 'message' => 'Franquiciado no encontrado.']);

        $empresa = $db->fetchOne("SELECT * FROM empresas_franquiciados WHERE id = :id", ['id' => $franq['empresa_madre_id']]);
        if (!empty($empresa['control_empresas_id'])) {
            $this->json(['success' => false, 'message' => 'Este franquiciado ya tiene empresa en Control Empresas (ID ' . $empresa['control_empresas_id'] . ').']);
        }

        $resultado = $this->provisionarEnControlEmpresas($franq['empresa_madre_id'], $id);

        $this->json(['success' => $resultado['success'], 'message' => $resultado['detalle']]);
    }

    /**
     * Editar franquiciado existente (AJAX POST)
     */
    public function editar() {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->json(['success' => false, 'message' => 'Método no soportado.'], 405);
        }

        $id           = (int)$this->input('id');
        $razonSocial  = $this->input('razon_social', '');
        $nombreFant   = $this->input('nombre_fantasia', '');
        $rut          = normalizar_rut($this->input('rut', ''));
        $email        = $this->input('email', '');
        $telefono     = $this->input('telefono', '');
        $direccion    = $this->input('direccion', '');
        $giro         = $this->input('giro', '');
        $comunaId     = (int)$this->input('comuna_id');
        $nombreContacto = $this->input('nombre_contacto', '');
        $regionId     = (int)$this->input('region_id');
        $verticalId   = (int)$this->input('vertical_id');
        $tiempoToma   = (int)$this->input('tiempo_toma_lead', 300);
        $prioridad    = (int)$this->input('prioridad', 0);
        $maxLeads     = (int)$this->input('max_leads_activos', 0);
        $estado       = $this->input('estado', 'activo');

        if ($id <= 0 || empty($razonSocial) || empty($rut) || $regionId <= 0 || $verticalId <= 0) {
            $this->json(['success' => false, 'message' => 'Datos incompletos.']);
        }
        $this->validarDatosFacturacion($email, $telefono, $direccion, $giro, $comunaId);

        $db = Database::getInstance();
        $franq = $db->fetchOne("SELECT * FROM franquiciados WHERE id = :id", ['id' => $id]);
        if (!$franq) {
            $this->json(['success' => false, 'message' => 'Franquiciado no encontrado.']);
        }

        // Verificar RUT duplicado (excluyendo la empresa actual)
        $existe = $db->fetchOne(
            "SELECT id FROM empresas_franquiciados WHERE rut = :rut AND id != :eid",
            ['rut' => $rut, 'eid' => $franq['empresa_madre_id']]
        );
        if ($existe) {
            $this->json(['success' => false, 'message' => 'El RUT ya está registrado en otro franquiciado.']);
        }

        $db->beginTransaction();
        try {
            $db->update('empresas_franquiciados', [
                'razon_social'    => $razonSocial,
                'nombre_fantasia' => $nombreFant ?: $razonSocial,
                'rut'             => $rut,
                'email'           => $email,
                'telefono'        => $telefono,
                'direccion'       => $direccion,
                'giro'            => $giro,
                'comuna_id'       => $comunaId,
                'nombre_contacto' => $nombreContacto
            ], "id = :id", ['id' => $franq['empresa_madre_id']]);

            $db->update('franquiciados', [
                'region_id'         => $regionId,
                'vertical_id'       => $verticalId,
                'estado'            => $estado,
                'tiempo_toma_lead'  => $tiempoToma,
                'prioridad'         => $prioridad,
                'max_leads_activos' => $maxLeads
            ], "id = :id", ['id' => $id]);

            AuditHelper::log('edit_franquiciado', 'franquiciados', $id, $franq, ['region_id' => $regionId]);

            $db->commit();
            $this->json(['success' => true, 'message' => 'Franquiciado actualizado correctamente.']);

        } catch (Exception $e) {
            $db->rollBack();
            error_log("Error al editar franquiciado: " . $e->getMessage());
            $this->json(['success' => false, 'message' => 'Error de base de datos al actualizar.']);
        }
    }

    /**
     * Cambiar estado activo/suspendido (AJAX POST)
     */
    public function toggleEstado() {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->json(['success' => false, 'message' => 'Método no soportado.'], 405);
        }

        $id = (int)$this->input('id');
        if ($id <= 0) {
            $this->json(['success' => false, 'message' => 'ID inválido.']);
        }

        $db = Database::getInstance();
        $franq = $db->fetchOne("SELECT id, estado FROM franquiciados WHERE id = :id", ['id' => $id]);
        if (!$franq) {
            $this->json(['success' => false, 'message' => 'Franquiciado no encontrado.']);
        }

        $nuevoEstado = $franq['estado'] === 'activo' ? 'suspendido' : 'activo';
        $db->update('franquiciados', ['estado' => $nuevoEstado], "id = :id", ['id' => $id]);

        AuditHelper::log('toggle_franquiciado', 'franquiciados', $id, ['estado' => $franq['estado']], ['estado' => $nuevoEstado]);

        $this->json(['success' => true, 'estado' => $nuevoEstado, 'message' => 'Estado actualizado.']);
    }

    /**
     * Vista de Cola de Asignación de un franquiciado
     */
    public function colaIndex() {
        if (!SessionHelper::isAdmin()) {
            $this->redirect('dashboard');
        }

        $id = (int)$this->input('franquiciado_id');
        $db = Database::getInstance();

        $franquiciados = $db->fetchAll(
            "SELECT f.id, ef.nombre_fantasia FROM franquiciados f
             INNER JOIN empresas_franquiciados ef ON f.empresa_madre_id = ef.id
             WHERE f.estado = 'activo' ORDER BY ef.nombre_fantasia ASC"
        );

        $colaActual = array();
        $usuariosDisponibles = array();

        if ($id > 0) {
            $colaActual = $db->fetchAll(
                "SELECT c.*, u.nombre as usuario_nombre, u.email as usuario_email
                 FROM cola_asignacion c
                 INNER JOIN usuarios u ON c.usuario_id = u.id
                 WHERE c.franquiciado_id = :fid
                 ORDER BY c.orden ASC",
                array('fid' => $id)
            );
            $usuariosDisponibles = $db->fetchAll(
                "SELECT id, nombre, email FROM usuarios WHERE franquiciado_id = :fid AND activo = 1 AND rol = :rol ORDER BY nombre ASC",
                array('fid' => $id, 'rol' => ROL_VENDEDOR)
            );
        }

        $this->render('franquiciados/cola', array(
            'title'              => 'Cola de Asignación',
            'franquiciados'      => $franquiciados,
            'franquiciadoId'     => $id,
            'colaActual'         => $colaActual,
            'usuariosDisponibles'=> $usuariosDisponibles
        ));
    }

    /**
     * Guardar configuración de cola de asignación (AJAX POST)
     */
    public function colaGuardar() {
        if (!SessionHelper::isAdmin()) {
            $this->json(array('success' => false, 'message' => 'Sin permisos.'), 403);
        }

        $franquiciadoId = (int)$this->input('franquiciado_id');
        $accion         = $this->input('accion', '');
        $usuarioId      = (int)$this->input('usuario_id');

        if ($franquiciadoId <= 0) {
            $this->json(array('success' => false, 'message' => 'Franquiciado inválido.'));
        }

        $db = Database::getInstance();

        if ($accion === 'agregar') {
            $existe = $db->fetchOne("SELECT id FROM cola_asignacion WHERE franquiciado_id = :fid AND usuario_id = :uid", array('fid' => $franquiciadoId, 'uid' => $usuarioId));
            if ($existe) {
                $db->update('cola_asignacion', array('activo' => 1), "id = :id", array('id' => $existe['id']));
            } else {
                $maxOrden = $db->fetchOne("SELECT MAX(orden) as mx FROM cola_asignacion WHERE franquiciado_id = :fid", array('fid' => $franquiciadoId));
                $db->insert('cola_asignacion', array(
                    'franquiciado_id' => $franquiciadoId,
                    'usuario_id'      => $usuarioId,
                    'orden'           => (int)$maxOrden['mx'] + 1,
                    'activo'          => 1
                ));
            }
            AuditHelper::log('cola_agregar', 'cola_asignacion', $franquiciadoId, null, array('usuario_id' => $usuarioId));
            $this->json(array('success' => true, 'message' => 'Vendedor agregado a la cola.'));

        } elseif ($accion === 'quitar') {
            $db->delete('cola_asignacion', "franquiciado_id = :fid AND usuario_id = :uid", array('fid' => $franquiciadoId, 'uid' => $usuarioId));
            AuditHelper::log('cola_quitar', 'cola_asignacion', $franquiciadoId, null, array('usuario_id' => $usuarioId));
            $this->json(array('success' => true, 'message' => 'Vendedor removido de la cola.'));

        } elseif ($accion === 'reordenar') {
            $orden = isset($_POST['orden']) ? $_POST['orden'] : array();
            foreach ($orden as $idx => $uid) {
                $uid = (int)$uid;
                $db->update('cola_asignacion', array('orden' => (int)$idx + 1), "franquiciado_id = :fid AND usuario_id = :uid", array('fid' => $franquiciadoId, 'uid' => $uid));
            }
            AuditHelper::log('cola_reordenar', 'cola_asignacion', $franquiciadoId, null, array('cantidad' => count($orden)));
            $this->json(array('success' => true, 'message' => 'Orden actualizado.'));
        } else {
            $this->json(array('success' => false, 'message' => 'Acción no reconocida.'));
        }
    }

    /**
     * Obtener datos de un franquiciado para rellenar el formulario de edición (AJAX GET)
     */
    public function getData() {
        $id = (int)$this->input('id');
        if ($id <= 0) {
            $this->json(['success' => false, 'message' => 'ID inválido.']);
        }

        $db = Database::getInstance();
        $sql = "SELECT f.*, ef.razon_social, ef.nombre_fantasia, ef.rut, ef.email, ef.telefono,
                       ef.direccion, ef.giro, ef.comuna_id, ef.nombre_contacto, ef.control_empresas_id
                FROM franquiciados f
                INNER JOIN empresas_franquiciados ef ON f.empresa_madre_id = ef.id
                WHERE f.id = :id LIMIT 1";
        $data = $db->fetchOne($sql, ['id' => $id]);

        if (!$data) {
            $this->json(['success' => false, 'message' => 'No encontrado.']);
        }

        $this->json(['success' => true, 'data' => $data]);
    }
}
