<?php
namespace ZenCommunity\Api;
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;
use ZenCommunity\Database\Models\Profile;
use ZenCommunity\Addons\AcademyLms\Api\Common\Permissions;
class Auth extends Common\Base {
    use Schema\AuthSchema;
    public function init() : void {
        register_rest_route( $this->namespace, '/auth/signin', [
            'methods'             => WP_REST_Server::CREATABLE,
            'callback'            => [ $this, 'signin' ],
            'permission_callback' => fn() : bool =>  ! is_user_logged_in(),
            'args'                => $this->signin_schema(),
        ] );
        
        register_rest_route( $this->namespace, '/auth/signup', [
            'methods'             => WP_REST_Server::CREATABLE,
            'callback'            => [ $this, 'signup' ],
            'permission_callback' => fn() : bool =>  ! is_user_logged_in(),
            'args'                => $this->signup_schema(),
        ] );

        register_rest_route( $this->namespace, '/auth/signout', [
            'methods'             => WP_REST_Server::CREATABLE,
            'callback'            => [ $this, 'sign_out' ],
            'permission_callback' => fn() : bool =>  is_user_logged_in(),
        ] );
        
        register_rest_route( $this->namespace, '/settings/user/create', [
            'methods'             => WP_REST_Server::CREATABLE,
            'callback'            => [ $this, 'create_member' ],
            'permission_callback' => [ Permissions::class, 'admin_can'  ],
            'args'                => $this->signup_schema(),
        ] );

        add_filter( 'rest_post_dispatch', function( $response, $server, WP_REST_Request $request ) {
            $route = $request->get_route();
            if ( str_starts_with( $route, '/' . $this->namespace . '/auth/' ) ) {
                $response->header( 'Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0' );
                $response->header( 'Pragma', 'no-cache' );
            }
            return $response;
        }, 10, 3 );
    }

    public function signin( WP_REST_Request $request ) : WP_REST_Response {

        if ( is_user_logged_in() ) {
            return new WP_REST_Response( [
                'success' => true,
                'message' => __( 'You are already logged in.', 'zencommunity' ),
                'data'    => Profile::current(),
            ] );
        }

        $params         = $request->get_params();
        $user_identifier = isset( $params['user'] ) ? sanitize_text_field( $params['user'] ) : '';
        $password       = isset( $params['password'] ) ? $params['password'] : '';
        $remember_me    = isset( $params['remember_me'] ) ? (bool) $params['remember_me'] : true;

        if ( empty( $user_identifier ) || empty( $password ) ) {
            return new WP_REST_Response( [
                'success' => false,
                'message' => __( 'Username/email and password are required.', 'zencommunity' ),
            ], 400 );
        }

        $creds = [
            'user_login'    => $user_identifier,
            'user_password' => $password,
            'remember'      => $remember_me,
        ];

        $user = wp_signon( $creds );

        if ( is_wp_error( $user ) ) {
            return new WP_REST_Response( [
                'success' => false,
                'message' => __( 'Invalid username/email or password.', 'zencommunity' ),
            ], 400 );
        }

        return new WP_REST_Response( [
            'success' => true,
            'message' => __( 'Logged in successfully.', 'zencommunity' ),
            'data'    => Profile::current(),
        ] );
    }

    public function signup( WP_REST_Request $request ) : WP_REST_Response {
        global $zencommunity_settings;
        if ( ! $zencommunity_settings->allow_member_registration ) 
            return new WP_REST_Response( [
                'success' => false,
                'message' =>__( 'Member registration is currently disabled.', 'zencommunity' )
            ], 401 );
        
        if ( is_user_logged_in() )
            return new WP_REST_Response( [
                'success' => true,
                'message' => __( 'You are already logged in.', 'zencommunity' ),
                'data' => Profile::current(),
            ] );
        
        return $this->create_member( $request );
    }

    public function create_member( WP_REST_Request $request ) : WP_REST_Response {
        $params = $request->get_params();
        $first_name = sanitize_text_field( $params['first_name'] ?? '' );
        $last_name  = sanitize_text_field( $params['last_name'] ?? '' );
        $username   = sanitize_user( $params['username'] ?? '' );
        $email      = sanitize_email( $params['email'] );
        $password   = $params['password'];

        // If a guest already filed tickets under this email (auto-registered
        // visitor), claim+upgrade that same account so their tickets carry over.
        $existing_user = is_email( $email ) ? get_user_by( 'email', $email ) : false;
        $claim_user    = ( $existing_user instanceof \WP_User && self::is_claimable_visitor( $existing_user ) ) ? $existing_user : null;

        $errors = [];
        if( ! is_email( $email ) ) {
            $errors['email'] = __( 'invalid email.', 'zencommunity' );
        }

        if( email_exists( $email ) && ! $claim_user ) {
            $errors['email'] = __( 'email already exists.', 'zencommunity' );
        }

        if( ! empty( $username ) && username_exists( $username ) ) {
            $errors['username'] = __( 'username already in use.', 'zencommunity' );
        }

        if( empty( $password ) ) {
            $errors['password'] = __( 'Password is required.', 'zencommunity' );
        }

        if( ! empty( $password ) && strlen( $password ) < 6 ) {
            $errors['password'] = __( 'Password must be at least 6 characters.', 'zencommunity' );
        }

        if ( ! empty( $errors ) ) {
            return new WP_REST_Response( [
                'success' => false,
                // translators: %s The database error message.
                'message' => sprintf( __( 'Validation Errors: %s fields are required.', 'zencommunity' ), implode( ',', array_keys( $errors ) ) ),
                'errors' => $errors,
            ], 422 );
        }

        if ( empty( $username ) ) {
            $username = $this->username_from_email( $email );
        }

        if ( $claim_user ) {
            // Upgrade the existing guest/visitor account in place: their prior
            // tickets are already owned by this user id, so they carry over.
            $user_id = (int) $claim_user->ID;
            wp_set_password( $password, $user_id );
            update_user_meta( $user_id, 'first_name', $first_name );
            update_user_meta( $user_id, 'last_name',  $last_name );
            wp_update_user( [ 'ID' => $user_id, 'display_name' => trim( "{$first_name} {$last_name}" ) ?: $email ] );
            ( new \WP_User( $user_id ) )->set_role( get_option( 'default_role', 'subscriber' ) );
            delete_user_meta( $user_id, '_zenc_guest_visitor' );
        } else {
            $user_id = register_new_user( $username, $email );
            if ( is_wp_error( $user_id ) ) {
                return new WP_REST_Response( [
                    'success' => false,
                    'message' => __( 'Error.', 'zencommunity' ),
                ], 500 );
            }
            wp_set_password( $password, $user_id );
            update_user_meta( $user_id, 'first_name', $first_name );
            update_user_meta( $user_id, 'last_name',  $last_name );
        }

        wp_new_user_notification( $user_id, null, 'both' );

        return new WP_REST_Response([
            'success' => true,
            'message' =>  __( 'User registered successfully.', 'zencommunity' ),
            'data'    =>  Profile::create_profile_if_not_exists( $user_id )
        ], 201);
    }

    /**
     * A "claimable" account is a guest/visitor auto-created for tickets/chat
     * (marker meta, the live_chat_visitor role, or the lcv_/tkv_ login prefix).
     * Registering with that email upgrades it instead of erroring.
     */
    private static function is_claimable_visitor( \WP_User $user ) : bool {
        if ( get_user_meta( $user->ID, '_zenc_guest_visitor', true ) ) {
            return true;
        }
        if ( in_array( 'live_chat_visitor', (array) $user->roles, true ) ) {
            return true;
        }
        $login = (string) ( $user->user_login ?? '' );
        return 0 === strpos( $login, 'lcv_' ) || 0 === strpos( $login, 'tkv_' );
    }

    private function username_from_email( string $email ) : string { 
        $username = sanitize_user( current( explode( '@', $email ) ), true );
        $original_username = $username;
        $counter = 1;
        while (username_exists($username)) {
            $username = $original_username . $counter;
            $counter++;
        }
        return $username;
    }

    public function sign_out( WP_REST_Request $request ) : WP_REST_Response {
        if ( ! is_user_logged_in() )
            return new WP_REST_Response( [
                'success' => false,
                'message' => __( 'You are already logged out.', 'zencommunity' ),
            ] );

        // logout current user 
        wp_logout();

        return new WP_REST_Response( [
            'success' => true,
            'message' => __( 'You are logged out.', 'zencommunity' ),
        ] );
    }
}