<?php

namespace SugarCalendarBookings\Integrations\CalendarEvents;

use SugarCalendarBookings\Appointments\AppointmentModel;

/**
 * Calendar event link repository.
 *
 * Reads and writes calendar event links from an appointment's meta. Owns the
 * meta key and the JSON-decode fallback used for legacy stored shapes.
 *
 * @since 1.5.0
 */
class EventLinkRepository {

	/**
	 * Meta key on the appointment that stores all calendar event links.
	 *
	 * @since 1.5.0
	 */
	public const META_KEY = 'external_calendar_events';

	/**
	 * Register the dynamic meta key so set_meta/get_meta accept it.
	 *
	 * Called from CalendarEventManager::hooks() so registration timing
	 * is identical to the pre-refactor flow.
	 *
	 * @since 1.5.0
	 */
	public static function register_meta(): void {

		AppointmentModel::register_meta_field( self::META_KEY, [] );
	}

	/**
	 * Read the calendar event links for the appointment.
	 *
	 * @since 1.5.0
	 *
	 * @param AppointmentModel $appointment Target appointment.
	 *
	 * @return EventLinkCollection
	 */
	public function read( AppointmentModel $appointment ): EventLinkCollection {

		$raw = $appointment->get_meta( self::META_KEY );

		if ( is_string( $raw ) && $raw !== '' ) {
			$decoded = json_decode( $raw, true );
			$raw     = is_array( $decoded ) ? $decoded : [];
		}

		if ( ! is_array( $raw ) ) {
			return EventLinkCollection::empty();
		}

		return EventLinkCollection::from_raw( array_values( $raw ) );
	}

	/**
	 * Persist the calendar event links for the appointment.
	 *
	 * Stored as a JSON string because HasMeta::set_meta() casts every value to
	 * string before writing, which would silently corrupt a raw array to the
	 * literal "Array". The read side already JSON-decodes the stored string.
	 *
	 * @since 1.5.0
	 *
	 * @param AppointmentModel    $appointment Target appointment.
	 * @param EventLinkCollection $links       Links to persist.
	 */
	public function write( AppointmentModel $appointment, EventLinkCollection $links ): void {

		$appointment->set_meta( self::META_KEY, (string) wp_json_encode( $links->to_array() ) );
	}
}
