<?php
/**
 * Appointment REST API Endpoints
 *
 * Handles all appointment-related REST API endpoints
 *
 * @package Care_API
 * @subpackage Endpoints
 * @version    1.0.0
 * @author     Descomplicar® <dev@descomplicar.pt>
 * @link       https://descomplicar.pt
 * @since      1.0.0
 */

namespace Care_API\Endpoints;

use Care_API\Services\Database\Appointment_Service;
use Care_API\Services\Auth_Service;
use Care_API\Utils\Input_Validator;
use Care_API\Utils\Error_Handler;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

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

/**
 * Class Appointment_Endpoints
 *
 * REST API endpoints for appointment management
 *
 * @since 1.0.0
 */
class Appointment_Endpoints {

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

    /**
     * Register all appointment endpoints
     *
     * @since 1.0.0
     */
    public static function register_routes() {
        // Get appointments (list with filters)
        register_rest_route( self::NAMESPACE, '/appointments', array(
            'methods' => 'GET',
            'callback' => array( self::class, 'get_appointments' ),
            'permission_callback' => array( Auth_Service::class, 'check_authentication' ),
            'args' => self::get_appointments_args()
        ) );

        // Create appointment
        register_rest_route( self::NAMESPACE, '/appointments', array(
            'methods' => 'POST',
            'callback' => array( self::class, 'create_appointment' ),
            'permission_callback' => array( Auth_Service::class, 'check_authentication' ),
            'args' => self::get_create_appointment_args()
        ) );

        // Get single appointment
        register_rest_route( self::NAMESPACE, '/appointments/(?P<id>\d+)', array(
            'methods' => 'GET',
            'callback' => array( self::class, 'get_appointment' ),
            'permission_callback' => array( Auth_Service::class, 'check_authentication' ),
            'args' => array(
                'id' => array(
                    'required' => true,
                    'validate_callback' => function( $param ) {
                        return is_numeric( $param );
                    },
                    'sanitize_callback' => 'absint'
                )
            )
        ) );

        // Update appointment
        register_rest_route( self::NAMESPACE, '/appointments/(?P<id>\d+)', array(
            'methods' => 'PUT',
            'callback' => array( self::class, 'update_appointment' ),
            'permission_callback' => array( Auth_Service::class, 'check_authentication' ),
            'args' => self::get_update_appointment_args()
        ) );

        // Cancel appointment
        register_rest_route( self::NAMESPACE, '/appointments/(?P<id>\d+)/cancel', array(
            'methods' => 'POST',
            'callback' => array( self::class, 'cancel_appointment' ),
            'permission_callback' => array( Auth_Service::class, 'check_authentication' ),
            'args' => array(
                'id' => array(
                    'required' => true,
                    'validate_callback' => function( $param ) {
                        return is_numeric( $param );
                    },
                    'sanitize_callback' => 'absint'
                ),
                'reason' => array(
                    'validate_callback' => 'rest_validate_request_arg',
                    'sanitize_callback' => 'sanitize_textarea_field'
                )
            )
        ) );

        // Complete appointment
        register_rest_route( self::NAMESPACE, '/appointments/(?P<id>\d+)/complete', array(
            'methods' => 'POST',
            'callback' => array( self::class, 'complete_appointment' ),
            'permission_callback' => array( Auth_Service::class, 'check_authentication' ),
            'args' => array(
                'id' => array(
                    'required' => true,
                    'validate_callback' => function( $param ) {
                        return is_numeric( $param );
                    },
                    'sanitize_callback' => 'absint'
                ),
                'notes' => array(
                    'validate_callback' => 'rest_validate_request_arg',
                    'sanitize_callback' => 'sanitize_textarea_field'
                )
            )
        ) );

        // Get doctor availability
        register_rest_route( self::NAMESPACE, '/appointments/availability/(?P<doctor_id>\d+)', array(
            'methods' => 'GET',
            'callback' => array( self::class, 'get_doctor_availability' ),
            'permission_callback' => array( Auth_Service::class, 'check_authentication' ),
            'args' => array(
                'doctor_id' => array(
                    'required' => true,
                    'validate_callback' => function( $param ) {
                        return is_numeric( $param );
                    },
                    'sanitize_callback' => 'absint'
                ),
                'start_date' => array(
                    'required' => true,
                    'validate_callback' => function( $param ) {
                        return self::validate_date( $param );
                    },
                    'sanitize_callback' => 'sanitize_text_field'
                ),
                'end_date' => array(
                    'required' => true,
                    'validate_callback' => function( $param ) {
                        return self::validate_date( $param );
                    },
                    'sanitize_callback' => 'sanitize_text_field'
                )
            )
        ) );

        // Search appointments
        register_rest_route( self::NAMESPACE, '/appointments/search', array(
            'methods' => 'GET',
            'callback' => array( self::class, 'search_appointments' ),
            'permission_callback' => array( Auth_Service::class, 'check_authentication' ),
            'args' => self::get_search_args()
        ) );

        // Bulk operations
        register_rest_route( self::NAMESPACE, '/appointments/bulk', array(
            'methods' => 'POST',
            'callback' => array( self::class, 'bulk_operations' ),
            'permission_callback' => array( Auth_Service::class, 'check_authentication' ),
            'args' => self::get_bulk_operation_args()
        ) );
    }

    /**
     * Get appointments list
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     * @since 1.0.0
     */
    public static function get_appointments( WP_REST_Request $request ) {
        try {
            $params = $request->get_params();
            
            // Build filters array
            $filters = array(
                'limit' => $params['per_page'] ?? 20,
                'offset' => ( ( $params['page'] ?? 1 ) - 1 ) * ( $params['per_page'] ?? 20 )
            );

            // Add filters based on parameters
            if ( ! empty( $params['start_date'] ) ) {
                $filters['start_date'] = sanitize_text_field( $params['start_date'] );
            }
            if ( ! empty( $params['end_date'] ) ) {
                $filters['end_date'] = sanitize_text_field( $params['end_date'] );
            }
            if ( ! empty( $params['doctor_id'] ) ) {
                $filters['doctor_id'] = absint( $params['doctor_id'] );
            }
            if ( ! empty( $params['patient_id'] ) ) {
                $filters['patient_id'] = absint( $params['patient_id'] );
            }
            if ( ! empty( $params['clinic_id'] ) ) {
                $filters['clinic_id'] = absint( $params['clinic_id'] );
            }
            if ( isset( $params['status'] ) ) {
                $status = $params['status'];
                if ( is_array( $status ) ) {
                    $filters['status'] = array_map( 'absint', $status );
                } else {
                    $filters['status'] = absint( $status );
                }
            }
            if ( ! empty( $params['search'] ) ) {
                $filters['search'] = sanitize_text_field( $params['search'] );
            }

            $result = Appointment_Service::search_appointments( $filters );
            
            if ( is_wp_error( $result ) ) {
                return Error_Handler::handle_service_error( $result );
            }

            return new WP_REST_Response( array(
                'success' => true,
                'data' => $result['appointments'],
                'pagination' => array(
                    'total' => $result['total'],
                    'page' => $params['page'] ?? 1,
                    'per_page' => $params['per_page'] ?? 20,
                    'has_more' => $result['has_more']
                )
            ), 200 );

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

    /**
     * Create a new appointment
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     * @since 1.0.0
     */
    public static function create_appointment( WP_REST_Request $request ) {
        try {
            $data = $request->get_json_params();
            
            // Validate required fields
            $validation = Input_Validator::validate_appointment_data( $data, 'create' );
            if ( is_wp_error( $validation ) ) {
                return $validation;
            }

            // Sanitize input data
            $appointment_data = self::sanitize_appointment_data( $data );
            
            $result = Appointment_Service::create_appointment( $appointment_data );
            
            if ( is_wp_error( $result ) ) {
                return Error_Handler::handle_service_error( $result );
            }

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

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

    /**
     * Get single appointment
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     * @since 1.0.0
     */
    public static function get_appointment( WP_REST_Request $request ) {
        try {
            $appointment_id = $request['id'];
            
            $result = Appointment_Service::get_appointment_with_metadata( $appointment_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 appointment
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     * @since 1.0.0
     */
    public static function update_appointment( WP_REST_Request $request ) {
        try {
            $appointment_id = $request['id'];
            $data = $request->get_json_params();
            
            // Validate input data
            $validation = Input_Validator::validate_appointment_data( $data, 'update' );
            if ( is_wp_error( $validation ) ) {
                return $validation;
            }

            // Sanitize input data
            $appointment_data = self::sanitize_appointment_data( $data );
            
            $result = Appointment_Service::update_appointment( $appointment_id, $appointment_data );
            
            if ( is_wp_error( $result ) ) {
                return Error_Handler::handle_service_error( $result );
            }

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

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

    /**
     * Cancel appointment
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     * @since 1.0.0
     */
    public static function cancel_appointment( WP_REST_Request $request ) {
        try {
            $appointment_id = $request['id'];
            $data = $request->get_json_params();
            $reason = sanitize_textarea_field( $data['reason'] ?? '' );
            
            $result = Appointment_Service::cancel_appointment( $appointment_id, $reason );
            
            if ( is_wp_error( $result ) ) {
                return Error_Handler::handle_service_error( $result );
            }

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

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

    /**
     * Complete appointment
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     * @since 1.0.0
     */
    public static function complete_appointment( WP_REST_Request $request ) {
        try {
            $appointment_id = $request['id'];
            $data = $request->get_json_params();
            
            $completion_data = array();
            if ( ! empty( $data['notes'] ) ) {
                $completion_data['completion_notes'] = sanitize_textarea_field( $data['notes'] );
            }
            
            $result = Appointment_Service::complete_appointment( $appointment_id, $completion_data );
            
            if ( is_wp_error( $result ) ) {
                return Error_Handler::handle_service_error( $result );
            }

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

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

    /**
     * Get doctor availability
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     * @since 1.0.0
     */
    public static function get_doctor_availability( WP_REST_Request $request ) {
        try {
            $doctor_id = $request['doctor_id'];
            $start_date = $request['start_date'];
            $end_date = $request['end_date'];
            
            $result = Appointment_Service::get_doctor_availability( $doctor_id, $start_date, $end_date );
            
            return new WP_REST_Response( array(
                'success' => true,
                'data' => $result
            ), 200 );

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

    /**
     * Search appointments
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     * @since 1.0.0
     */
    public static function search_appointments( WP_REST_Request $request ) {
        try {
            $params = $request->get_params();
            
            // Build filters array
            $filters = array();
            
            if ( ! empty( $params['q'] ) ) {
                $filters['search'] = sanitize_text_field( $params['q'] );
            }
            if ( ! empty( $params['start_date'] ) ) {
                $filters['start_date'] = sanitize_text_field( $params['start_date'] );
            }
            if ( ! empty( $params['end_date'] ) ) {
                $filters['end_date'] = sanitize_text_field( $params['end_date'] );
            }
            if ( ! empty( $params['doctor_id'] ) ) {
                $filters['doctor_id'] = absint( $params['doctor_id'] );
            }
            if ( ! empty( $params['patient_id'] ) ) {
                $filters['patient_id'] = absint( $params['patient_id'] );
            }
            if ( ! empty( $params['clinic_id'] ) ) {
                $filters['clinic_id'] = absint( $params['clinic_id'] );
            }
            if ( isset( $params['status'] ) ) {
                $filters['status'] = absint( $params['status'] );
            }

            $filters['limit'] = $params['per_page'] ?? 20;
            $filters['offset'] = ( ( $params['page'] ?? 1 ) - 1 ) * ( $params['per_page'] ?? 20 );

            $result = Appointment_Service::search_appointments( $filters );
            
            if ( is_wp_error( $result ) ) {
                return Error_Handler::handle_service_error( $result );
            }

            return new WP_REST_Response( array(
                'success' => true,
                'data' => $result['appointments'],
                'pagination' => array(
                    'total' => $result['total'],
                    'page' => $params['page'] ?? 1,
                    'per_page' => $params['per_page'] ?? 20,
                    'has_more' => $result['has_more']
                )
            ), 200 );

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

    /**
     * Bulk operations on appointments
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     * @since 1.0.0
     */
    public static function bulk_operations( WP_REST_Request $request ) {
        try {
            $data = $request->get_json_params();
            $action = sanitize_text_field( $data['action'] ?? '' );
            $appointment_ids = array_map( 'absint', $data['appointment_ids'] ?? array() );
            
            if ( empty( $action ) || empty( $appointment_ids ) ) {
                return new WP_Error(
                    'invalid_bulk_data',
                    'Action and appointment IDs are required',
                    array( 'status' => 400 )
                );
            }

            $results = array();
            $errors = array();

            switch ( $action ) {
                case 'cancel':
                    $reason = sanitize_textarea_field( $data['reason'] ?? 'Bulk cancellation' );
                    foreach ( $appointment_ids as $appointment_id ) {
                        $result = Appointment_Service::cancel_appointment( $appointment_id, $reason );
                        if ( is_wp_error( $result ) ) {
                            $errors[] = array( 'id' => $appointment_id, 'error' => $result->get_error_message() );
                        } else {
                            $results[] = array( 'id' => $appointment_id, 'status' => 'cancelled' );
                        }
                    }
                    break;

                case 'complete':
                    $completion_data = array();
                    if ( ! empty( $data['notes'] ) ) {
                        $completion_data['completion_notes'] = sanitize_textarea_field( $data['notes'] );
                    }
                    foreach ( $appointment_ids as $appointment_id ) {
                        $result = Appointment_Service::complete_appointment( $appointment_id, $completion_data );
                        if ( is_wp_error( $result ) ) {
                            $errors[] = array( 'id' => $appointment_id, 'error' => $result->get_error_message() );
                        } else {
                            $results[] = array( 'id' => $appointment_id, 'status' => 'completed' );
                        }
                    }
                    break;

                default:
                    return new WP_Error(
                        'invalid_bulk_action',
                        'Invalid bulk action',
                        array( 'status' => 400 )
                    );
            }

            return new WP_REST_Response( array(
                'success' => true,
                'message' => 'Bulk operation completed',
                'results' => $results,
                'errors' => $errors
            ), 200 );

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

    /**
     * Sanitize appointment data
     *
     * @param array $data Raw data
     * @return array Sanitized data
     * @since 1.0.0
     */
    private static function sanitize_appointment_data( $data ) {
        $sanitized = array();

        if ( isset( $data['patient_id'] ) ) {
            $sanitized['patient_id'] = absint( $data['patient_id'] );
        }
        if ( isset( $data['doctor_id'] ) ) {
            $sanitized['doctor_id'] = absint( $data['doctor_id'] );
        }
        if ( isset( $data['clinic_id'] ) ) {
            $sanitized['clinic_id'] = absint( $data['clinic_id'] );
        }
        if ( isset( $data['service_id'] ) ) {
            $sanitized['service_id'] = absint( $data['service_id'] );
        }

        $text_fields = array( 'appointment_start_date', 'appointment_start_time', 'appointment_end_time', 'description' );
        foreach ( $text_fields as $field ) {
            if ( isset( $data[$field] ) ) {
                $sanitized[$field] = sanitize_text_field( $data[$field] );
            }
        }

        if ( isset( $data['duration'] ) ) {
            $sanitized['duration'] = absint( $data['duration'] );
        }

        if ( isset( $data['status'] ) ) {
            $sanitized['status'] = absint( $data['status'] );
        }

        return $sanitized;
    }

    /**
     * Validate date format
     *
     * @param string $date Date string
     * @return bool Valid or not
     * @since 1.0.0
     */
    private static function validate_date( $date ) {
        $d = \DateTime::createFromFormat( 'Y-m-d', $date );
        return $d && $d->format( 'Y-m-d' ) === $date;
    }

    /**
     * Get arguments for appointments list endpoint
     *
     * @return array
     * @since 1.0.0
     */
    private static function get_appointments_args() {
        return array(
            'page' => array(
                'validate_callback' => function( $param ) {
                    return is_numeric( $param ) && $param > 0;
                },
                'sanitize_callback' => 'absint',
                'default' => 1
            ),
            'per_page' => array(
                'validate_callback' => function( $param ) {
                    return is_numeric( $param ) && $param > 0 && $param <= 100;
                },
                'sanitize_callback' => 'absint',
                'default' => 20
            ),
            'start_date' => array(
                'validate_callback' => function( $param ) {
                    return self::validate_date( $param );
                },
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'end_date' => array(
                'validate_callback' => function( $param ) {
                    return self::validate_date( $param );
                },
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'doctor_id' => array(
                'validate_callback' => function( $param ) {
                    return is_numeric( $param );
                },
                'sanitize_callback' => 'absint'
            ),
            'patient_id' => array(
                'validate_callback' => function( $param ) {
                    return is_numeric( $param );
                },
                'sanitize_callback' => 'absint'
            ),
            'clinic_id' => array(
                'validate_callback' => function( $param ) {
                    return is_numeric( $param );
                },
                'sanitize_callback' => 'absint'
            ),
            'status' => array(
                'validate_callback' => function( $param ) {
                    if ( is_array( $param ) ) {
                        return ! empty( $param );
                    }
                    return is_numeric( $param );
                },
                'sanitize_callback' => function( $param ) {
                    if ( is_array( $param ) ) {
                        return array_map( 'absint', $param );
                    }
                    return absint( $param );
                }
            ),
            'search' => array(
                'validate_callback' => 'rest_validate_request_arg',
                'sanitize_callback' => 'sanitize_text_field'
            )
        );
    }

    /**
     * Get arguments for create appointment endpoint
     *
     * @return array
     * @since 1.0.0
     */
    private static function get_create_appointment_args() {
        return array(
            'patient_id' => array(
                'required' => true,
                'validate_callback' => function( $param ) {
                    return is_numeric( $param ) && $param > 0;
                },
                'sanitize_callback' => 'absint'
            ),
            'doctor_id' => array(
                'required' => true,
                'validate_callback' => function( $param ) {
                    return is_numeric( $param ) && $param > 0;
                },
                'sanitize_callback' => 'absint'
            ),
            'clinic_id' => array(
                'required' => true,
                'validate_callback' => function( $param ) {
                    return is_numeric( $param ) && $param > 0;
                },
                'sanitize_callback' => 'absint'
            ),
            'appointment_start_date' => array(
                'required' => true,
                'validate_callback' => function( $param ) {
                    return self::validate_date( $param );
                },
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'appointment_start_time' => array(
                'required' => true,
                'validate_callback' => function( $param ) {
                    return preg_match( '/^([0-1]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/', $param );
                },
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'appointment_end_time' => array(
                'validate_callback' => function( $param ) {
                    return preg_match( '/^([0-1]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/', $param );
                },
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'duration' => array(
                'validate_callback' => function( $param ) {
                    return is_numeric( $param ) && $param > 0;
                },
                'sanitize_callback' => 'absint'
            ),
            'service_id' => array(
                'validate_callback' => function( $param ) {
                    return empty( $param ) || is_numeric( $param );
                },
                'sanitize_callback' => 'absint'
            ),
            'description' => array(
                'validate_callback' => 'rest_validate_request_arg',
                'sanitize_callback' => 'sanitize_textarea_field'
            )
        );
    }

    /**
     * Get arguments for update appointment endpoint
     *
     * @return array
     * @since 1.0.0
     */
    private static function get_update_appointment_args() {
        $args = self::get_create_appointment_args();
        // Make all fields optional for update
        foreach ( $args as &$arg ) {
            $arg['required'] = false;
        }
        return $args;
    }

    /**
     * Get arguments for search endpoint
     *
     * @return array
     * @since 1.0.0
     */
    private static function get_search_args() {
        return array(
            'q' => array(
                'validate_callback' => 'rest_validate_request_arg',
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'start_date' => array(
                'validate_callback' => function( $param ) {
                    return self::validate_date( $param );
                },
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'end_date' => array(
                'validate_callback' => function( $param ) {
                    return self::validate_date( $param );
                },
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'doctor_id' => array(
                'validate_callback' => function( $param ) {
                    return is_numeric( $param );
                },
                'sanitize_callback' => 'absint'
            ),
            'patient_id' => array(
                'validate_callback' => function( $param ) {
                    return is_numeric( $param );
                },
                'sanitize_callback' => 'absint'
            ),
            'clinic_id' => array(
                'validate_callback' => function( $param ) {
                    return is_numeric( $param );
                },
                'sanitize_callback' => 'absint'
            ),
            'status' => array(
                'validate_callback' => function( $param ) {
                    return is_numeric( $param );
                },
                'sanitize_callback' => 'absint'
            ),
            'page' => array(
                'validate_callback' => function( $param ) {
                    return is_numeric( $param ) && $param > 0;
                },
                'sanitize_callback' => 'absint',
                'default' => 1
            ),
            'per_page' => array(
                'validate_callback' => function( $param ) {
                    return is_numeric( $param ) && $param > 0 && $param <= 100;
                },
                'sanitize_callback' => 'absint',
                'default' => 20
            )
        );
    }

    /**
     * Get arguments for bulk operations endpoint
     *
     * @return array
     * @since 1.0.0
     */
    private static function get_bulk_operation_args() {
        return array(
            'action' => array(
                'required' => true,
                'validate_callback' => function( $param ) {
                    return in_array( $param, array( 'cancel', 'complete' ) );
                },
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'appointment_ids' => array(
                'required' => true,
                'validate_callback' => function( $param ) {
                    return is_array( $param ) && ! empty( $param );
                },
                'sanitize_callback' => function( $param ) {
                    return array_map( 'absint', $param );
                }
            ),
            'reason' => array(
                'validate_callback' => 'rest_validate_request_arg',
                'sanitize_callback' => 'sanitize_textarea_field'
            ),
            'notes' => array(
                'validate_callback' => 'rest_validate_request_arg',
                'sanitize_callback' => 'sanitize_textarea_field'
            )
        );
    }
}