<?php
/**
 * Clinic REST API Endpoints
 *
 * Handles all clinic-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\Clinic_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 Clinic_Endpoints
 *
 * REST API endpoints for clinic management
 *
 * @since 1.0.0
 */
class Clinic_Endpoints {

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

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

        // Create clinic
        register_rest_route( self::NAMESPACE, '/clinics', array(
            'methods' => 'POST',
            'callback' => array( self::class, 'create_clinic' ),
            'permission_callback' => array( Auth_Service::class, 'check_authentication' ),
            'args' => self::get_create_clinic_args()
        ) );

        // Get single clinic
        register_rest_route( self::NAMESPACE, '/clinics/(?P<id>\d+)', array(
            'methods' => 'GET',
            'callback' => array( self::class, 'get_clinic' ),
            '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 clinic
        register_rest_route( self::NAMESPACE, '/clinics/(?P<id>\d+)', array(
            'methods' => 'PUT',
            'callback' => array( self::class, 'update_clinic' ),
            'permission_callback' => array( Auth_Service::class, 'check_authentication' ),
            'args' => self::get_update_clinic_args()
        ) );

        // Delete clinic
        register_rest_route( self::NAMESPACE, '/clinics/(?P<id>\d+)', array(
            'methods' => 'DELETE',
            'callback' => array( self::class, 'delete_clinic' ),
            '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'
                )
            )
        ) );

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

        // Get clinic dashboard
        register_rest_route( self::NAMESPACE, '/clinics/(?P<id>\d+)/dashboard', array(
            'methods' => 'GET',
            'callback' => array( self::class, 'get_clinic_dashboard' ),
            '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'
                )
            )
        ) );

        // Get clinic statistics
        register_rest_route( self::NAMESPACE, '/clinics/(?P<id>\d+)/statistics', array(
            'methods' => 'GET',
            'callback' => array( self::class, 'get_clinic_statistics' ),
            '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'
                )
            )
        ) );

        // Bulk operations
        register_rest_route( self::NAMESPACE, '/clinics/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 clinics list
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     * @since 1.0.0
     */
    public static function get_clinics( WP_REST_Request $request ) {
        try {
            $params = $request->get_params();
            
            // Validate input parameters
            $validation = Input_Validator::validate_clinic_list_params( $params );
            if ( is_wp_error( $validation ) ) {
                return $validation;
            }

            $args = array(
                'limit' => $params['per_page'] ?? 20,
                'offset' => ( ( $params['page'] ?? 1 ) - 1 ) * ( $params['per_page'] ?? 20 ),
                'status' => $params['status'] ?? 1,
                'include_statistics' => $params['include_statistics'] ?? false,
                'include_doctors' => $params['include_doctors'] ?? false,
                'include_services' => $params['include_services'] ?? false
            );

            $result = Clinic_Service::get_accessible_clinics( $args );
            
            if ( is_wp_error( $result ) ) {
                return Error_Handler::handle_service_error( $result );
            }

            return new WP_REST_Response( array(
                'success' => true,
                'data' => $result['clinics'],
                '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 clinic
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     * @since 1.0.0
     */
    public static function create_clinic( WP_REST_Request $request ) {
        try {
            $data = $request->get_json_params();
            
            // Validate required fields
            $validation = Input_Validator::validate_clinic_data( $data, 'create' );
            if ( is_wp_error( $validation ) ) {
                return $validation;
            }

            // Sanitize input data
            $clinic_data = Input_Validator::sanitize_clinic_data( $data );
            
            $result = Clinic_Service::create_clinic( $clinic_data );
            
            if ( is_wp_error( $result ) ) {
                return Error_Handler::handle_service_error( $result );
            }

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

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

    /**
     * Get single clinic
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     * @since 1.0.0
     */
    public static function get_clinic( WP_REST_Request $request ) {
        try {
            $clinic_id = $request['id'];
            
            $result = Clinic_Service::get_clinic_with_metadata( $clinic_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 clinic
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     * @since 1.0.0
     */
    public static function update_clinic( WP_REST_Request $request ) {
        try {
            $clinic_id = $request['id'];
            $data = $request->get_json_params();
            
            // Validate input data
            $validation = Input_Validator::validate_clinic_data( $data, 'update' );
            if ( is_wp_error( $validation ) ) {
                return $validation;
            }

            // Sanitize input data
            $clinic_data = Input_Validator::sanitize_clinic_data( $data );
            
            $result = Clinic_Service::update_clinic( $clinic_id, $clinic_data );
            
            if ( is_wp_error( $result ) ) {
                return Error_Handler::handle_service_error( $result );
            }

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

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

    /**
     * Delete clinic
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     * @since 1.0.0
     */
    public static function delete_clinic( WP_REST_Request $request ) {
        try {
            $clinic_id = $request['id'];
            
            // Soft delete - update status to inactive
            $result = Clinic_Service::update_clinic( $clinic_id, array( 'status' => 0 ) );
            
            if ( is_wp_error( $result ) ) {
                return Error_Handler::handle_service_error( $result );
            }

            return new WP_REST_Response( array(
                'success' => true,
                'message' => 'Clinic deactivated successfully'
            ), 200 );

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

    /**
     * Search clinics
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     * @since 1.0.0
     */
    public static function search_clinics( WP_REST_Request $request ) {
        try {
            $params = $request->get_params();
            $search_term = sanitize_text_field( $params['q'] ?? '' );
            
            if ( empty( $search_term ) ) {
                return new WP_Error(
                    'missing_search_term',
                    'Search term is required',
                    array( 'status' => 400 )
                );
            }

            $filters = array();
            if ( ! empty( $params['city'] ) ) {
                $filters['city'] = sanitize_text_field( $params['city'] );
            }
            if ( ! empty( $params['state'] ) ) {
                $filters['state'] = sanitize_text_field( $params['state'] );
            }
            if ( ! empty( $params['specialty'] ) ) {
                $filters['specialty'] = sanitize_text_field( $params['specialty'] );
            }
            
            $result = Clinic_Service::search_clinics( $search_term, $filters );
            
            return new WP_REST_Response( array(
                'success' => true,
                'data' => $result
            ), 200 );

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

    /**
     * Get clinic dashboard
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     * @since 1.0.0
     */
    public static function get_clinic_dashboard( WP_REST_Request $request ) {
        try {
            $clinic_id = $request['id'];
            
            $result = Clinic_Service::get_clinic_dashboard( $clinic_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 );
        }
    }

    /**
     * Get clinic statistics
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     * @since 1.0.0
     */
    public static function get_clinic_statistics( WP_REST_Request $request ) {
        try {
            $clinic_id = $request['id'];
            
            $result = Clinic_Service::get_performance_metrics( $clinic_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 );
        }
    }

    /**
     * Bulk operations on clinics
     *
     * @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'] ?? '' );
            $clinic_ids = array_map( 'absint', $data['clinic_ids'] ?? array() );
            
            if ( empty( $action ) || empty( $clinic_ids ) ) {
                return new WP_Error(
                    'invalid_bulk_data',
                    'Action and clinic IDs are required',
                    array( 'status' => 400 )
                );
            }

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

            switch ( $action ) {
                case 'activate':
                    foreach ( $clinic_ids as $clinic_id ) {
                        $result = Clinic_Service::update_clinic( $clinic_id, array( 'status' => 1 ) );
                        if ( is_wp_error( $result ) ) {
                            $errors[] = array( 'id' => $clinic_id, 'error' => $result->get_error_message() );
                        } else {
                            $results[] = array( 'id' => $clinic_id, 'status' => 'activated' );
                        }
                    }
                    break;

                case 'deactivate':
                    foreach ( $clinic_ids as $clinic_id ) {
                        $result = Clinic_Service::update_clinic( $clinic_id, array( 'status' => 0 ) );
                        if ( is_wp_error( $result ) ) {
                            $errors[] = array( 'id' => $clinic_id, 'error' => $result->get_error_message() );
                        } else {
                            $results[] = array( 'id' => $clinic_id, 'status' => 'deactivated' );
                        }
                    }
                    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 );
        }
    }

    /**
     * Get arguments for clinic list endpoint
     *
     * @return array
     * @since 1.0.0
     */
    private static function get_clinics_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
            ),
            'status' => array(
                'validate_callback' => function( $param ) {
                    return in_array( $param, array( 0, 1, '0', '1' ) );
                },
                'sanitize_callback' => 'absint',
                'default' => 1
            ),
            'include_statistics' => array(
                'validate_callback' => 'rest_validate_request_arg',
                'sanitize_callback' => 'rest_sanitize_boolean',
                'default' => false
            ),
            'include_doctors' => array(
                'validate_callback' => 'rest_validate_request_arg',
                'sanitize_callback' => 'rest_sanitize_boolean',
                'default' => false
            ),
            'include_services' => array(
                'validate_callback' => 'rest_validate_request_arg',
                'sanitize_callback' => 'rest_sanitize_boolean',
                'default' => false
            )
        );
    }

    /**
     * Get arguments for create clinic endpoint
     *
     * @return array
     * @since 1.0.0
     */
    private static function get_create_clinic_args() {
        return array(
            'name' => array(
                'required' => true,
                'validate_callback' => function( $param ) {
                    return ! empty( $param ) && is_string( $param );
                },
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'address' => array(
                'validate_callback' => 'rest_validate_request_arg',
                'sanitize_callback' => 'sanitize_textarea_field'
            ),
            'city' => array(
                'validate_callback' => 'rest_validate_request_arg',
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'state' => array(
                'validate_callback' => 'rest_validate_request_arg',
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'country' => array(
                'validate_callback' => 'rest_validate_request_arg',
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'postal_code' => array(
                'validate_callback' => 'rest_validate_request_arg',
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'telephone_no' => array(
                'validate_callback' => 'rest_validate_request_arg',
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'email' => array(
                'validate_callback' => function( $param ) {
                    return empty( $param ) || is_email( $param );
                },
                'sanitize_callback' => 'sanitize_email'
            ),
            'specialties' => array(
                'validate_callback' => 'rest_validate_request_arg',
                'sanitize_callback' => function( $param ) {
                    return is_array( $param ) ? array_map( 'sanitize_text_field', $param ) : array();
                }
            ),
            'clinic_admin_id' => array(
                'validate_callback' => function( $param ) {
                    return empty( $param ) || is_numeric( $param );
                },
                'sanitize_callback' => 'absint'
            )
        );
    }

    /**
     * Get arguments for update clinic endpoint
     *
     * @return array
     * @since 1.0.0
     */
    private static function get_update_clinic_args() {
        $args = self::get_create_clinic_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(
                'required' => true,
                'validate_callback' => function( $param ) {
                    return ! empty( $param ) && is_string( $param );
                },
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'city' => array(
                'validate_callback' => 'rest_validate_request_arg',
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'state' => array(
                'validate_callback' => 'rest_validate_request_arg',
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'specialty' => array(
                'validate_callback' => 'rest_validate_request_arg',
                'sanitize_callback' => 'sanitize_text_field'
            )
        );
    }

    /**
     * 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( 'activate', 'deactivate' ) );
                },
                'sanitize_callback' => 'sanitize_text_field'
            ),
            'clinic_ids' => array(
                'required' => true,
                'validate_callback' => function( $param ) {
                    return is_array( $param ) && ! empty( $param );
                },
                'sanitize_callback' => function( $param ) {
                    return array_map( 'absint', $param );
                }
            )
        );
    }
}