<?php

namespace SugarCalendarBookings\Abilities\Appointments;

use SugarCalendarBookings\Abilities\AbstractAbility;
use SugarCalendarBookings\Appointments\AppointmentModel;
use WP_Error;

/**
 * Ability: get a single appointment by ID with full detail.
 *
 * @since 1.5.0
 */
class GetAppointmentAbility extends AbstractAbility {

	/**
	 * Ability slug, without the namespace prefix.
	 *
	 * @since 1.5.0
	 *
	 * @return string
	 */
	public function get_name(): string {

		return 'get-appointment';
	}

	/**
	 * Human-readable label.
	 *
	 * @since 1.5.0
	 *
	 * @return string
	 */
	public function get_label(): string {

		return esc_html__( 'Get Appointment', 'sugar-calendar-bookings-scheduling-appointments-lite' );
	}

	/**
	 * Human-readable description.
	 *
	 * @since 1.5.0
	 *
	 * @return string
	 */
	public function get_description(): string {

		return esc_html__( 'Get a single booking by ID, including payments and activity log.', 'sugar-calendar-bookings-scheduling-appointments-lite' );
	}

	/**
	 * Input schema.
	 *
	 * @since 1.5.0
	 *
	 * @return array
	 */
	public function get_input_schema(): array {

		return [
			'type'       => 'object',
			'properties' => self::SCHEMA_ID,
			'required'   => [ 'id' ],
		];
	}

	/**
	 * Output schema.
	 *
	 * @since 1.5.0
	 *
	 * @return array
	 */
	public function get_output_schema(): array {

		return [
			'type' => 'object',
		];
	}

	/**
	 * Resolve the appointment and return its full body.
	 *
	 * @since 1.5.0
	 *
	 * @param mixed $input Input data.
	 *
	 * @return array|WP_Error
	 */
	public function execute( $input ) {

		$args = $this->normalize_input( $input );
		$id   = isset( $args['id'] ) ? (int) $args['id'] : 0;

		if ( $id <= 0 ) {
			return $this->not_found_error(
				esc_html__( 'Appointment not found.', 'sugar-calendar-bookings-scheduling-appointments-lite' )
			);
		}

		$appointment = AppointmentModel::query()
			->with(
				[
					'service'       => static fn( $q ) => $q->select( [ 'id', 'name', 'color', 'duration', 'price' ] ),
					'customer'      => static fn( $q ) => $q->select( [ 'id', 'name', 'email', 'phone' ] ),
					'employee'      => static fn( $q ) => $q->select( [ 'id', 'name', 'email' ] ),
					'location'      => static fn( $q ) => $q->select( [ 'id', 'name', 'address', 'city', 'country_code', 'timezone' ] ),
					'meta'          => static fn( $q ) => $q->where( 'meta_key', 'IN', [ 'online_location', 'customer_timezone', 'internal_notes', 'customer_notes', 'ignore_availability' ], '%s' ),
					'payments'      => static fn( $q ) => $q->select( [ 'id', 'status', 'subtotal_amount', 'total_amount', 'currency', 'gateway', 'mode', 'transaction_id', 'created_at' ] )->order_by( 'created_at', 'ASC' ),
					'notes'         => static fn( $q ) => $q->order_by( 'created_at', 'ASC' ),
					'activity_logs' => static fn( $q ) => $q->order_by( 'created_at', 'ASC' ),
				]
			)
			->where( 'appointments.id', '=', $id, '%d' )
			->first();

		if ( ! $appointment ) {
			return $this->not_found_error(
				esc_html__( 'Appointment not found.', 'sugar-calendar-bookings-scheduling-appointments-lite' )
			);
		}

		return $this->formatter()->appointment( $appointment, true );
	}
}
