<?php

namespace WPIS;

$path = $_SERVER['DOCUMENT_ROOT'];

include_once $path . '/wp-config.php';
include_once $path . '/wp-load.php';
include_once $path . '/wp-includes/class-wpdb.php';
include_once $path . '/wp-includes/pluggable.php';

include_once __DIR__ . '/../core/SyncManager.php';

/**
 * Class ApiAdmin
 *
 * This class handles the AJAX exhanges with the administration
 */

 class ApiAdmin {

    private $apiUrl = WPIS::API_URL . '/wordpress/';

    private $payload = [];

    static public function init() : ApiAdmin {
        $class = new ApiAdmin();

        $class->payload = json_decode(file_get_contents('php://input'));
        $class->payload = $class->payload ? $class->payload : [];

        $public = false;
        $prefixPublic = 'wp_ajax_nopriv_wpis_';
        $prefixPrivate = 'wp_ajax_wpis_';
        $prefix = $public ? $prefixPublic : $prefixPrivate;

        add_action( $prefix . 'activate', [$class, 'activate'] );
        add_action( $prefix . 'disconnect', [$class, 'disconnect'] );
        add_action( $prefix . 'checkStatus', [$class, 'checkStatus'] );
        add_action( $prefix . 'updateSettings', [$class, 'updateSettings'] );
        add_action( $prefix . 'loadSettings', [$class, 'loadSettings'] );
        add_action( $prefix . 'importChecking', [$class, 'importChecking'] );
        add_action( $prefix . 'importNext', [$class, 'importNext'] );
        add_action( $prefix . 'updateStart', [$class, 'updateStart'] );
        add_action( $prefix . 'updateProgress', [$class, 'updateProgress'] );
        add_action( $prefix . 'removeAllEstates', [$class, 'removeAllEstates'] );
        add_action( $prefix . 'removeInactiveEstates', [$class, 'removeInactiveEstates'] );
        add_action( $prefix . 'getContactList', [$class, 'getContactList'] );
        add_action( $prefix . 'enableSyncAutomation', [$class, 'enableSyncAutomation'] );
        add_action( $prefix . 'disableSyncAutomation', [$class, 'disableSyncAutomation'] );
        add_action( $prefixPublic . 'importNext', [$class, 'importNext'] );

        return $class;
    }

    private function post($endpoint, $payload = [], $headers = []) {

        $params = [
            'wpis_version' => get_plugin_data(__DIR__ . '/../wp-immo-sync.php')['Version'],
            'wp_version'   => get_bloginfo('version'),
            'referer'      => $_SERVER['HTTP_HOST']
        ];

        $curl = curl_init();
        curl_setopt_array($curl, [
            CURLOPT_URL => $this->apiUrl . $endpoint . '?' . http_build_query($params),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_CUSTOMREQUEST => "POST",
            CURLOPT_POSTFIELDS => http_build_query($payload),
            CURLOPT_HTTPHEADER => $headers,
        ]);

        $response = curl_exec($curl);
        $err = curl_error($curl);
        $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);

        curl_close($curl);
        if ($err) {
          echo "cURL Error #:" . $err;
        }
        else {
            return (object) ['code' => $httpcode, 'data' => $response];
        }
    }

    private function response( $code, $data = false ) : void {
        http_response_code($code);
        header('Content-Type: application/json');
        echo json_encode($data);
        exit;
    }

    public function checkStatus(){

        $connection = DatabaseManager::db()->get_results('SELECT access_id, name, account FROM ' . DatabaseManager::db()->prefix . WPIS::WP_TABLE_CONNEXION . ' LIMIT 1');

        if( !$connection ){
            return $this->response(200, ['debug' => SettingsManager::get('debug', false), 'access' => false]);
        }

        $access = $connection[0];

        $response = [
            'debug' => SettingsManager::get('debug', false),
            'access' => $access
        ];

        return $this->response(200, $response);
    }

    public function activate(){

        $response = $this->post('activate', $this->payload, [
            "Content-Type: application/x-www-form-urlencoded",
            "cache-control: no-cache"
        ]);

        if( $response->code !== 200 ){
            return $this->response($response->code, ['success' => false, 'message' => json_decode($response->data)->message]);
        }

        if( !isset($response->data) ){
            return $this->response(400, ['success' => false, 'message' => 'An error occured while trying to login.']);
        }

        $data = json_decode($response->data);

        if( !isset($data->token) ){
            return $this->response(400, ['success' => false, 'message' => 'An error occured while trying to activate.']);
        }

        if( !DatabaseManager::db()->get_results('SELECT * FROM ' . DatabaseManager::db()->prefix . WPIS::WP_TABLE_CONNEXION . ' LIMIT 1') ){
            DatabaseManager::db()->insert(DatabaseManager::db()->prefix . WPIS::WP_TABLE_CONNEXION, [
                'access_id' => $data->id,
                'name' => $data->name,
                'account' => $data->account,
                'token' => $data->token
            ]);
        }
        $access = DatabaseManager::db()->get_results('SELECT access_id, name, account FROM ' . DatabaseManager::db()->prefix . WPIS::WP_TABLE_CONNEXION . ' LIMIT 1')[0];
        $this->response(200, ['success' => true, 'access' => $access]);
    }

    public function disconnect(){

        if( !$this->payload->accessId ){
            return $this->response(400, ['message' => 'Access Id is required.']);
        }

        DatabaseManager::db()->delete(DatabaseManager::db()->prefix . WPIS::WP_TABLE_CONNEXION, ['access_id' => $this->payload->accessId]);

        $this->response(200, ['message' => 'Access removed.']);
    }

    public function loadSettings(){

        $settings = SettingsManager::getAll();
        $defaultSettings = SettingsManager::getDefault();

        $postTypes = get_post_types();

        unset($postTypes['attachment']);
        unset($postTypes['page']);
        unset($postTypes['revision']);
        unset($postTypes['nav_menu_item']);
        unset($postTypes['custom_css']);
        unset($postTypes['customize_changeset']);
        unset($postTypes['oembed_cache']);
        unset($postTypes['wp_block']);
        unset($postTypes['user_request']);
        unset($postTypes['wpis_estates']);
        unset($settings['cronKey']);

        if( !isset($settings['formEmailDefaultSender']) || $settings['formEmailDefaultSender'] === '' ){
            $settings['formEmailDefaultSender'] = $defaultSettings['formEmailDefaultSender'];
        }
        if( !isset($settings['formEmailDefaultSenderName']) || $settings['formEmailDefaultSenderName'] === '' ){
            $settings['formEmailDefaultSenderName'] = $defaultSettings['formEmailDefaultSenderName'];
        }
        if( !isset($settings['formEmailDefaultReceiver']) || $settings['formEmailDefaultReceiver'] === '' ){
            $settings['formEmailDefaultReceiver'] = $defaultSettings['formEmailDefaultReceiver'];
        }

        $response = [
            'debug'         => SettingsManager::get('debug', false),
            'settings'      => $settings,
            'configuration' => [
                'max_execution_time' => [
                    'current'  => ini_get('max_execution_time'),
                    'required' => '600'
                ]
            ],
            'formData' => [
                'pageList'      => get_pages(),
                'postTypesList' => $postTypes
            ]
        ];

        $this->response(200, $response);
    }

    public function updateSettings(){

        $acceptedKeys = [
            'estatePageId',
            'enableImportSystem',
            'enableTaxonomies',
            'autoRemoveUpdatedEstates',
            'enablePartialRemove',
            'enableImportCustomPostType',
            'customPostType',
            'enableSyncAutomation',
            'enableCronImport',
            'enableCronUpdate',
            'enableCronRemove',
            'enableProjectManagement',
            'enableProjectManagementCustomPostType',
            'projectCustomPostType',
            'enableAgentManagement',
            'enableAgentManagementCustomPostType',
            'agentCustomPostType',
            'enableVueShortcodes',
            'formEnableContactSaving',
            'formEnableRecipientEmail',
            'formEnableClientEmail',
            'formEmailDefaultReceiver',
            'formEmailDefaultSender',
            'formEmailDefaultSenderName'
        ];

        foreach( $this->payload as $key => $value ){
            if( !in_array($key, $acceptedKeys) ){
                continue;
            }

            if( $key === 'enableSyncAutomation' && $value === '1' ){
                $token = $this->generateRandomString('12');
                if( is_null( SettingsManager::get('cronKey') ) ){
                    SettingsManager::set('cronKey', $token);
                }
            }

            SettingsManager::set($key, $value);
        }

        $this->response(200, ['success' => true]);
    }

    public function importNext(){
        $response = SyncManager::init()->next($this->payload);
        $this->response(200, $response);
    }

    public function importChecking(){
        $response = SyncManager::init()->prepareEstateSync();
        $this->response(200, $response);
    }

    public function updateStart(){
        $response = SyncManager::init()->updateStart($this->payload);
        $this->response(200, $response);
    }

    public function updateProgress(){
        $response = SyncManager::init()->updateProgress($this->payload);
        $this->response(200, $response);
    }

    public function removeInactiveEstates(){
        $response = SyncManager::init()->removeEstates();
        $this->response(200, $response);
    }

    public function removeAllEstates(){
        $response = SyncManager::init()->removeAll();
        $this->response(200, $response);
    }

    public function getContactList(){
        $response = FormManager::init()->getSavedContacts();
        $this->response(200, $response);
    }

    public function enableSyncAutomation(){
       return $this->response(200, ImmosyncClient::init()->enableSyncAutomation());
    }

    public function disableSyncAutomation(){
       return $this->response(200, ImmosyncClient::init()->disableSyncAutomation());
    }

    public function logError($error = []){
        $response = $this->post('log', ['accessId' => $this->payload->accessId, 'domain' => $protocol . $_SERVER['HTTP_HOST'], 'error' => $error], [
            'Content-Type: application/x-www-form-urlencoded',
            'Authorization: Bearer ' . $this->payload->token
        ]);
    }

    private function generateRandomString($length = 10) {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $charactersLength = strlen($characters);
        $randomString = '';
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[rand(0, $charactersLength - 1)];
        }
        return $randomString;
    }

}