<?php

namespace App\Models;

use CodeIgniter\Model;

class CertificadoModel extends Model
{
    protected $table            = 'certificado';
    protected $primaryKey       = 'id';
    protected $useAutoIncrement = true;
    protected $returnType       = 'array';
    protected $useSoftDeletes   = true;
    protected $protectFields    = true;
    protected $allowedFields    = [
        'organizacion_id',
        'usuario_id',
        'firma_usuario_id',
        'tipo_certificado_id',
        'correlativo',
        'created_at',
        'nombre_participante',
        'numero_certificado',
        'evento_id',
        'descripcion',
        'activo'
    ];

    // Dates
    protected $useTimestamps = true;
    protected $dateFormat    = 'datetime';
    protected $createdField  = 'created_at';
    protected $updatedField  = 'updated_at';
    protected $deletedField  = 'deleted_at';

    // Validation
    protected $validationRules      = [
        'organizacion_id'      => 'required|numeric',
        'usuario_id'           => 'required|numeric',
        'tipo_certificado_id'  => 'required|numeric',
        'correlativo'          => 'required|max_length[50]',
        'numero_certificado'   => 'required|max_length[100]',
        'nombre_participante'  => 'required|max_length[255]',
        'created_at'       => 'required|valid_date',
    ];
    protected $validationMessages   = [
        'organizacion_id' => [
            'required' => 'La organización es requerida.'
        ],
        'usuario_id' => [
            'required' => 'El usuario es requerido.'
        ],
        'tipo_certificado_id' => [
            'required' => 'El tipo de certificado es requerido.'
        ],
        'correlativo' => [
            'required' => 'El correlativo es requerido.'
        ],
        'numero_certificado' => [
            'required' => 'El número de certificado es requerido.'
        ],
        'nombre_participante' => [
            'required' => 'El nombre del participante es requerido.'
        ],
        'created_at' => [
            'required' => 'La fecha de creación es requerida.'
        ]
    ];
    protected $skipValidation       = false;
    protected $cleanValidationRules = true;

    // Callbacks
    protected $allowCallbacks = true;
    protected $beforeInsert   = [];
    protected $afterInsert    = [];
    protected $beforeUpdate   = [];
    protected $afterUpdate    = [];
    protected $beforeFind     = [];
    protected $afterFind      = [];
    protected $beforeDelete   = [];
    protected $afterDelete    = [];

    /**
     * Obtiene certificados de una organización con filtro opcional de evento
     * 
     * @param int|null $eventoId ID del evento (opcional)
     * @param int|null $cantidad Cantidad de registros a obtener (opcional)
     * @return array Lista de certificados
     */
    public function getCertificadosPorOrganizacion(?int $eventoId = null, ?int $cantidad = null): array
    {
        $organizacionId = session()->get('usuario')['organizacion_id'] ?? null;
        
        // Construir query base con filtros obligatorios
        $builder = $this->where('deleted_at', null);
        
        $usuario = session()->get('usuario');
        if (isset($usuario['perfil_id']) && $usuario['perfil_id'] > 1) {
            $builder = $builder->where('organizacion_id', $organizacionId);
        }
        
        // Aplicar filtro de evento si se proporciona
        if (!empty($eventoId)) {
            $builder->where('evento_id', $eventoId);
        }

        if (!empty($cantidad)) {
            return $builder->orderBy('created_at', 'DESC')->findAll($cantidad);
        }
        
        return $builder->orderBy('created_at', 'DESC')->findAll();
    }

    /**
     * Obtiene certificados por tipo de certificado
     * 
     * @param int $tipoCertificadoId ID del tipo de certificado
     * @param int|null $cantidad Cantidad de registros a obtener (opcional)
     * @return array Lista de certificados
     */
    public function getCertificadosPorTipo(int $tipoCertificadoId, ?int $cantidad = null): array
    {
        $organizacionId = session()->get('usuario')['organizacion_id'] ?? null;
        
        $builder = $this->where('tipo_certificado_id', $tipoCertificadoId)
                        ->where('deleted_at', null);
        
        $usuario = session()->get('usuario');
        if (isset($usuario['perfil_id']) && $usuario['perfil_id'] > 1) {
            $builder = $builder->where('organizacion_id', $organizacionId);
        }

        if (!empty($cantidad)) {
            return $builder->orderBy('created_at', 'DESC')->findAll($cantidad);
        }
        
        return $builder->orderBy('created_at', 'DESC')->findAll();
    }

    /**
     * Obtiene certificados de un usuario específico
     * 
     * @param int $usuarioId ID del usuario
     * @param int|null $cantidad Cantidad de registros a obtener (opcional)
     * @return array Lista de certificados
     */
    public function getCertificadosPorUsuario(int $usuarioId, ?int $cantidad = null): array
    {
        $builder = $this->where('usuario_id', $usuarioId)
                        ->where('deleted_at', null)
                        ->where('activo', 1);

        if (!empty($cantidad)) {
            return $builder->orderBy('created_at', 'DESC')->findAll($cantidad);
        }
        
        return $builder->orderBy('created_at', 'DESC')->findAll();
    }

    /**
     * Obtiene el siguiente correlativo para una organización
     * 
     * @param int|null $organizacionId ID de la organización (opcional, usa sesión si no se proporciona)
     * @return string Siguiente correlativo
     */
    public function getSiguienteCorrelativo(?int $organizacionId = null): string
    {
        if (empty($organizacionId)) {
            $organizacionId = session()->get('usuario')['organizacion_id'] ?? 1;
        }

        $ultimoCertificado = $this->where('organizacion_id', $organizacionId)
        ->where('deleted_at', null)
        ->orderBy('id', 'DESC')
        ->first();

        if ($ultimoCertificado) {
            // Extraer número del correlativo y sumar 1
            preg_match('/(\d+)/', $ultimoCertificado['correlativo'], $matches);
            $numero = isset($matches[1]) ? intval($matches[1]) + 1 : 1;
            return 'CERT-' . str_pad($numero, 6, '0', STR_PAD_LEFT);
        }

        return 'CERT-000001';
    }
}
