<?php

namespace Trainingssystem\Module\App;

use Trainingssystem\Module\App\RestHandler\AudioRestHandler;
use Trainingssystem\Module\App\RestHandler\Factory\AudioRestHandlerFactory;
use Trainingssystem\Module\App\RestHandler\Factory\IssueJwtRestHandlerFactory;
use Trainingssystem\Module\App\RestHandler\Factory\JournalRestHandlerFactory;
use Trainingssystem\Module\App\RestHandler\Factory\SleepRestHandlerFactory;
use Trainingssystem\Module\App\RestHandler\Factory\TrainingDataRestHandlerFactory;
use Trainingssystem\Module\App\RestHandler\IssueJwtRestHandler;
use Trainingssystem\Module\App\RestHandler\JournalRestHandler;
use Trainingssystem\Module\App\RestHandler\SleepRestHandler;
use Trainingssystem\Module\App\RestHandler\TrainingDataRestHandler;
use Trainingssystem\Module\App\Rule\Factory\HasRequestValidJwtRuleFactory;
use Trainingssystem\Module\App\Rule\HasRequestValidJwtRule;

class AppModule
{
    private IssueJwtRestHandler $issueJwtRestHandler;
    private TrainingDataRestHandler $trainingDataRestHandler;
    private AudioRestHandler $audioRestHander;
    private HasRequestValidJwtRule $hasRequestValidJwtRule;
    private JournalRestHandler $journalRestHandler;
    private SleepRestHandler $sleepRestHandler;


    public function __construct()
    {
        $this->issueJwtRestHandler = (new IssueJwtRestHandlerFactory())();
        $this->trainingDataRestHandler = (new TrainingDataRestHandlerFactory())();
        $this->audioRestHander = (new AudioRestHandlerFactory())();
        $this->hasRequestValidJwtRule = (new HasRequestValidJwtRuleFactory())();
        $this->journalRestHandler = (new JournalRestHandlerFactory())();
        $this->sleepRestHandler = (new SleepRestHandlerFactory())();

    }

    public function __invoke()
    {
        $activated = false;
        if(isset(get_option(TRAININGSSYSTEM_PLUGIN_SETTINGS)['rest_activated']) && get_option(TRAININGSSYSTEM_PLUGIN_SETTINGS)['rest_activated']) {
            $activated = true;
        }

        
        if($activated) {
            add_action('init', [$this, 'addCorsHttpHeader']);
            add_action('init', [$this, 'addPostType']);
            add_action('rest_api_init', [$this, 'registerRoutes']);
        } else {
            add_filter( 'rest_authentication_errors', function( $result ) {
                if ( ! empty( $result ) ) {
                    return $result;
                }
                if ( ! is_user_logged_in() ) {
                    return new \WP_Error( 'rest_not_logged_in', 'You are not currently logged in.', array( 'status' => 401 ) );
                }
                return $result;
            });
        }
    }

    public function registerRoutes(): void
    {
        register_rest_route(
            'app/v1',
            '/auth',
            [
                'methods' => 'POST',
                'callback' => [$this->issueJwtRestHandler, 'handle'],
                'permission_callback' => '__return_true'
            ]
        );

        register_rest_route(
            'app/v1',
            '/training-data',
            [
                'methods' => 'GET',
                'callback' => [$this->trainingDataRestHandler, 'handle'],
                'permission_callback' => [$this->hasRequestValidJwtRule, 'apply']
            ]
        );

        register_rest_route(
            'app/v1',
            '/sleep-questions',
            [
                'methods' => 'POST',
                'callback' => [$this->trainingDataRestHandler, 'getAppSleepQestions'],
                'permission_callback' => [$this->hasRequestValidJwtRule, 'apply']
            ]
        );

        register_rest_route(
            'app/v1',
            '/sleep-questions-multi',
            [
                'methods' => 'POST',
                'callback' => [$this->trainingDataRestHandler, 'getAppSleepQestionsMulti'],
                'permission_callback' => [$this->hasRequestValidJwtRule, 'apply']
            ]
        );

        register_rest_route(
            'app/v1',
            '/audio',
            [
                'methods' => 'GET',
                'callback' => [$this->audioRestHander, 'handle'],
                'permission_callback' => [$this->hasRequestValidJwtRule, 'apply']
            ]
        );

        register_rest_route(
            'app/v1',
            '/journal',
            [
                'methods' => 'POST',
                'callback' => [$this->journalRestHandler, 'handle'],
                'permission_callback' => [$this->hasRequestValidJwtRule, 'apply']
            ]
        );

        register_rest_route(
            'app/v1',
            '/get-all-entries',
            [
                'methods' => 'GET',
                'callback' => [$this->journalRestHandler, 'getAllEntries'],
                'permission_callback' => [$this->hasRequestValidJwtRule, 'apply']
            ]
        );

        register_rest_route(
            'app/v1',
            '/add-journal-entry',
            [
                'methods' => 'POST',
                'callback' => [$this->journalRestHandler, 'addEntry'],
                'permission_callback' => [$this->hasRequestValidJwtRule, 'apply']
            ]
        );

        register_rest_route(
            'app/v1',
            '/del-journal-entry',
            [
                'methods' => 'DELETE',
                'callback' => [$this->journalRestHandler, 'delEntry'],
                'permission_callback' => [$this->hasRequestValidJwtRule, 'apply']
            ]
        );

        register_rest_route(
            'app/v1',
            '/sleep',
            [
                'methods' => 'POST',
                'callback' => [$this->sleepRestHandler, 'update'],
                'permission_callback' => [$this->hasRequestValidJwtRule, 'apply']
            ]
        );

        register_rest_route(
            'app/v1',
            '/del-sleep-entry',
            [
                'methods' => 'POST',
                'callback' => [$this->sleepRestHandler, 'delEntry'],
                'permission_callback' => [$this->hasRequestValidJwtRule, 'apply']
            ]
        );

        register_rest_route(
            'app/v1',
            '/add-sleep-entry',
            [
                'methods' => 'POST',
                'callback' => [$this->sleepRestHandler, 'addEntry'],
                'permission_callback' => [$this->hasRequestValidJwtRule, 'apply']
            ]
        );

        register_rest_route(
            'app/v1',
            '/update-sleep-entry',
            [
                'methods' => 'POST',
                'callback' => [$this->sleepRestHandler, 'updateEntry'],
                'permission_callback' => [$this->hasRequestValidJwtRule, 'apply']
            ]
        );

        register_rest_route(
            'app/v1',
            '/add-update-postmeta',
            [
                'methods' => 'POST',
                'callback' => [$this->sleepRestHandler, 'addPostmetaForUserId'],
                'permission_callback' => [$this->hasRequestValidJwtRule, 'apply']
            ]
        );

        register_rest_route(
            'app/v1',
            '/get-postmeta',
            [
                'methods' => 'POST',
                'callback' => [$this->sleepRestHandler, 'getPostmetaForUserId'],
                'permission_callback' => [$this->hasRequestValidJwtRule, 'apply']
            ]
        );
        
        register_rest_route(
            'app/v1',
            '/sleep-weeks',
            [
                'methods' => 'POST',
                'callback' => [$this->sleepRestHandler, 'updateWeeks'],
                'permission_callback' => [$this->hasRequestValidJwtRule, 'apply']
            ]
        );

        register_rest_route(
            'app/v1',
            '/del-sleep-week',
            [
                'methods' => 'DELETE',
                'callback' => [$this->sleepRestHandler, 'delWeek'],
                'permission_callback' => [$this->hasRequestValidJwtRule, 'apply']
            ]
        );

        register_rest_route(
            'app/v1',
            '/add-sleep-week-entry',
            [
                'methods' => 'POST',
                'callback' => [$this->sleepRestHandler, 'addWeek'],
                'permission_callback' => [$this->hasRequestValidJwtRule, 'apply']
            ]
        );

        register_rest_route(
            'app/v1',
            '/update-sleep-week-entry',
            [
                'methods' => 'POST',
                'callback' => [$this->sleepRestHandler, 'updateWeek'],
                'permission_callback' => [$this->hasRequestValidJwtRule, 'apply']
            ]
        );
    }

    public function addCorsHttpHeader(): void
    {
        header("Access-Control-Allow-Origin: *");
    }

    public function addPostType(): void
    {
        $arguments = [
            'public' => false,
            'description' => '',
            'label' => 'App Journal Entry',
        ];
        register_post_type( 'appjournalentry', $arguments);
    }
}
