<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
 * Represents a single machine-readable capability granted by a Plan.
 *
 * This is the normalized, queryable alternative to storing limits in a JSON blob.
 * Each row represents one feature entitlement on one plan.
 *
 * Value conventions (all stored as VARCHAR, cast at the application layer):
 *   '15'    → numeric limit   → $entitlement->numericLimit() returns 15
 *   'true'  → boolean flag    → $entitlement->boolValue() returns true
 *   'false' → disabled flag   → $entitlement->boolValue() returns false
 *   NULL    → unlimited/on    → $entitlement->isUnlimited() returns true
 *
 * Modules seed defaults during activation via AdminModulesController::provisionProductFromManifest().
 * Admins can adjust values through each module's admin panel without touching the core.
 *
 * @property int         $id
 * @property int         $plan_id
 * @property string      $key
 * @property string|null $value
 * @property string|null $label       Human-readable display text for the pricing page
 * @property bool        $is_visible  Whether to render on the public pricing page
 */
class PlanEntitlement extends Model
{
    protected $table   = 'plan_entitlements';
    protected $guarded = ['id'];

    protected $casts = [
        'is_visible' => 'boolean',
    ];

    // -------------------------------------------------------------------------
    // Relationships
    // -------------------------------------------------------------------------

    public function plan(): BelongsTo
    {
        return $this->belongsTo(Plan::class);
    }

    // -------------------------------------------------------------------------
    // Value helpers
    // -------------------------------------------------------------------------

    /**
     * Returns the numeric limit, or null if unlimited (value is NULL).
     */
    public function numericLimit(): ?int
    {
        return $this->value !== null ? (int) $this->value : null;
    }

    /**
     * Returns true when value is NULL (no cap enforced — unlimited usage).
     */
    public function isUnlimited(): bool
    {
        return $this->value === null;
    }

    /**
     * Interprets the value as a boolean feature flag.
     */
    public function boolValue(): bool
    {
        return $this->value === 'true' || $this->value === '1';
    }

    // -------------------------------------------------------------------------
    // Static query helpers
    // -------------------------------------------------------------------------

    /**
     * Retrieve the raw value for a specific entitlement key on a plan.
     * Returns null if the key does not exist OR if value is NULL (unlimited).
     *
     * Usage:
     *   $limit = PlanEntitlement::valueOf($plan, 'generations_per_month');
     *   if ($limit !== null) { // enforce limit }
     */
    public static function valueOf(Plan $plan, string $key): ?string
    {
        return static::where('plan_id', $plan->id)
                     ->where('key', $key)
                     ->value('value');
    }
}
