<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;

class Constant extends Model
{
    use HasFactory;

    protected $guarded = ['id'];

    protected $casts = [
        'constant_value' => 'integer',
    ];

    /**
     * Retrieve a constant from cache or database.
     *
     * @param string $key
     * @return mixed
     */
    public static function getConstant(string $key): mixed
    {
        // Cache key for this constant
        $cacheKey = 'constant_' . $key;

        // Check if constant is in cache
        return Cache::remember($cacheKey, 600, function () use ($key) {
            // If not cached, retrieve it from the database
            return self::where('constant_key', $key)->first()->constant_value ?? null;
        });
    }

    /**
     * Retrieve all constants by type from cache or database.
     *
     * @param string $type
     * @return mixed
     */
    public static function getByType(string $type): mixed
    {
        // Cache key for this type
        $cacheKey = 'constants_type_' . $type;

//        return Cache::remember($cacheKey, 600, function () use ($type) {
            return self::where('type', $type)
                ->pluck('label', 'constant_value')
                ->toArray();
    }

    public static function getKeyValuesByType(string $type): array
    {
        return self::where('type', $type)
            ->pluck('constant_value', 'constant_key')
            ->toArray();
    }

    /**
     * Retrieve a constant by its value from cache or database.
     *
     * @param string $type
     * @param string $value
     * @return mixed
     */
    public static function getByValue(string $type, string $value): mixed
    {
        // Cache key for this constant value
        $cacheKey = 'constant_' . $type . '_' . $value;

        // Check if constant is in cache
        return Cache::remember($cacheKey, 600, function () use ($type, $value) {
            // If not cached, retrieve it from the database
            return self::where('constant_value', $value)
                ->where('type', $type)
                ->first();
        });
    }

    function getConstantValues(string $type): array
    {
        return array_keys(Constant::getByType($type));
    }

    /**
     * Get all order statuses
     *
     * @return Collection
     */
    public static function orderStatuses(): Collection
    {
        return self::getByType('order_status');
    }

    /**
     * Get all subscription statuses
     *
     * @return Collection
     */
    public static function subscriptionStatuses(): Collection
    {
        return self::getByType('subscription_status');
    }

    /**
     * Get all billing cycles
     *
     * @return Collection
     */
    public static function billingCycles(): Collection
    {
        return self::getByType('billing_cycle');
    }

    /**
     * Get all trial duration units
     *
     * @return Collection
     */
    public static function trialDurationUnits(): Collection
    {
        return self::getByType('trial_duration_unit');
    }

    /**
     * Get all plan types
     *
     * @return Collection
     */
    public static function planTypes(): Collection
    {
        return self::getByType('billing_type');
    }
}
