<?php

declare(strict_types=1);

namespace App\Models;

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

/**
 * Идемпотентность webhook'ов от crm.bp-gr.ru — отдельная не-партиционированная
 * таблица с PRIMARY KEY (tenant_id, source_crm_id).
 *
 * v8.6 (CTO-17): архитектурная замена UNIQUE INDEX на партиционированной deals
 * (PostgreSQL запрещает UNIQUE без partition key). См. db/schema.sql:1289 и
 * §5.5 narrative ТЗ — двустадийная dedup-логика.
 *
 * Composite PK (tenant_id, source_crm_id). $incrementing=false, $primaryKey
 * не задан — работаем через QueryBuilder. Eloquent-CRUD не используется
 * (записи создаёт ProcessWebhookJob через DB::selectOne ON CONFLICT).
 *
 * Полезна для тестов и debug-запросов: WebhookDedupKey::where(...)->count().
 *
 * @mixin IdeHelperWebhookDedupKey
 */
class WebhookDedupKey extends Model
{
    protected $table = 'webhook_dedup_keys';

    public $incrementing = false;

    public $timestamps = false;

    protected $fillable = [
        'tenant_id',
        'source_crm_id',
        'deal_id',
        'deal_received_at',
        'created_at',
        'updated_at',
    ];

    protected function casts(): array
    {
        return [
            'tenant_id' => 'integer',
            'source_crm_id' => 'integer',
            'deal_id' => 'integer',
            'deal_received_at' => 'datetime',
            'created_at' => 'datetime',
            'updated_at' => 'datetime',
        ];
    }

    /**
     * Composite PK guard на случай Eloquent::save() из тестов.
     */
    protected function setKeysForSaveQuery($query)
    {
        return $query
            ->where('tenant_id', $this->getAttribute('tenant_id'))
            ->where('source_crm_id', $this->getAttribute('source_crm_id'));
    }

    /** @return BelongsTo<Tenant, $this> */
    public function tenant(): BelongsTo
    {
        return $this->belongsTo(Tenant::class);
    }
}
