<?php

namespace SugarCalendarBookings\Integrations;

use SugarCalendarBookings\Appointments\AppointmentModel;
use SugarCalendarBookings\Integrations\OAuthRelay\OAuthConnectionModel;
use WP_Error;

/**
 * Calendar event provider interface.
 *
 * Contract for integrations that mirror appointments as calendar events on a
 * third-party calendar (Outlook, Google Calendar). Unlike MeetingProviderInterface,
 * event push is per-user rather than per-online-location: every appointment owned
 * by a connected user is mirrored, regardless of online_location.
 *
 * @since 1.5.0
 */
interface CalendarEventProviderInterface extends IntegrationCapabilityInterface {

	/**
	 * Push a new calendar event for an appointment on a specific connection.
	 *
	 * @since 1.5.0
	 *
	 * @param AppointmentModel     $appointment Appointment to mirror.
	 * @param OAuthConnectionModel $connection  Target OAuth connection.
	 *
	 * @return array|WP_Error Event link metadata or error.
	 *   Shape: [
	 *     'connection_id' => int,
	 *     'provider'      => string,
	 *     'calendar_id'   => string,
	 *     'event_id'      => string,
	 *     'event_url'     => string,
	 *     'pushed_at'     => string  // ISO 8601 UTC.
	 *   ]
	 */
	public function push_event( AppointmentModel $appointment, OAuthConnectionModel $connection );

	/**
	 * Update an existing calendar event after an appointment change.
	 *
	 * @since 1.5.0
	 *
	 * @param AppointmentModel     $appointment   Updated appointment.
	 * @param OAuthConnectionModel $connection    Target OAuth connection.
	 * @param string               $event_id      Existing provider event ID.
	 * @param array                $existing_link Previously-stored event link entry from appointment meta.
	 *
	 * @return array|WP_Error Updated link metadata (same shape as push_event) or error.
	 */
	public function update_event( AppointmentModel $appointment, OAuthConnectionModel $connection, string $event_id, array $existing_link );

	/**
	 * Delete a calendar event for an appointment on a specific connection.
	 *
	 * Called in two situations: when a connection drops out of the deliverable
	 * set (e.g. employee disconnects their calendar), and when an appointment
	 * is hard-deleted. On cancellation, use
	 * CancellableCalendarEventProviderInterface::cancel_event() instead.
	 *
	 * @since 1.5.0
	 *
	 * @param AppointmentModel     $appointment   Appointment being deleted.
	 * @param OAuthConnectionModel $connection    Target OAuth connection.
	 * @param string               $event_id      Provider event ID to delete.
	 * @param array                $existing_link Previously-stored event link entry.
	 *
	 * @return true|WP_Error True on success or error.
	 */
	public function delete_event( AppointmentModel $appointment, OAuthConnectionModel $connection, string $event_id, array $existing_link );

	/**
	 * Return the list of active OAuth connections that should receive an event for this appointment.
	 *
	 * Each provider encapsulates its own fan-out rules. In Lite, only the admin's own connection.
	 * In Pro, the employee's own connection plus the admin's connection if admin monitoring matches.
	 *
	 * @since 1.5.0
	 *
	 * @param AppointmentModel $appointment Appointment to resolve connections for.
	 *
	 * @return OAuthConnectionModel[]
	 */
	public function get_deliverable_connections( AppointmentModel $appointment ): array;

	/**
	 * Meta keys the provider writes onto each entry in appointment meta `external_calendar_events`.
	 *
	 * @since 1.5.0
	 *
	 * @return string[]
	 */
	public function get_event_link_keys(): array;
}
