<?php
/**
 * RadiusBooking API Route Registrar
 *
 * This class is responsible for registering API routes dynamically with the WordPress REST API.
 * It supports CRUD operations and allows for middleware to be applied globally or per route.
 *
 * @package RadiusTheme\RadiusBooking\Core\Api\Routes
 */

namespace RadiusTheme\RadiusBooking\Resources;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}
use RadiusTheme\RadiusBooking\Abstracts\BaseResource;
use RadiusTheme\RadiusBooking\Helpers\SettingsHelper;
use RadiusTheme\RadiusBooking\Models\Location;
use RadiusTheme\RadiusBooking\Repositories\BookingRepository;
use RadiusTheme\RadiusBooking\Repositories\PaymentRepository;
use RadiusTheme\RadiusBooking\Repositories\UserRepository;
use RadiusTheme\RadiusBooking\Services\EmployeeServices\UserWeekdayDataService;

/**
 * Api/Resources/UserResource.php
 * User resource transformer
 *
 * @package RadiusTheme\RadiusBooking\Resources
 */
class UserResource extends BaseResource {

	/**
	 * Transform a User model into an API-friendly array.
	 *
	 * @param object $user The User model instance.
	 *
	 * @return array Transformed user data.
	 */
	public function transform( $user ): array {
		$data = array(
			'id'                 => $user->id,
			'user_type'          => $user->user_type,
			'email'              => $user->email,
			'status'             => $user->status,
			'created_at'         => $user->created_at,
			'updated_at'         => $user->updated_at,
			'profile'            => $this->getProfileData( $user ),
			'total_appointments' => $this->getTotalAppointments( $user->id ),
			'total_spent'        => $this->getTotalSpend( $user->id ),
			'links'              => $this->getResourceLinks( $user ),
		);

		if ( $user->get_type() === 'employee' ) {
			$data['services']     = $this->getEmployeeServices( $user->id );
			$data['days_off']     = $this->getDaysOff( $user->id );
			$data['weekdays']     = ( new UserWeekdayDataService() )->getUserWeekdays( $user->id );
			$data['special_days'] = ( new UserRepository() )->getUserSpecialDays( $user->id );
			$data['currency']     = array(
				'currency_symbol' => get_rtrb_currency_symbol(),
				'currency'        => get_rtrb_currency(),
			);
			$data['phone_settings'] = SettingsHelper::get_setting( 'phone' );
		}

		return $data;
	}

	/**
	 * Retrieves the total number of appointments for a given user.
	 *
	 * @param int $userId The ID of the user whose appointments are to be retrieved.
	 *
	 * @return mixed The total number of appointments for the specified user.
	 */
	private function getTotalAppointments( int $userId ) {
		return ( new BookingRepository() )->getCustomerBookings( $userId );
	}

	/**
	 * Retrieves the total spending amount for a specific user.
	 *
	 * @param int $userId The unique identifier of the user.
	 *
	 * @return float The total amount spent by the user.
	 */
	private function getTotalSpend( int $userId ) {
		return ( new PaymentRepository() )->getCustomerTotalPaymentPrice( $userId );
	}

	/**
	 *
	 * Retrieves the list of days off for a specified user.
	 *
	 * @param int $userId The unique identifier of the user.
	 *
	 * @return array An array containing the user's days off.
	 */
	private function getDaysOff( int $userId ): array {
		return ( new UserRepository() )->getUserDaysOff( $userId );
	}

	/**
	 * Retrieves profile data for the given user, including additional details such as image URL, location,
	 * and associated WordPress user data if available.
	 *
	 * @param object $user The user object containing profile information.
	 *
	 * @return object An object representing the profile data. Returns an empty object if no profile is found.
	 */
	private function getProfileData( $user ): object {
		$profile = $this->whenLoaded( 'profile', $user ) ?? $user->profile;
		if ( ! $profile ) {
			return (object) array();
		}
		if ( $profile->image_id ) {
			$profile->image_full_path = ( new UserRepository() )->getImageUrl( $user->profile->id );

		} else {
			$profile->image_full_path = '';
		}

		if ( $profile->location_id ) {
			$profile->location = $this->getLocationData( $profile->location_id );
		}
		if ( $profile->wp_user_id ) {
			$userData           = get_userdata( $profile->wp_user_id );
			if(!empty($userData)){
				$profile->wp_user[] = array(
					'id'         => $userData->ID,
					'username'   => $userData->user_login,
					'email'      => $userData->user_email,
					'first_name' => $userData->first_name,
					'last_name'  => $userData->last_name,
				);
			}

		} else {
			$profile->wp_user = null;
		}

		return $profile;
	}

	/**
	 * Retrieves location data for a specific location ID.
	 *
	 * @param int $locationId The ID of the location to retrieve data for.
	 *
	 * @return array An associative array containing the location data, including 'id' and 'name'. Returns an empty array if the location is not found.
	 */
	private function getLocationData( int $locationId ): array {
		$location = Location::find( $locationId );
		if ( ! $location ) {
			return array();
		}

		return array(
			'id'   => $location->id,
			'name' => $location->name,
		);
	}

	/**
	 * Retrieves resource links for the given user.
	 *
	 * @param object $user The user object containing user information.
	 *
	 * @return array An associative array of resource links, including a self link.
	 */
	private function getResourceLinks( $user ): array {
		return array(
			'self' => get_rest_url( null, 'radius-booking/v1/users/' . $user->id ),
		);
	}

	/**
	 * Retrieves the services associated with a specific employee based on their user ID.
	 *
	 * @param int $userId The ID of the user whose services are to be retrieved.
	 *
	 * @return array An array of services associated with the given user ID.
	 */
	private function getEmployeeServices( int $userId ): array {
		return ( new UserRepository() )->getUserServices( $userId );
	}
}
