<?php
/**
 * Encounter 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\Encounter_Service;
use Care_API\Services\Permission_Service;
use Care_API\Utils\Input_Validator;
use Care_API\Utils\Error_Handler;

/**
 * Encounter Endpoints Class
 */
class Encounter_Endpoints {

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

	/**
	 * Register encounter REST routes.
	 */
	public static function register_routes() {
		// Get all encounters
		register_rest_route( self::NAMESPACE, '/encounters', array(
			'methods'             => WP_REST_Server::READABLE,
			'callback'            => array( __CLASS__, 'get_encounters' ),
			'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 encounters per page',
					'type'              => 'integer',
					'default'           => 10,
					'minimum'           => 1,
					'maximum'           => 100,
					'sanitize_callback' => 'absint',
				),
				'status' => array(
					'description' => 'Filter by encounter status',
					'type'        => 'string',
					'enum'        => array( 'scheduled', 'in_progress', 'completed', 'cancelled' ),
				),
				'patient_id' => array(
					'description'       => 'Filter by patient ID',
					'type'              => 'integer',
					'sanitize_callback' => 'absint',
				),
				'doctor_id' => array(
					'description'       => 'Filter by doctor ID',
					'type'              => 'integer',
					'sanitize_callback' => 'absint',
				),
				'appointment_id' => array(
					'description'       => 'Filter by appointment ID',
					'type'              => 'integer',
					'sanitize_callback' => 'absint',
				),
				'date_from' => array(
					'description' => 'Filter encounters from date (YYYY-MM-DD)',
					'type'        => 'string',
					'format'      => 'date',
				),
				'date_to' => array(
					'description' => 'Filter encounters to date (YYYY-MM-DD)',
					'type'        => 'string',
					'format'      => 'date',
				),
			),
		));

		// Create new encounter
		register_rest_route( self::NAMESPACE, '/encounters', array(
			'methods'             => WP_REST_Server::CREATABLE,
			'callback'            => array( __CLASS__, 'create_encounter' ),
			'permission_callback' => array( __CLASS__, 'check_create_permission' ),
			'args'                => array(
				'appointment_id' => array(
					'description'       => 'Related appointment ID',
					'type'              => 'integer',
					'required'          => true,
					'sanitize_callback' => 'absint',
				),
				'patient_id' => array(
					'description'       => 'Patient ID',
					'type'              => 'integer',
					'required'          => true,
					'sanitize_callback' => 'absint',
				),
				'doctor_id' => array(
					'description'       => 'Doctor ID',
					'type'              => 'integer',
					'required'          => true,
					'sanitize_callback' => 'absint',
				),
				'encounter_date' => array(
					'description' => 'Encounter date (YYYY-MM-DD HH:MM:SS)',
					'type'        => 'string',
					'required'    => true,
					'format'      => 'date-time',
				),
				'encounter_type' => array(
					'description'       => 'Type of encounter',
					'type'              => 'string',
					'required'          => true,
					'enum'              => array( 'consultation', 'follow_up', 'emergency', 'routine_check', 'procedure' ),
					'sanitize_callback' => 'sanitize_text_field',
				),
				'chief_complaint' => array(
					'description'       => 'Patient\'s chief complaint',
					'type'              => 'string',
					'sanitize_callback' => 'sanitize_textarea_field',
				),
				'present_illness' => array(
					'description'       => 'History of present illness',
					'type'              => 'string',
					'sanitize_callback' => 'sanitize_textarea_field',
				),
				'vital_signs' => array(
					'description' => 'Vital signs data',
					'type'        => 'object',
				),
				'clinical_notes' => array(
					'description'       => 'Clinical notes',
					'type'              => 'string',
					'sanitize_callback' => 'sanitize_textarea_field',
				),
			),
		));

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

		// Update encounter
		register_rest_route( self::NAMESPACE, '/encounters/(?P<id>\d+)', array(
			'methods'             => WP_REST_Server::EDITABLE,
			'callback'            => array( __CLASS__, 'update_encounter' ),
			'permission_callback' => array( __CLASS__, 'check_update_permission' ),
			'args'                => array(
				'id' => array(
					'description'       => 'Encounter ID',
					'type'              => 'integer',
					'required'          => true,
					'sanitize_callback' => 'absint',
				),
				'encounter_date' => array(
					'description' => 'Encounter date (YYYY-MM-DD HH:MM:SS)',
					'type'        => 'string',
					'format'      => 'date-time',
				),
				'encounter_type' => array(
					'description'       => 'Type of encounter',
					'type'              => 'string',
					'enum'              => array( 'consultation', 'follow_up', 'emergency', 'routine_check', 'procedure' ),
					'sanitize_callback' => 'sanitize_text_field',
				),
				'chief_complaint' => array(
					'description'       => 'Patient\'s chief complaint',
					'type'              => 'string',
					'sanitize_callback' => 'sanitize_textarea_field',
				),
				'present_illness' => array(
					'description'       => 'History of present illness',
					'type'              => 'string',
					'sanitize_callback' => 'sanitize_textarea_field',
				),
				'vital_signs' => array(
					'description' => 'Vital signs data',
					'type'        => 'object',
				),
				'clinical_notes' => array(
					'description'       => 'Clinical notes',
					'type'              => 'string',
					'sanitize_callback' => 'sanitize_textarea_field',
				),
				'soap_notes' => array(
					'description' => 'SOAP notes data',
					'type'        => 'object',
				),
				'status' => array(
					'description' => 'Encounter status',
					'type'        => 'string',
					'enum'        => array( 'scheduled', 'in_progress', 'completed', 'cancelled' ),
				),
			),
		));

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

		// Start encounter
		register_rest_route( self::NAMESPACE, '/encounters/(?P<id>\d+)/start', array(
			'methods'             => WP_REST_Server::CREATABLE,
			'callback'            => array( __CLASS__, 'start_encounter' ),
			'permission_callback' => array( __CLASS__, 'check_update_permission' ),
			'args'                => array(
				'id' => array(
					'description'       => 'Encounter ID',
					'type'              => 'integer',
					'required'          => true,
					'sanitize_callback' => 'absint',
				),
				'start_time' => array(
					'description' => 'Encounter start time (YYYY-MM-DD HH:MM:SS)',
					'type'        => 'string',
					'format'      => 'date-time',
				),
			),
		));

		// Complete/Finalize encounter
		register_rest_route( self::NAMESPACE, '/encounters/(?P<id>\d+)/complete', array(
			'methods'             => WP_REST_Server::CREATABLE,
			'callback'            => array( __CLASS__, 'complete_encounter' ),
			'permission_callback' => array( __CLASS__, 'check_update_permission' ),
			'args'                => array(
				'id' => array(
					'description'       => 'Encounter ID',
					'type'              => 'integer',
					'required'          => true,
					'sanitize_callback' => 'absint',
				),
				'soap_notes' => array(
					'description' => 'Final SOAP notes',
					'type'        => 'object',
					'required'    => true,
				),
				'diagnosis' => array(
					'description' => 'Diagnosis information',
					'type'        => 'object',
				),
				'treatment_plan' => array(
					'description'       => 'Treatment plan',
					'type'              => 'string',
					'sanitize_callback' => 'sanitize_textarea_field',
				),
				'follow_up_required' => array(
					'description' => 'Whether follow-up is required',
					'type'        => 'boolean',
					'default'     => false,
				),
				'follow_up_date' => array(
					'description' => 'Recommended follow-up date',
					'type'        => 'string',
					'format'      => 'date',
				),
			),
		));

		// Get encounter SOAP notes
		register_rest_route( self::NAMESPACE, '/encounters/(?P<id>\d+)/soap', array(
			'methods'             => WP_REST_Server::READABLE,
			'callback'            => array( __CLASS__, 'get_soap_notes' ),
			'permission_callback' => array( __CLASS__, 'check_read_permission' ),
			'args'                => array(
				'id' => array(
					'description'       => 'Encounter ID',
					'type'              => 'integer',
					'required'          => true,
					'sanitize_callback' => 'absint',
				),
			),
		));

		// Update encounter SOAP notes
		register_rest_route( self::NAMESPACE, '/encounters/(?P<id>\d+)/soap', array(
			'methods'             => WP_REST_Server::EDITABLE,
			'callback'            => array( __CLASS__, 'update_soap_notes' ),
			'permission_callback' => array( __CLASS__, 'check_update_permission' ),
			'args'                => array(
				'id' => array(
					'description'       => 'Encounter ID',
					'type'              => 'integer',
					'required'          => true,
					'sanitize_callback' => 'absint',
				),
				'soap_notes' => array(
					'description' => 'SOAP notes data',
					'type'        => 'object',
					'required'    => true,
				),
			),
		));

		// Get encounter vital signs
		register_rest_route( self::NAMESPACE, '/encounters/(?P<id>\d+)/vitals', array(
			'methods'             => WP_REST_Server::READABLE,
			'callback'            => array( __CLASS__, 'get_vital_signs' ),
			'permission_callback' => array( __CLASS__, 'check_read_permission' ),
			'args'                => array(
				'id' => array(
					'description'       => 'Encounter ID',
					'type'              => 'integer',
					'required'          => true,
					'sanitize_callback' => 'absint',
				),
			),
		));

		// Update encounter vital signs
		register_rest_route( self::NAMESPACE, '/encounters/(?P<id>\d+)/vitals', array(
			'methods'             => WP_REST_Server::EDITABLE,
			'callback'            => array( __CLASS__, 'update_vital_signs' ),
			'permission_callback' => array( __CLASS__, 'check_update_permission' ),
			'args'                => array(
				'id' => array(
					'description'       => 'Encounter ID',
					'type'              => 'integer',
					'required'          => true,
					'sanitize_callback' => 'absint',
				),
				'vital_signs' => array(
					'description' => 'Vital signs data',
					'type'        => 'object',
					'required'    => true,
				),
			),
		));

		// Search encounters
		register_rest_route( self::NAMESPACE, '/encounters/search', array(
			'methods'             => WP_REST_Server::READABLE,
			'callback'            => array( __CLASS__, 'search_encounters' ),
			'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( 'patient_name', 'doctor_name', 'chief_complaint', 'diagnosis' ),
					),
					'default' => array( 'patient_name', 'chief_complaint' ),
				),
				'limit' => array(
					'description'       => 'Maximum results to return',
					'type'              => 'integer',
					'default'           => 10,
					'minimum'           => 1,
					'maximum'           => 50,
					'sanitize_callback' => 'absint',
				),
			),
		));

		// Get encounter templates
		register_rest_route( self::NAMESPACE, '/encounters/templates', array(
			'methods'             => WP_REST_Server::READABLE,
			'callback'            => array( __CLASS__, 'get_encounter_templates' ),
			'permission_callback' => array( __CLASS__, 'check_read_permission' ),
			'args'                => array(
				'encounter_type' => array(
					'description'       => 'Filter by encounter type',
					'type'              => 'string',
					'enum'              => array( 'consultation', 'follow_up', 'emergency', 'routine_check', 'procedure' ),
					'sanitize_callback' => 'sanitize_text_field',
				),
				'specialty' => array(
					'description'       => 'Filter by medical specialty',
					'type'              => 'string',
					'sanitize_callback' => 'sanitize_text_field',
				),
			),
		));
	}

	/**
	 * Get encounters list.
	 */
	public static function get_encounters( 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
			$filters = array( 'status', 'patient_id', 'doctor_id', 'appointment_id', 'date_from', 'date_to' );
			foreach ( $filters as $filter ) {
				$value = $request->get_param( $filter );
				if ( $value ) {
					$args[$filter] = $value;
				}
			}

			$result = Encounter_Service::get_encounters( $args );

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

			$total_encounters = Encounter_Service::get_encounters_count( $args );
			$total_pages      = ceil( $total_encounters / $per_page );

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

			return $response;

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

	/**
	 * Create new encounter.
	 */
	public static function create_encounter( WP_REST_Request $request ) {
		try {
			$encounter_data = array(
				'appointment_id'   => $request->get_param( 'appointment_id' ),
				'patient_id'       => $request->get_param( 'patient_id' ),
				'doctor_id'        => $request->get_param( 'doctor_id' ),
				'encounter_date'   => $request->get_param( 'encounter_date' ),
				'encounter_type'   => $request->get_param( 'encounter_type' ),
				'chief_complaint'  => $request->get_param( 'chief_complaint' ),
				'present_illness'  => $request->get_param( 'present_illness' ),
				'vital_signs'      => $request->get_param( 'vital_signs' ),
				'clinical_notes'   => $request->get_param( 'clinical_notes' ),
			);

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

			$result = Encounter_Service::create_encounter( $encounter_data );

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

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

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

	/**
	 * Get specific encounter.
	 */
	public static function get_encounter( WP_REST_Request $request ) {
		try {
			$encounter_id = $request->get_param( 'id' );
			$result       = Encounter_Service::get_encounter( $encounter_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 encounter.
	 */
	public static function update_encounter( WP_REST_Request $request ) {
		try {
			$encounter_id = $request->get_param( 'id' );
			$update_data  = array();

			// Only include parameters that were actually sent
			$params = array(
				'encounter_date', 'encounter_type', 'chief_complaint',
				'present_illness', 'vital_signs', 'clinical_notes',
				'soap_notes', 'status'
			);

			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_encounter_data( $update_data, true );
			if ( is_wp_error( $validation_result ) ) {
				return Error_Handler::handle_service_error( $validation_result );
			}

			$result = Encounter_Service::update_encounter( $encounter_id, $update_data );

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

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

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

	/**
	 * Delete encounter.
	 */
	public static function delete_encounter( WP_REST_Request $request ) {
		try {
			$encounter_id = $request->get_param( 'id' );
			$force        = $request->get_param( 'force' );

			$result = Encounter_Service::delete_encounter( $encounter_id, $force );

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

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

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

	/**
	 * Start encounter.
	 */
	public static function start_encounter( WP_REST_Request $request ) {
		try {
			$encounter_id = $request->get_param( 'id' );
			$start_time   = $request->get_param( 'start_time' );

			$result = Encounter_Service::start_encounter( $encounter_id, $start_time );

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

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

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

	/**
	 * Complete encounter.
	 */
	public static function complete_encounter( WP_REST_Request $request ) {
		try {
			$encounter_id = $request->get_param( 'id' );
			$completion_data = array(
				'soap_notes'         => $request->get_param( 'soap_notes' ),
				'diagnosis'          => $request->get_param( 'diagnosis' ),
				'treatment_plan'     => $request->get_param( 'treatment_plan' ),
				'follow_up_required' => $request->get_param( 'follow_up_required' ),
				'follow_up_date'     => $request->get_param( 'follow_up_date' ),
			);

			$result = Encounter_Service::finalize_encounter( $encounter_id, $completion_data );

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

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

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

	/**
	 * Get SOAP notes.
	 */
	public static function get_soap_notes( WP_REST_Request $request ) {
		try {
			$encounter_id = $request->get_param( 'id' );
			$result       = Encounter_Service::get_soap_notes( $encounter_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 SOAP notes.
	 */
	public static function update_soap_notes( WP_REST_Request $request ) {
		try {
			$encounter_id = $request->get_param( 'id' );
			$soap_notes   = $request->get_param( 'soap_notes' );

			$result = Encounter_Service::update_soap_notes( $encounter_id, $soap_notes );

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

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

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

	/**
	 * Get vital signs.
	 */
	public static function get_vital_signs( WP_REST_Request $request ) {
		try {
			$encounter_id = $request->get_param( 'id' );
			$result       = Encounter_Service::get_vital_signs( $encounter_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 vital signs.
	 */
	public static function update_vital_signs( WP_REST_Request $request ) {
		try {
			$encounter_id = $request->get_param( 'id' );
			$vital_signs  = $request->get_param( 'vital_signs' );

			$result = Encounter_Service::update_vital_signs( $encounter_id, $vital_signs );

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

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

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

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

			$result = Encounter_Service::search_encounters( $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 encounter templates.
	 */
	public static function get_encounter_templates( WP_REST_Request $request ) {
		try {
			$encounter_type = $request->get_param( 'encounter_type' );
			$specialty      = $request->get_param( 'specialty' );

			$result = Encounter_Service::get_encounter_templates( $encounter_type, $specialty );

			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 );
		}
	}

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

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

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

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