<?php

namespace Modules\SmartStorage\Entities;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Crypt;

class SsSetting extends Model
{
    protected $table = 'ss_settings';

    protected $guarded = ['id'];

    protected $casts = [
        'encryption_enabled' => 'boolean',
        'otp_enabled'        => 'boolean',
        'track_reads'        => 'boolean',
        'track_writes'       => 'boolean',
        'otp_ttl_minutes'    => 'integer',
    ];

    /** @var SsSetting|null per-request cache */
    protected static $cached;

    /**
     * The active settings row. There is one row per business (or a single global
     * row when no business context exists). Created lazily from config defaults
     * so the app never crashes on a fresh install.
     */
    public static function current(): self
    {
        if (static::$cached) {
            return static::$cached;
        }

        $businessId = function_exists('auth') && auth()->check()
            ? (auth()->user()->business_id ?? null)
            : null;

        $query = static::query();
        if ($businessId) {
            $query->where('business_id', $businessId);
        }

        $row = $query->first() ?? static::query()->first();

        if (!$row) {
            $row = new static(array_merge(
                config('smartstorage.defaults', []),
                ['business_id' => $businessId]
            ));
            // Persist only when the table exists and we are not mid-migration.
            try {
                $row->save();
            } catch (\Throwable $e) {
                // leave unsaved; behaves as defaults for this request
            }
        }

        return static::$cached = $row;
    }

    public static function flushCache(): void
    {
        static::$cached = null;
    }

    /**
     * Decoded credentials array (decrypted). Shape: [backend => [key => value]].
     */
    public function credentialsArray(): array
    {
        if (empty($this->credentials)) {
            return [];
        }
        try {
            $decrypted = Crypt::decryptString($this->credentials);
            $data = json_decode($decrypted, true);
            return is_array($data) ? $data : [];
        } catch (\Throwable $e) {
            return [];
        }
    }

    public function setCredentialsArray(array $data): void
    {
        $this->credentials = Crypt::encryptString(json_encode($data));
    }

    /**
     * Convenience accessor for a single credential of the active/given backend.
     */
    public function cred(string $backend, string $key, $default = null)
    {
        $all = $this->credentialsArray();
        return $all[$backend][$key] ?? $default;
    }

    public function lanCidrList(): array
    {
        return collect(explode(',', (string) $this->lan_cidrs))
            ->map(fn ($c) => trim($c))
            ->filter()
            ->values()
            ->all();
    }
}
