<?php
/**
 * MeetingTypeRepository
 *
 * Data access layer for meeting types and their availability/overrides.
 *
 * @package RadiusTheme\RadiusBooking\Repositories
 * @since   1.2.0
 */

namespace RadiusTheme\RadiusBooking\Repositories;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use RadiusTheme\RadiusBooking\Abstracts\BaseRepository;
use RadiusTheme\RadiusBooking\Models\MeetingType;
use RadiusTheme\RadiusBooking\Models\MeetingTypeAvailability;
use RadiusTheme\RadiusBooking\Models\MeetingTypeDateOverride;

/**
 * Class MeetingTypeRepository
 */
class MeetingTypeRepository extends BaseRepository {

	/**
	 * The model class managed by this repository.
	 *
	 * @var string
	 */
	protected string $model = MeetingType::class;

	/**
	 * Find a meeting type by its public-facing slug.
	 *
	 * @param string $slug The slug to search for.
	 *
	 * @return MeetingType|null
	 */
	public function findBySlug( string $slug ) {
		$result = MeetingType::where( 'slug', $slug )
			->where( 'is_active', 1 )
			->first();

		return $result ? MeetingType::hydrate( $result ) : null;
	}

	/**
	 * Get all meeting types for a given employee.
	 *
	 * @param int $employee_id The employee user ID.
	 *
	 * @return array
	 */
	public function findByEmployee( int $employee_id ): array {
		return MeetingType::where( 'employee_id', $employee_id )->get();
	}

	/**
	 * Get active meeting types for a given employee.
	 *
	 * @param int $employee_id The employee user ID.
	 *
	 * @return array
	 */
	public function getActiveByEmployee( int $employee_id ): array {
		return MeetingType::where( 'employee_id', $employee_id )
			->where( 'is_active', 1 )
			->get();
	}

	/**
	 * Replace all availability windows for a meeting type.
	 *
	 * @param int   $meeting_type_id The meeting type ID.
	 * @param array $availability_data Array of availability slot data.
	 *
	 * @return void
	 */
	public function syncAvailability( int $meeting_type_id, array $availability_data ): void {
		MeetingTypeAvailability::deleteWhere( array( 'meeting_type_id' => $meeting_type_id ) );

		foreach ( $availability_data as $slot ) {
			$day_of_week = $slot['day_of_week'] ?? null;
			if ( null === $day_of_week ) {
				continue;
			}

			$is_enabled = $slot['is_enabled'] ?? true;

			// Frontend sends grouped format with time_windows array.
			if ( ! empty( $slot['time_windows'] ) && is_array( $slot['time_windows'] ) ) {
				foreach ( $slot['time_windows'] as $window ) {
					MeetingTypeAvailability::create(
						array(
							'meeting_type_id' => $meeting_type_id,
							'day_of_week'     => $day_of_week,
							'start_time'      => $window['start_time'],
							'end_time'        => $window['end_time'],
							'is_enabled'      => $is_enabled,
						)
					);
				}
			} else {
				// Flat format (single time window per row).
				MeetingTypeAvailability::create(
					array(
						'meeting_type_id' => $meeting_type_id,
						'day_of_week'     => $day_of_week,
						'start_time'      => $slot['start_time'],
						'end_time'        => $slot['end_time'],
						'is_enabled'      => $is_enabled,
					)
				);
			}
		}
	}

	/**
	 * Replace all date overrides for a meeting type.
	 *
	 * @param int   $meeting_type_id The meeting type ID.
	 * @param array $overrides Array of date override data.
	 *
	 * @return void
	 */
	public function syncDateOverrides( int $meeting_type_id, array $overrides ): void {
		MeetingTypeDateOverride::deleteWhere( array( 'meeting_type_id' => $meeting_type_id ) );

		foreach ( $overrides as $override ) {
			MeetingTypeDateOverride::create(
				array(
					'meeting_type_id' => $meeting_type_id,
					'override_date'   => $override['override_date'],
					'is_unavailable'  => $override['is_unavailable'] ?? false,
					'start_time'      => $override['start_time'] ?? null,
					'end_time'        => $override['end_time'] ?? null,
				)
			);
		}
	}

	/**
	 * Get all enabled availability windows for a meeting type.
	 *
	 * @param int $meeting_type_id The meeting type ID.
	 *
	 * @return array
	 */
	public function getAvailability( int $meeting_type_id ): array {
		return MeetingTypeAvailability::where( 'meeting_type_id', $meeting_type_id )
			->where( 'is_enabled', 1 )
			->get();
	}

	/**
	 * Get all availability windows (enabled and disabled) for a meeting type.
	 *
	 * @param int $meeting_type_id The meeting type ID.
	 *
	 * @return array
	 */
	public function getAllAvailability( int $meeting_type_id ): array {
		return MeetingTypeAvailability::where( 'meeting_type_id', $meeting_type_id )->get();
	}

	/**
	 * Get all date overrides for a meeting type.
	 *
	 * @param int $meeting_type_id The meeting type ID.
	 *
	 * @return array
	 */
	public function getDateOverrides( int $meeting_type_id ): array {
		return MeetingTypeDateOverride::where( 'meeting_type_id', $meeting_type_id )->get();
	}
}
