<?php

namespace App\Models;

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

class Transaction extends Model
{
    use HasFactory;

    public const STATUS_TRUE_POSITIVE = 'true_positive';

    public const STATUS_FALSE_POSITIVE = 'false_positive';

    public const STATUS_CLEARED = 'cleared';

    /**
     * Disable mass assignment protection to allow JSONB columns
     *
     * @var array<int, string>
     */
    protected $guarded = [];

    /**
     * Cached JSONB column casts to avoid repeated schema queries
     */
    private static ?array $jsonbCasts = null;

    /**
     * Get the attributes that should be cast.
     *
     * Dynamically casts all JSONB columns (102 output_keys) as arrays
     * Uses static caching to avoid repeated database schema queries
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        // Return cached casts if available
        if (self::$jsonbCasts !== null) {
            return self::$jsonbCasts;
        }

        $standardCasts = [
            'executed_at' => 'datetime',
            'requires_review' => 'boolean',
            'signals' => 'array',
        ];

        // Standard non-JSONB columns
        $standardColumns = [
            'id', 'company_id', 'reference', 'amount', 'currency',
            'counterparty', 'counterparty_country', 'channel', 'executed_at',
            'risk_score', 'status', 'requires_review', 'flagged_by',
            'flagged_reason', 'signals', 'created_at', 'updated_at',
        ];

        try {
            // Get all columns from the database (only once per request)
            $allColumns = \Illuminate\Support\Facades\Schema::getColumnListing('transactions');

            // All remaining columns are JSONB columns that should be cast as arrays
            $jsonbColumns = array_diff($allColumns, $standardColumns);

            foreach ($jsonbColumns as $column) {
                $standardCasts[$column] = 'array';
            }
        } catch (\Exception $e) {
            // If schema query fails (e.g., during migrations), just use standard casts
            \Illuminate\Support\Facades\Log::warning('Failed to load JSONB column casts: '.$e->getMessage());
        }

        // Cache for subsequent calls
        self::$jsonbCasts = $standardCasts;

        return self::$jsonbCasts;
    }

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

    public function statusLabel(): string
    {
        return match ($this->status) {
            self::STATUS_TRUE_POSITIVE => __('Kritisches Risiko'),
            self::STATUS_FALSE_POSITIVE => __('Hohes Risiko'),
            self::STATUS_CLEARED => __('Geringes Risiko'),
            default => __('Unbekanntes Risiko'),
        };
    }
}
