<?php
/**
 * ASISMA CRM - Identidad visual del documento de cotización, POR MARCA.
 *
 * Decisión 22-07-2026: la identidad corporativa vive en la MARCA
 * (marcas.branding_json + diseno_documento + condiciones_json) y aplica a
 * TODO lo que la marca vende, productos y servicios. El servicio solo aporta
 * su contenido de oferta (rótulo del cliente, párrafos, frase, título de
 * bonos, garantía, planes, características y bonos).
 *
 * Cascada de resolución: defaults sobrios ← branding de la MARCA ← rótulo
 * del servicio (si lo hay).
 */
class IdentidadHelper {

    /** Identidad corporativa que se configura POR MARCA. */
    private static $camposMarca = array(
        'color_primario', 'color_secundario', 'logo_ruta', 'eslogan',
        'ciudad_firma', 'telefono_contacto',
        'transferencia_titular', 'transferencia_rut', 'transferencia_banco',
        'transferencia_tipo_cuenta', 'transferencia_numero_cuenta', 'transferencia_correo'
    );

    /** Cache por request: marca_id => fila resuelta. */
    private static $cacheMarcas = array();

    public static function camposMarca() {
        return self::$camposMarca;
    }

    /** Claves completas de la identidad (marca + rótulo, que es del servicio). */
    public static function campos() {
        return array_merge(self::$camposMarca, array('rotulo_cliente'));
    }

    /**
     * Diseños pre-configurados del documento de cotización. La clave se guarda
     * en marcas.diseno_documento; el documento unificado (publica.php) pinta
     * cada uno con su propio estilo. 'moderno' con servicio usa la plantilla
     * ornamentada (publica_servicio, ex Control Farma).
     */
    public static function disenos() {
        return array(
            'ejecutivo' => array(
                'nombre'      => 'Ejecutivo',
                'descripcion' => 'Sobrio y corporativo: tipografía formal, líneas finas, el clásico documento de negocios.'
            ),
            'moderno' => array(
                'nombre'      => 'Moderno',
                'descripcion' => 'Ornamentado y vendedor (estilo Control Farma): héroe destacado, degradados y bordes decorativos.'
            ),
            'minimal' => array(
                'nombre'      => 'Minimal',
                'descripcion' => 'Blanco y aire: solo tipografía y espacios, sin adornos ni sombras. Elegancia silenciosa.'
            ),
            'oscuro' => array(
                'nombre'      => 'Elegante Oscuro',
                'descripcion' => 'Fondo carbón con acentos del color de la marca. Premium y tecnológico.'
            ),
            'comercial' => array(
                'nombre'      => 'Comercial',
                'descripcion' => 'Vivo y directo, estilo folleto: cajas redondeadas, precios grandes y bonos protagonistas.'
            ),
        );
    }

    /** Identidad por defecto: sobria/corporativa (nunca el morado de CF). */
    public static function defaults() {
        return array(
            'color_primario'              => '#1c2430',
            'color_secundario'            => '#334155',
            'logo_ruta'                   => null,
            'eslogan'                     => '',
            'ciudad_firma'                => 'Santiago',
            'telefono_contacto'           => '',
            'rotulo_cliente'              => 'su empresa',
            'transferencia_titular'       => '',
            'transferencia_rut'           => '',
            'transferencia_banco'         => '',
            'transferencia_tipo_cuenta'   => '',
            'transferencia_numero_cuenta' => '',
            'transferencia_correo'        => '',
        );
    }

    /** Toma solo las claves de identidad no vacías de un arreglo. */
    private static function soloIdentidad($fila) {
        $out = array();
        if (!is_array($fila)) return $out;
        foreach (self::campos() as $c) {
            if (isset($fila[$c]) && $fila[$c] !== '' && $fila[$c] !== null) $out[$c] = $fila[$c];
        }
        return $out;
    }

    /**
     * Extrae las claves de identidad conocidas desde un JSON de branding
     * (string o array). Acepta el blob al ras o bajo la clave "branding".
     */
    public static function desdeConfigJson($brandingJson) {
        $data = is_string($brandingJson) && $brandingJson !== '' ? json_decode($brandingJson, true) : $brandingJson;
        if (!is_array($data)) return array();
        $branding = isset($data['branding']) && is_array($data['branding']) ? $data['branding'] : $data;
        return self::soloIdentidad($branding);
    }

    /**
     * Fila de branding de una MARCA: identidad + diseño + condiciones.
     * Devuelve array(branding => [...], diseno => 'ejecutivo', condiciones => []).
     */
    public static function brandingDeMarca($marcaId) {
        $marcaId = (int)$marcaId;
        if (isset(self::$cacheMarcas[$marcaId])) return self::$cacheMarcas[$marcaId];

        $salida = array('branding' => array(), 'diseno' => 'ejecutivo', 'condiciones' => array());
        if ($marcaId > 0) {
            $fila = Database::getInstance()->fetchOne(
                "SELECT branding_json, diseno_documento, condiciones_json FROM marcas WHERE id = :id",
                array('id' => $marcaId)
            );
            if ($fila) {
                $salida['branding'] = self::desdeConfigJson($fila['branding_json']);
                if (!empty($fila['diseno_documento']) && array_key_exists($fila['diseno_documento'], self::disenos())) {
                    $salida['diseno'] = $fila['diseno_documento'];
                }
                if (!empty($fila['condiciones_json'])) {
                    $cond = json_decode($fila['condiciones_json'], true);
                    if (is_array($cond)) $salida['condiciones'] = $cond;
                }
            }
        }
        self::$cacheMarcas[$marcaId] = $salida;
        return $salida;
    }

    /**
     * Resuelve la identidad final para un documento.
     * @param int        $marcaId     marca dueña de lo cotizado (0 = defaults)
     * @param array|null $servicioCfg fila del servicio (aporta SOLO rotulo_cliente) o null
     */
    public static function resolver($marcaId, $servicioCfg = null) {
        $marca = self::brandingDeMarca($marcaId);
        $identidad = array_merge(self::defaults(), $marca['branding']);
        if (is_array($servicioCfg) && !empty($servicioCfg['rotulo_cliente'])) {
            $identidad['rotulo_cliente'] = $servicioCfg['rotulo_cliente'];
        }
        return $identidad;
    }

    /** Diseño del documento para una marca (clave de disenos()). */
    public static function disenoDeMarca($marcaId) {
        $marca = self::brandingDeMarca($marcaId);
        return $marca['diseno'];
    }

    /** Condiciones comerciales de la marca (array de {titulo, texto}). */
    public static function condicionesDeMarca($marcaId) {
        $marca = self::brandingDeMarca($marcaId);
        return $marca['condiciones'];
    }

    /** Arma el arreglo de branding de MARCA (solo sus claves) desde un POST. */
    public static function construirDesdePost($post) {
        $branding = array();
        foreach (self::$camposMarca as $c) {
            $branding[$c] = isset($post[$c]) ? trim($post[$c]) : '';
        }
        return $branding;
    }

    /**
     * Codifica el branding para guardar en marcas.branding_json. Devuelve
     * null si está TODO vacío (la marca usa los defaults sobrios).
     */
    public static function codificarBranding($branding) {
        foreach ($branding as $v) {
            if (trim((string)$v) !== '') return json_encode($branding, JSON_UNESCAPED_UNICODE);
        }
        return null;
    }

    /** Identidad guardada de una marca (para poblar el editor de la marca). */
    public static function leerDeMarca($marcaId) {
        return array_merge(self::defaults(), self::brandingDeMarca($marcaId)['branding']);
    }
}
