<?php

namespace WPUF\UserDirectory\Api;

use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;
use WP_User;
use WP_User_Query;

class User_Profile extends WPUF_Pro_REST_Controller {

    /**
     * Route name
     *
     * @since 4.2.0
     *
     * @var string
     */
    protected $rest_base = 'user-profile';

    public function register_routes() {
        // Get current user profile endpoint
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/current',
            [
                [
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => [ $this, 'get_current_user_profile' ],
                    'permission_callback' => '__return_true', // Public endpoint
                ],
            ]
        );

        // Get user profile by ID endpoint
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id>\\d+)',
            [
                [
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => [ $this, 'get_user_profile' ],
                    'permission_callback' => '__return_true', // Public endpoint
                    'args'                => [
                        'id' => [
                            'description' => __( 'User ID.', 'wpuf-pro' ),
                            'type'        => 'integer',
                            'required'    => true,
                        ],
                    ],
                ],
            ]
        );

        // Get user profile by username endpoint
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/by-username/(?P<username>[a-zA-Z0-9._-]+)',
            [
                [
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => [ $this, 'get_user_profile_by_username' ],
                    'permission_callback' => '__return_true', // Public endpoint
                    'args'                => [
                        'username' => [
                            'description' => __( 'Username.', 'wpuf-pro' ),
                            'type'        => 'string',
                            'required'    => true,
                        ],
                    ],
                ],
            ]
        );

        // Register avatar routes
        $this->register_avatar_routes();

        // Register cover photo routes
        $this->register_cover_photo_routes();
    }

    /**
     * Register avatar-related REST routes
     *
     * @since 4.2.0
     */
    public function register_avatar_routes() {
        register_rest_route( 'wpuf-pro/v1', '/user/(?P<id>\d+)/avatar', [
            'methods' => 'GET',
            'callback' => [ $this, 'get_user_avatar_data' ],
            'permission_callback' => [ $this, 'get_user_avatar_permissions' ],
            'args' => [
                'id' => [
                    'validate_callback' => function( $param ) {
                        return is_numeric( $param );
                    }
                ],
                'size' => [
                    'default' => 96,
                    'validate_callback' => function( $param ) {
                        return is_numeric( $param ) && $param > 0;
                    }
                ],
                'fallback_type' => [
                    'default' => 'gravatar',
                    'enum' => [ 'gravatar', 'initials' ]
                ]
            ]
        ] );
    }

    /**
     * Register cover photo-related REST routes
     *
     * @since 4.2.0
     */
    public function register_cover_photo_routes() {
        register_rest_route( 'wpuf-pro/v1', '/user/(?P<id>\d+)/cover-photo', [
            'methods' => 'GET',
            'callback' => [ $this, 'get_user_cover_photo_data' ],
            'permission_callback' => [ $this, 'get_user_cover_photo_permissions' ],
            'args' => [
                'id' => [
                    'validate_callback' => function( $param ) {
                        return is_numeric( $param );
                    }
                ]
            ]
        ] );
    }

    /**
     * Get user avatar data
     *
     * @since 4.2.0
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     */
    public function get_user_avatar_data( $request ) {
        $user_id = $request['id'];
        $size = $request['size'];
        $fallback_type = $request['fallback_type'];

        $user = get_user_by( 'ID', $user_id );
        if ( ! $user ) {
            return new WP_Error( 'user_not_found', __( 'User not found', 'wpuf-pro' ), [ 'status' => 404 ] );
        }

        $avatar_data = wpuf_ud_get_block_avatar_data( $user, $size, $fallback_type );

        return rest_ensure_response( $avatar_data );
    }

    /**
     * Get user cover photo data
     *
     * @since 4.2.0
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response|WP_Error
     */
    public function get_user_cover_photo_data( $request ) {
        $user_id = $request['id'];

        $user = get_user_by( 'ID', $user_id );
        if ( ! $user ) {
            return new WP_Error( 'user_not_found', __( 'User not found', 'wpuf-pro' ), [ 'status' => 404 ] );
        }

        // Get cover photo data using the proper function that handles attachment ID to URL conversion
        $cover_photo_data = wpuf_ud_get_block_cover_photo_data( $user, 1200 ); // Default to large size

        return rest_ensure_response( $cover_photo_data );
    }

    /**
     * Check permissions for avatar data endpoint
     *
     * @since 4.2.0
     *
     * @return bool
     */
    public function get_user_avatar_permissions() {
        // Allow public access for avatar data
        return true;
    }

    /**
     * Check permissions for cover photo data endpoint
     *
     * @since 4.2.0
     *
     * @return bool
     */
    public function get_user_cover_photo_permissions() {
        // Allow public access for cover photo data
        return true;
    }

    /**
     * Get current user profile
     *
     * @since 4.2.0
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function get_current_user_profile( $request ) {
        if ( ! is_user_logged_in() ) {
            return new WP_Error( 'rest_not_logged_in', __( 'You are not currently logged in.', 'wpuf-pro' ), [ 'status' => 401 ] );
        }

        $current_user = wp_get_current_user();

        return $this->prepare_user_profile_response( $current_user, $request );
    }

    /**
     * Get user profile by ID
     *
     * @since 4.2.0
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function get_user_profile( $request ) {
        $user_id = (int) $request['id'];

        if ( empty( $user_id ) ) {
            return new WP_Error( 'rest_invalid_user_id', __( 'Invalid user ID.', 'wpuf-pro' ), [ 'status' => 400 ] );
        }

        $user = get_user_by( 'ID', $user_id );

        if ( ! $user ) {
            return new WP_Error( 'rest_user_not_found', __( 'User not found.', 'wpuf-pro' ), [ 'status' => 404 ] );
        }

        // Check if user profile should be public
        if ( ! $this->is_user_profile_accessible( $user ) ) {
            return new WP_Error( 'rest_user_profile_private', __( 'User profile is not publicly accessible.', 'wpuf-pro' ), [ 'status' => 403 ] );
        }

        return $this->prepare_user_profile_response( $user, $request );
    }

    /**
     * Get user profile by username
     *
     * @since 4.2.0
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function get_user_profile_by_username( $request ) {
        $username = sanitize_user( $request['username'] );

        if ( empty( $username ) ) {
            return new WP_Error( 'rest_invalid_username', __( 'Invalid username.', 'wpuf-pro' ), [ 'status' => 400 ] );
        }

        $user = get_user_by( 'login', $username );

        if ( ! $user ) {
            return new WP_Error( 'rest_user_not_found', __( 'User not found.', 'wpuf-pro' ), [ 'status' => 404 ] );
        }

        // Check if user profile should be public
        if ( ! $this->is_user_profile_accessible( $user ) ) {
            return new WP_Error( 'rest_user_profile_private', __( 'User profile is not publicly accessible.', 'wpuf-pro' ), [ 'status' => 403 ] );
        }

        return $this->prepare_user_profile_response( $user, $request );
    }

    /**
     * Check if user profile is accessible (public)
     *
     * @since 4.2.0
     *
     * @param WP_User $user User object.
     *
     * @return bool
     */
    private function is_user_profile_accessible( $user ) {
        // Check if current user can view this profile
        $current_user = wp_get_current_user();

        // User can always view their own profile
        if ( $current_user->ID === $user->ID ) {
            return true;
        }

        // Administrators can view all profiles
        if ( current_user_can( 'manage_options' ) ) {
            return true;
        }

        // Check if user has made their profile private (custom meta field)
        $profile_privacy = get_user_meta( $user->ID, '_wpuf_profile_privacy', true );
        if ( 'private' === $profile_privacy ) {
            return false;
        }

        // Check if user role should be hidden
        $user_roles = $user->roles;
        $hidden_roles = apply_filters( 'wpuf_hidden_user_roles', [ 'administrator' ] );

        if ( array_intersect( $user_roles, $hidden_roles ) ) {
            return false;
        }

        return true;
    }

    /**
     * Prepare user profile response
     *
     * @since 4.2.0
     *
     * @param WP_User $user User object.
     * @param WP_REST_Request $request Request object (optional).
     * @return WP_REST_Response
     */
    private function prepare_user_profile_response( $user, $request = null ) {
        // Get user meta
        $user_meta = get_user_meta( $user->ID );

        // Flatten single-value meta (remove arrays with single values)
        $meta = [];
        foreach ( $user_meta as $key => $value ) {
            if ( is_array( $value ) && count( $value ) === 1 ) {
                $meta[ $key ] = $value[0];
            } else {
                $meta[ $key ] = $value;
            }
        }

        // Check if this is an editor request (for block preview)
        $is_editor_request = false;
        if ( $request ) {
            $user_agent = $request->get_header( 'User-Agent' );
            $referer = $request->get_header( 'Referer' );
            $is_editor_request = (
                strpos( $user_agent, 'WordPress' ) !== false ||
                strpos( $referer, 'post.php' ) !== false ||
                strpos( $referer, 'post-new.php' ) !== false ||
                ( isset( $_GET['context'] ) && $_GET['context'] === 'edit' )
            );
        }

        // Prepare response data
        $data = [
            'id'          => $user->ID,
            'username'    => $user->user_login,
            'slug'        => $user->user_nicename,
            'name'        => $user->display_name,
            'first_name'  => $user->first_name,
            'last_name'   => $user->last_name,
            'user_email'  => $user->user_email,
            'user_url'    => $user->user_url,
            'description' => $user->description,
            'nickname'    => $user->nickname,
            'roles'       => $user->roles,
            'capabilities' => $user->allcaps,
            'registered_date' => $user->user_registered,
            'avatar_urls' => rest_get_avatar_urls( $user->ID ),
            'meta'        => $meta,
        ];

        // For editor requests or admin users, provide full data
        $current_user = wp_get_current_user();
        $is_admin = current_user_can( 'manage_options' );
        $is_own_profile = ( $current_user->ID === $user->ID );

        if ( $is_editor_request || $is_admin || $is_own_profile ) {
            // Provide full user data for editor/admin/own profile
            // Include all meta fields for complete user information
            $data['full_data'] = true;
        } else {
            // Remove sensitive information for public viewing
            unset( $data['capabilities'] );

            // Filter meta to only include publicly viewable fields
            $public_meta_fields = apply_filters( 'wpuf_public_user_meta_fields', [
                'nickname',
                'first_name',
                'last_name',
                'description'
            ] );

            $filtered_meta = [];
            foreach ( $public_meta_fields as $field ) {
                if ( isset( $meta[ $field ] ) ) {
                    $filtered_meta[ $field ] = $meta[ $field ];
                }
            }
            $data['meta'] = $filtered_meta;
            $data['full_data'] = false;
        }

        // Apply filters for customization
        $data = apply_filters( 'wpuf_user_profile_rest_response', $data, $user, $request );

        return new WP_REST_Response( $data, 200 );
    }

    /**
     * Custom permissions check for user profile endpoints
     * Override parent class to allow public access with privacy controls
     *
     * @since 4.2.0
     *
     * @return bool
     */
    public function permissions_check( $request ) {
        // User profile endpoints are public but with privacy controls
        // The actual privacy checking is done in individual methods
        return true;
    }
}
