<?php

namespace App\Entities;

use CodeIgniter\Entity\Entity;

class Promocion extends Entity
{
    protected $casts = [
        'id_promocion'    => 'integer',
        'valor_descuento' => 'float',
        'cantidad_minima' => 'integer',
        'stock'           => '?integer',
        'activo'          => 'integer',
    ];

    /**
     * ¿La promoción está marcada como activa (columna `activo`)?
     */
    public function estaActiva(): bool
    {
        return isset($this->attributes['activo']) && (int) $this->attributes['activo'] === 1;
    }

    /**
     * Vigencia por fechas: hoy debe estar entre fecha_inicio y fecha_fin (inclusive).
     */
    public function estaEnRangoDeFechas(): bool
    {
        $hoy = date('Y-m-d');
        return ($this->attributes['fecha_inicio'] ?? '9999-12-31') <= $hoy
            && ($this->attributes['fecha_fin'] ?? '0000-01-01') >= $hoy;
    }

    /**
     * Vigencia de stock: null = ilimitado, de lo contrario debe quedar al menos 1.
     */
    public function tieneStockDisponible(): bool
    {
        return $this->attributes['stock'] === null || (int) $this->attributes['stock'] > 0;
    }

    /**
     * Vigencia completa: activo + rango de fechas + stock.
     * (No valida el día de la semana; eso depende de la tabla promocion_dia
     * y se resuelve en App\Libraries\PromoHelper porque requiere una consulta aparte).
     */
    public function estaVigente(): bool
    {
        return $this->estaActiva() && $this->estaEnRangoDeFechas() && $this->tieneStockDisponible();
    }

    public function esTipoEntrada(): bool
    {
        return ($this->attributes['tipo'] ?? '') === 'ENTRADA';
    }

    /**
     * Cantidad mínima de entradas/items requerida para que la promo se active
     * (ej. "2x1 Domingos" exige 2). Por defecto 1 si la columna viene vacía.
     */
    public function getCantidadMinima(): int
    {
        return max(1, (int) ($this->attributes['cantidad_minima'] ?? 1));
    }

    /**
     * Tipo de sala al que está restringida la promoción (2D/3D/IMAX/4DX),
     * o null si aplica a cualquier tipo de sala.
     */
    public function getTipoSalaRequerido(): ?string
    {
        $tipo = $this->attributes['aplica_tipo_sala'] ?? null;
        return !empty($tipo) ? $tipo : null;
    }

    /**
     * ¿La promoción aplica a funciones del tipo de sala indicado?
     * Si la promo no restringe tipo de sala, siempre es true.
     */
    public function aplicaATipoSala(?string $tipoSala): bool
    {
        $requerido = $this->getTipoSalaRequerido();
        return $requerido === null || $requerido === $tipoSala;
    }

    public function getImagenUrl(): string
    {
        $url = $this->attributes['imagen'] ?? '';
        if (empty($url)) {
            return base_url('img/placeholder-poster.jpg');
        }

        if (preg_match('#^https?://#i', $url)) {
            return $url;
        }

        return base_url('uploads/promociones/' . $url);
    }
}
