<?php

namespace SugarCalendarBookings\Integrations\Webhooks;

use DateTimeImmutable;
use SugarCalendarBookings\Support\Database\AbstractModel;

/**
 * Webhook subscription model.
 *
 * Maps a provider-issued push subscription to the OAuth connection and the
 * resource it watches. One row per (connection, watched resource) — for
 * calendar providers the resource is a calendar id, so an Outlook connection
 * watching three conflict calendars owns three rows.
 *
 * The watched resource is generic on purpose: the column is `resource_id`,
 * not `calendar_id`, so other push-subscription providers (e.g. Google
 * Calendar watch channels) can reuse the same table. Connection-wide
 * subscriptions that don't target a specific resource store an empty
 * `resource_id` (so the unique key still behaves — MySQL treats NULLs as
 * distinct, which would allow duplicate connection-wide rows).
 *
 * The webhook handler resolves an incoming notification's source resource from
 * this mapping instead of trying to derive it from the event payload.
 *
 * @since 1.5.0
 *
 * @property int               $id
 * @property int               $connection_id
 * @property string            $provider
 * @property string            $resource_id
 * @property string            $subscription_id
 * @property DateTimeImmutable $expires_at
 * @property string            $status
 * @property DateTimeImmutable $created_at
 * @property DateTimeImmutable $updated_at
 */
class WebhookSubscriptionModel extends AbstractModel {

	/**
	 * Active subscription status.
	 *
	 * @since 1.5.0
	 *
	 * @var string
	 */
	const STATUS_ACTIVE = 'active';

	/**
	 * The database table name without prefix.
	 *
	 * @since 1.5.0
	 *
	 * @var string
	 */
	protected static $table_name = 'webhook_subscriptions';

	/**
	 * The model type identifier.
	 *
	 * @since 1.5.0
	 *
	 * @var string
	 */
	protected static $type = 'webhook_subscription';

	/**
	 * Column formats for the model.
	 *
	 * @since 1.5.0
	 *
	 * @var array<string, string>
	 */
	protected static $column_formats = [
		'id'              => '%d',
		'connection_id'   => '%d',
		'provider'        => '%s',
		'resource_id'     => '%s',
		'subscription_id' => '%s',
		'expires_at'      => '%s',
		'status'          => '%s',
		'created_at'      => '%s',
		'updated_at'      => '%s',
	];

	/**
	 * The attributes that should be cast.
	 *
	 * @since 1.5.0
	 *
	 * @var array<string, string>
	 */
	protected static $casts = [
		'id'            => 'integer',
		'connection_id' => 'integer',
		'expires_at'    => 'datetime',
		'created_at'    => 'datetime',
		'updated_at'    => 'datetime',
	];

	/**
	 * Column defaults for the model.
	 *
	 * @since 1.5.0
	 *
	 * @return array<string, mixed>
	 */
	protected static function column_defaults() {

		return [
			'resource_id' => '',
			'status'      => self::STATUS_ACTIVE,
		];
	}
}
