<?php
/**
 * Doctor REST API Endpoints
 *
 * @package Care_API
 */

namespace Care_API\Endpoints;

use WP_REST_Server;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;
use Care_API\Services\Database\Doctor_Service;
use Care_API\Services\Permission_Service;
use Care_API\Utils\Input_Validator;
use Care_API\Utils\Error_Handler;

/**
 * Doctor Endpoints Class
 */
class Doctor_Endpoints {

	/**
	 * API namespace
	 *
	 * @var string
	 */
	private const NAMESPACE = 'care/v1';

	/**
	 * Register doctor REST routes.
	 */
	public static function register_routes() {
		// Get all doctors
		register_rest_route( self::NAMESPACE, '/doctors', array(
			'methods'             => WP_REST_Server::READABLE,
			'callback'            => array( __CLASS__, 'get_doctors' ),
			'permission_callback' => array( __CLASS__, 'check_read_permission' ),
			'args'                => array(
				'page' => array(
					'description'       => 'Page number for pagination',
					'type'              => 'integer',
					'default'           => 1,
					'minimum'           => 1,
					'sanitize_callback' => 'absint',
				),
				'per_page' => array(
					'description'       => 'Number of doctors per page',
					'type'              => 'integer',
					'default'           => 10,
					'minimum'           => 1,
					'maximum'           => 100,
					'sanitize_callback' => 'absint',
				),
				'status' => array(
					'description' => 'Filter by doctor status',
					'type'        => 'string',
					'enum'        => array( 'active', 'inactive', 'suspended' ),
				),
				'specialty' => array(
					'description'       => 'Filter by specialty',
					'type'              => 'string',
					'sanitize_callback' => 'sanitize_text_field',
				),
				'clinic_id' => array(
					'description'       => 'Filter by clinic ID',
					'type'              => 'integer',
					'sanitize_callback' => 'absint',
				),
			),
		));

		// Create new doctor
		register_rest_route( self::NAMESPACE, '/doctors', array(
			'methods'             => WP_REST_Server::CREATABLE,
			'callback'            => array( __CLASS__, 'create_doctor' ),
			'permission_callback' => array( __CLASS__, 'check_create_permission' ),
			'args'                => array(
				'first_name' => array(
					'description'       => 'Doctor first name',
					'type'              => 'string',
					'required'          => true,
					'sanitize_callback' => 'sanitize_text_field',
					'validate_callback' => array( __CLASS__, 'validate_required_string' ),
				),
				'last_name' => array(
					'description'       => 'Doctor last name',
					'type'              => 'string',
					'required'          => true,
					'sanitize_callback' => 'sanitize_text_field',
					'validate_callback' => array( __CLASS__, 'validate_required_string' ),
				),
				'email' => array(
					'description'       => 'Doctor email address',
					'type'              => 'string',
					'required'          => true,
					'format'            => 'email',
					'sanitize_callback' => 'sanitize_email',
					'validate_callback' => array( __CLASS__, 'validate_email' ),
				),
				'phone' => array(
					'description'       => 'Doctor phone number',
					'type'              => 'string',
					'required'          => true,
					'sanitize_callback' => 'sanitize_text_field',
				),
				'specialty' => array(
					'description'       => 'Doctor medical specialty',
					'type'              => 'string',
					'required'          => true,
					'sanitize_callback' => 'sanitize_text_field',
				),
				'license_number' => array(
					'description'       => 'Medical license number',
					'type'              => 'string',
					'required'          => true,
					'sanitize_callback' => 'sanitize_text_field',
				),
				'clinic_id' => array(
					'description'       => 'Primary clinic ID',
					'type'              => 'integer',
					'required'          => true,
					'sanitize_callback' => 'absint',
				),
				'qualifications' => array(
					'description' => 'Doctor qualifications',
					'type'        => 'string',
					'sanitize_callback' => 'sanitize_textarea_field',
				),
				'experience_years' => array(
					'description'       => 'Years of experience',
					'type'              => 'integer',
					'minimum'           => 0,
					'sanitize_callback' => 'absint',
				),
				'consultation_fee' => array(
					'description' => 'Consultation fee',
					'type'        => 'number',
					'minimum'     => 0,
				),
				'schedule' => array(
					'description' => 'Doctor availability schedule',
					'type'        => 'object',
				),
			),
		));

		// Get specific doctor
		register_rest_route( self::NAMESPACE, '/doctors/(?P<id>\d+)', array(
			'methods'             => WP_REST_Server::READABLE,
			'callback'            => array( __CLASS__, 'get_doctor' ),
			'permission_callback' => array( __CLASS__, 'check_read_permission' ),
			'args'                => array(
				'id' => array(
					'description'       => 'Doctor ID',
					'type'              => 'integer',
					'required'          => true,
					'sanitize_callback' => 'absint',
				),
			),
		));

		// Update doctor
		register_rest_route( self::NAMESPACE, '/doctors/(?P<id>\d+)', array(
			'methods'             => WP_REST_Server::EDITABLE,
			'callback'            => array( __CLASS__, 'update_doctor' ),
			'permission_callback' => array( __CLASS__, 'check_update_permission' ),
			'args'                => array(
				'id' => array(
					'description'       => 'Doctor ID',
					'type'              => 'integer',
					'required'          => true,
					'sanitize_callback' => 'absint',
				),
				'first_name' => array(
					'description'       => 'Doctor first name',
					'type'              => 'string',
					'sanitize_callback' => 'sanitize_text_field',
				),
				'last_name' => array(
					'description'       => 'Doctor last name',
					'type'              => 'string',
					'sanitize_callback' => 'sanitize_text_field',
				),
				'email' => array(
					'description'       => 'Doctor email address',
					'type'              => 'string',
					'format'            => 'email',
					'sanitize_callback' => 'sanitize_email',
				),
				'phone' => array(
					'description'       => 'Doctor phone number',
					'type'              => 'string',
					'sanitize_callback' => 'sanitize_text_field',
				),
				'specialty' => array(
					'description'       => 'Doctor medical specialty',
					'type'              => 'string',
					'sanitize_callback' => 'sanitize_text_field',
				),
				'license_number' => array(
					'description'       => 'Medical license number',
					'type'              => 'string',
					'sanitize_callback' => 'sanitize_text_field',
				),
				'qualifications' => array(
					'description' => 'Doctor qualifications',
					'type'        => 'string',
					'sanitize_callback' => 'sanitize_textarea_field',
				),
				'experience_years' => array(
					'description'       => 'Years of experience',
					'type'              => 'integer',
					'minimum'           => 0,
					'sanitize_callback' => 'absint',
				),
				'consultation_fee' => array(
					'description' => 'Consultation fee',
					'type'        => 'number',
					'minimum'     => 0,
				),
				'status' => array(
					'description' => 'Doctor status',
					'type'        => 'string',
					'enum'        => array( 'active', 'inactive', 'suspended' ),
				),
				'schedule' => array(
					'description' => 'Doctor availability schedule',
					'type'        => 'object',
				),
			),
		));

		// Delete doctor
		register_rest_route( self::NAMESPACE, '/doctors/(?P<id>\d+)', array(
			'methods'             => WP_REST_Server::DELETABLE,
			'callback'            => array( __CLASS__, 'delete_doctor' ),
			'permission_callback' => array( __CLASS__, 'check_delete_permission' ),
			'args'                => array(
				'id' => array(
					'description'       => 'Doctor ID',
					'type'              => 'integer',
					'required'          => true,
					'sanitize_callback' => 'absint',
				),
				'force' => array(
					'description' => 'Force delete (bypass soft delete)',
					'type'        => 'boolean',
					'default'     => false,
				),
			),
		));

		// Search doctors
		register_rest_route( self::NAMESPACE, '/doctors/search', array(
			'methods'             => WP_REST_Server::READABLE,
			'callback'            => array( __CLASS__, 'search_doctors' ),
			'permission_callback' => array( __CLASS__, 'check_read_permission' ),
			'args'                => array(
				'q' => array(
					'description'       => 'Search query',
					'type'              => 'string',
					'required'          => true,
					'sanitize_callback' => 'sanitize_text_field',
				),
				'fields' => array(
					'description' => 'Fields to search in',
					'type'        => 'array',
					'items'       => array(
						'type' => 'string',
						'enum' => array( 'name', 'email', 'specialty', 'license_number' ),
					),
					'default' => array( 'name', 'specialty' ),
				),
				'limit' => array(
					'description'       => 'Maximum results to return',
					'type'              => 'integer',
					'default'           => 10,
					'minimum'           => 1,
					'maximum'           => 50,
					'sanitize_callback' => 'absint',
				),
			),
		));

		// Get doctor schedule
		register_rest_route( self::NAMESPACE, '/doctors/(?P<id>\d+)/schedule', array(
			'methods'             => WP_REST_Server::READABLE,
			'callback'            => array( __CLASS__, 'get_doctor_schedule' ),
			'permission_callback' => array( __CLASS__, 'check_read_permission' ),
			'args'                => array(
				'id' => array(
					'description'       => 'Doctor ID',
					'type'              => 'integer',
					'required'          => true,
					'sanitize_callback' => 'absint',
				),
				'date_from' => array(
					'description' => 'Start date (YYYY-MM-DD)',
					'type'        => 'string',
					'format'      => 'date',
				),
				'date_to' => array(
					'description' => 'End date (YYYY-MM-DD)',
					'type'        => 'string',
					'format'      => 'date',
				),
			),
		));

		// Update doctor schedule
		register_rest_route( self::NAMESPACE, '/doctors/(?P<id>\d+)/schedule', array(
			'methods'             => WP_REST_Server::EDITABLE,
			'callback'            => array( __CLASS__, 'update_doctor_schedule' ),
			'permission_callback' => array( __CLASS__, 'check_update_permission' ),
			'args'                => array(
				'id' => array(
					'description'       => 'Doctor ID',
					'type'              => 'integer',
					'required'          => true,
					'sanitize_callback' => 'absint',
				),
				'schedule' => array(
					'description' => 'Doctor schedule data',
					'type'        => 'object',
					'required'    => true,
				),
			),
		));

		// Get doctor statistics
		register_rest_route( self::NAMESPACE, '/doctors/(?P<id>\d+)/stats', array(
			'methods'             => WP_REST_Server::READABLE,
			'callback'            => array( __CLASS__, 'get_doctor_stats' ),
			'permission_callback' => array( __CLASS__, 'check_read_permission' ),
			'args'                => array(
				'id' => array(
					'description'       => 'Doctor ID',
					'type'              => 'integer',
					'required'          => true,
					'sanitize_callback' => 'absint',
				),
				'period' => array(
					'description' => 'Statistics period',
					'type'        => 'string',
					'enum'        => array( 'week', 'month', 'quarter', 'year' ),
					'default'     => 'month',
				),
			),
		));

		// Bulk operations
		register_rest_route( self::NAMESPACE, '/doctors/bulk', array(
			'methods'             => WP_REST_Server::CREATABLE,
			'callback'            => array( __CLASS__, 'bulk_operations' ),
			'permission_callback' => array( __CLASS__, 'check_create_permission' ),
			'args'                => array(
				'action' => array(
					'description' => 'Bulk action to perform',
					'type'        => 'string',
					'required'    => true,
					'enum'        => array( 'activate', 'deactivate', 'suspend', 'delete' ),
				),
				'doctor_ids' => array(
					'description' => 'Array of doctor IDs',
					'type'        => 'array',
					'required'    => true,
					'items'       => array(
						'type' => 'integer',
					),
					'minItems' => 1,
				),
			),
		));
	}

	/**
	 * Get doctors list.
	 */
	public static function get_doctors( WP_REST_Request $request ) {
		try {
			$page     = $request->get_param( 'page' );
			$per_page = $request->get_param( 'per_page' );
			$offset   = ( $page - 1 ) * $per_page;

			$args = array(
				'limit'  => $per_page,
				'offset' => $offset,
			);

			// Add filters
			$status = $request->get_param( 'status' );
			if ( $status ) {
				$args['status'] = $status;
			}

			$specialty = $request->get_param( 'specialty' );
			if ( $specialty ) {
				$args['specialty'] = $specialty;
			}

			$clinic_id = $request->get_param( 'clinic_id' );
			if ( $clinic_id ) {
				$args['clinic_id'] = $clinic_id;
			}

			$result = Doctor_Service::get_doctors( $args );

			if ( is_wp_error( $result ) ) {
				return Error_Handler::handle_service_error( $result );
			}

			$total_doctors = Doctor_Service::get_doctors_count( $args );
			$total_pages   = ceil( $total_doctors / $per_page );

			$response = new WP_REST_Response( array(
				'success' => true,
				'data'    => $result,
				'meta'    => array(
					'total'       => $total_doctors,
					'pages'       => $total_pages,
					'current'     => $page,
					'per_page'    => $per_page,
				),
			), 200 );

			return $response;

		} catch ( Exception $e ) {
			return Error_Handler::handle_exception( $e );
		}
	}

	/**
	 * Create new doctor.
	 */
	public static function create_doctor( WP_REST_Request $request ) {
		try {
			$doctor_data = array(
				'first_name'      => $request->get_param( 'first_name' ),
				'last_name'       => $request->get_param( 'last_name' ),
				'email'           => $request->get_param( 'email' ),
				'phone'           => $request->get_param( 'phone' ),
				'specialty'       => $request->get_param( 'specialty' ),
				'license_number'  => $request->get_param( 'license_number' ),
				'clinic_id'       => $request->get_param( 'clinic_id' ),
				'qualifications'  => $request->get_param( 'qualifications' ),
				'experience_years' => $request->get_param( 'experience_years' ),
				'consultation_fee' => $request->get_param( 'consultation_fee' ),
				'schedule'        => $request->get_param( 'schedule' ),
			);

			// Validate input data
			$validation_result = Input_Validator::validate_doctor_data( $doctor_data );
			if ( is_wp_error( $validation_result ) ) {
				return Error_Handler::handle_service_error( $validation_result );
			}

			$result = Doctor_Service::create_doctor( $doctor_data );

			if ( is_wp_error( $result ) ) {
				return Error_Handler::handle_service_error( $result );
			}

			return new WP_REST_Response( array(
				'success' => true,
				'message' => 'Doctor created successfully',
				'data'    => $result,
			), 201 );

		} catch ( Exception $e ) {
			return Error_Handler::handle_exception( $e );
		}
	}

	/**
	 * Get specific doctor.
	 */
	public static function get_doctor( WP_REST_Request $request ) {
		try {
			$doctor_id = $request->get_param( 'id' );
			$result    = Doctor_Service::get_doctor( $doctor_id );

			if ( is_wp_error( $result ) ) {
				return Error_Handler::handle_service_error( $result );
			}

			return new WP_REST_Response( array(
				'success' => true,
				'data'    => $result,
			), 200 );

		} catch ( Exception $e ) {
			return Error_Handler::handle_exception( $e );
		}
	}

	/**
	 * Update doctor.
	 */
	public static function update_doctor( WP_REST_Request $request ) {
		try {
			$doctor_id   = $request->get_param( 'id' );
			$update_data = array();

			// Only include parameters that were actually sent
			$params = array(
				'first_name', 'last_name', 'email', 'phone', 'specialty',
				'license_number', 'qualifications', 'experience_years',
				'consultation_fee', 'status', 'schedule'
			);

			foreach ( $params as $param ) {
				if ( $request->has_param( $param ) ) {
					$update_data[$param] = $request->get_param( $param );
				}
			}

			if ( empty( $update_data ) ) {
				return new WP_REST_Response( array(
					'success' => false,
					'message' => 'No data provided for update',
				), 400 );
			}

			// Validate input data
			$validation_result = Input_Validator::validate_doctor_data( $update_data, true );
			if ( is_wp_error( $validation_result ) ) {
				return Error_Handler::handle_service_error( $validation_result );
			}

			$result = Doctor_Service::update_doctor( $doctor_id, $update_data );

			if ( is_wp_error( $result ) ) {
				return Error_Handler::handle_service_error( $result );
			}

			return new WP_REST_Response( array(
				'success' => true,
				'message' => 'Doctor updated successfully',
				'data'    => $result,
			), 200 );

		} catch ( Exception $e ) {
			return Error_Handler::handle_exception( $e );
		}
	}

	/**
	 * Delete doctor.
	 */
	public static function delete_doctor( WP_REST_Request $request ) {
		try {
			$doctor_id = $request->get_param( 'id' );
			$force     = $request->get_param( 'force' );

			$result = Doctor_Service::delete_doctor( $doctor_id, $force );

			if ( is_wp_error( $result ) ) {
				return Error_Handler::handle_service_error( $result );
			}

			return new WP_REST_Response( array(
				'success' => true,
				'message' => $force ? 'Doctor permanently deleted' : 'Doctor deactivated successfully',
				'data'    => $result,
			), 200 );

		} catch ( Exception $e ) {
			return Error_Handler::handle_exception( $e );
		}
	}

	/**
	 * Search doctors.
	 */
	public static function search_doctors( WP_REST_Request $request ) {
		try {
			$query  = $request->get_param( 'q' );
			$fields = $request->get_param( 'fields' );
			$limit  = $request->get_param( 'limit' );

			$result = Doctor_Service::search_doctors( $query, $fields, $limit );

			if ( is_wp_error( $result ) ) {
				return Error_Handler::handle_service_error( $result );
			}

			return new WP_REST_Response( array(
				'success' => true,
				'data'    => $result,
				'meta'    => array(
					'query'   => $query,
					'fields'  => $fields,
					'results' => count( $result ),
				),
			), 200 );

		} catch ( Exception $e ) {
			return Error_Handler::handle_exception( $e );
		}
	}

	/**
	 * Get doctor schedule.
	 */
	public static function get_doctor_schedule( WP_REST_Request $request ) {
		try {
			$doctor_id  = $request->get_param( 'id' );
			$date_from  = $request->get_param( 'date_from' );
			$date_to    = $request->get_param( 'date_to' );

			$result = Doctor_Service::get_doctor_schedule( $doctor_id, $date_from, $date_to );

			if ( is_wp_error( $result ) ) {
				return Error_Handler::handle_service_error( $result );
			}

			return new WP_REST_Response( array(
				'success' => true,
				'data'    => $result,
			), 200 );

		} catch ( Exception $e ) {
			return Error_Handler::handle_exception( $e );
		}
	}

	/**
	 * Update doctor schedule.
	 */
	public static function update_doctor_schedule( WP_REST_Request $request ) {
		try {
			$doctor_id = $request->get_param( 'id' );
			$schedule  = $request->get_param( 'schedule' );

			$result = Doctor_Service::update_doctor_schedule( $doctor_id, $schedule );

			if ( is_wp_error( $result ) ) {
				return Error_Handler::handle_service_error( $result );
			}

			return new WP_REST_Response( array(
				'success' => true,
				'message' => 'Doctor schedule updated successfully',
				'data'    => $result,
			), 200 );

		} catch ( Exception $e ) {
			return Error_Handler::handle_exception( $e );
		}
	}

	/**
	 * Get doctor statistics.
	 */
	public static function get_doctor_stats( WP_REST_Request $request ) {
		try {
			$doctor_id = $request->get_param( 'id' );
			$period    = $request->get_param( 'period' );

			$result = Doctor_Service::get_doctor_statistics( $doctor_id, $period );

			if ( is_wp_error( $result ) ) {
				return Error_Handler::handle_service_error( $result );
			}

			return new WP_REST_Response( array(
				'success' => true,
				'data'    => $result,
			), 200 );

		} catch ( Exception $e ) {
			return Error_Handler::handle_exception( $e );
		}
	}

	/**
	 * Handle bulk operations.
	 */
	public static function bulk_operations( WP_REST_Request $request ) {
		try {
			$action     = $request->get_param( 'action' );
			$doctor_ids = $request->get_param( 'doctor_ids' );

			$result = Doctor_Service::bulk_update_doctors( $doctor_ids, $action );

			if ( is_wp_error( $result ) ) {
				return Error_Handler::handle_service_error( $result );
			}

			return new WP_REST_Response( array(
				'success' => true,
				'message' => sprintf( 'Bulk operation "%s" completed successfully', $action ),
				'data'    => $result,
			), 200 );

		} catch ( Exception $e ) {
			return Error_Handler::handle_exception( $e );
		}
	}

	/**
	 * Check read permission.
	 */
	public static function check_read_permission( WP_REST_Request $request ) {
		return Permission_Service::can_read_doctors();
	}

	/**
	 * Check create permission.
	 */
	public static function check_create_permission( WP_REST_Request $request ) {
		return Permission_Service::can_manage_doctors();
	}

	/**
	 * Check update permission.
	 */
	public static function check_update_permission( WP_REST_Request $request ) {
		$doctor_id = $request->get_param( 'id' );
		return Permission_Service::can_edit_doctor( $doctor_id );
	}

	/**
	 * Check delete permission.
	 */
	public static function check_delete_permission( WP_REST_Request $request ) {
		$doctor_id = $request->get_param( 'id' );
		return Permission_Service::can_delete_doctor( $doctor_id );
	}

	/**
	 * Validate required string parameter.
	 */
	public static function validate_required_string( $value, $request, $param ) {
		if ( empty( $value ) || ! is_string( $value ) ) {
			return new WP_Error( 'invalid_param', sprintf( 'Parameter "%s" is required and must be a non-empty string.', $param ) );
		}
		return true;
	}

	/**
	 * Validate email parameter.
	 */
	public static function validate_email( $value, $request, $param ) {
		if ( ! is_email( $value ) ) {
			return new WP_Error( 'invalid_email', 'Please provide a valid email address.' );
		}
		return true;
	}
}