<?php

namespace WPIS;

require_once __DIR__ . '/../../../../wp-load.php';
class CronManager {

    const IMPORT_LIMIT = 5;
    const DELETE_LIMIT = 3;

    private $action = null;
    private $isCheckpointPassed = true;
    private $exceptions = [];
    private $currentImport = 1;
    private $importSettings = [];
    private $importList = [];
    private $allowedActions = ['import', 'update', 'remove'];
    private $cacheDirectory;

    public function __construct() {

        $this->cacheDirectory = __DIR__ . '/../../../uploads/wp-immo-sync';

        date_default_timezone_set('Europe/Brussels');
        set_error_handler([$this, 'errorHandler'], E_ALL);

        $this->checkAuthorisation();

        if( $this->isCheckpointPassed ){

            Logger::log('wpis-cron', '[CRON] TRIGGERED | Type: ' . $this->action);

            switch( $this->action ){

                case 'import':
                    if( SettingsManager::get('enableCronImport') ){
                        $this->importSettings = (object) ['updateOnly' => false, 'forcePictureImport' => false];
                        $result = $this->import();
                        Logger::log('wpis-cron', '[CRON] IMPORT | Estate Imported: ' . count($this->importList));
                    }
                    else {
                        Logger::log('wpis-cron', '[CRON] IMPORT | Phase Disabled');
                        $result = ['message' => 'Import Phase Disabled'];
                    }
                    break;

                case 'update':
                    if( SettingsManager::get('enableCronUpdate') ){
                        $result = $this->update();
                    }
                    else {
                        Logger::log('wpis-cron', '[CRON] UPDATE | Phase Disabld');
                        $result = ['message' => 'Update Phase Disabled'];
                    }
                    break;

                case 'remove':
                    if( SettingsManager::get('enableCronRemove') ){
                        $result = $this->remove();
                    }
                    else {
                        Logger::log('wpis-cron', '[CRON] REMOVE | Phase Disabld');
                        $result = ['message' => 'Remove Phase Disabled'];
                    }
                    break;

                case 'auto':
                    $result = [];
                    if( SettingsManager::get('enableCronRemove') ){
                        $result['remove'] = $this->remove();
                    }
                    if( ! SettingsManager::get('enableCronRemove') && SettingsManager::get('autoRemoveUpdatedEstates') ){
                        $result['remove_updated_images'] = $this->remove(true);
                    }
                    if( SettingsManager::get('enableCronUpdate') ){
                        $result['update'] = $this->update();
                    }
                    if( SettingsManager::get('enableCronImport') ){
                        $result['import'] = $this->import();
                        Logger::log('wpis-cron', '[CRON] IMPORT | Estate Imported: ' . count($this->importList));
                    }
                    $response = [
                        'success' => true,
                        'result'  => $result
                    ];
                    break;
            }

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

    public function errorHandler($e, $errstr) {
        if( in_array($e, [E_WARNING, E_ERROR]) ){
            $this->exceptions[] = json_encode($errstr);
        }
    }

    public function checkAuthorisation() {

        $this->isCheckpointPassed = true;

        if( ! SettingsManager::get('enableSyncAutomation') ){
            Logger::log('wpis-cron', '[CRON] Crons are disabled');
            $this->isCheckpointPassed = false;
            return $this->response(['success' => false, 'message' => 'Cron are disabled.']);
        }

        $token = SettingsManager::get('cronKey');

        if( !isset($_GET['token']) || $_GET['token'] !== $token ){
            Logger::log('wpis-cron', '[CRON] Invalid Token ' . (isset($_GET['token']) ? $_GET['token'] : ''));
            $this->isCheckpointPassed = false;
            return $this->response(['success' => false, 'message' => 'Invalid token.']);
        }

        if( isset($_GET['action']) ){
            if( !in_array($_GET['action'], $this->allowedActions) ){
                Logger::log('wpis-cron', '[CRON] Invalid Action ' . (isset($_GET['action']) ? $_GET['action'] : ''));
                $this->isCheckpointPassed = false;
                return $this->response(['success' => false, 'message' => 'Invalid action.']);
            }
            $this->action = $_GET['action'];
        }
        else {
            $this->action = 'auto';
        }

    }

    private function import() {

        $syncManager = SyncManager::init();
        $result = $syncManager->next($this->importSettings);
        $importLimit = self::IMPORT_LIMIT;

        if( $result['success'] && ! $result['isComplete'] && $this->currentImport <= self::IMPORT_LIMIT ){
            Logger::log('wpis-cron', '[CRON] IMPORT | ' . "Post ID: {$result['lastImport']['postId']} | Estate ID: {$result['lastImport']['estateId']} | Duration: {$result['time']} ({$this->currentImport}/{$importLimit})");
            $this->currentImport++;

            $estateImported = [
                'postId' => $result['lastImport']['postId'],
                'estateId' => $result['lastImport']['estateId'],
                'time' => $result['time']
            ];

            if( !empty($this->exceptions) ){
                $estateImported['exceptions'] = $this->exceptions;
                $this->exceptions = [];
            }

            $this->importList[] = $estateImported;

            $this->import();
        }
        else {
            if( !$result['success'] ){
                Logger::log('wpis-cron', '[CRON] IMPORT | ' . $result['message']);
                return [
                    'status'  => 'KO',
                    'message' => $result['message']
                ];
            }
            if( $this->action === 'import' && isset($result['lastImport'])){
                Logger::log('wpis-cron', '[CRON] IMPORT | ' . "Post ID: {$result['lastImport']['postId']} | Estate ID: {$result['lastImport']['estateId']} | Duration: {$result['time']} ({$this->currentImport}/{$importLimit})");
            }
            if( $result['isComplete'] ){
                $syncManager->cache->flush();
            }

        }

        return [
            'status'      => 'OK',
            'importCount' => count($this->importList),
            'importList'  => $this->importList,
        ];
    }

    private function update() {

        $syncManager = SyncManager::init();
        $result = $syncManager->updateStart();
        $syncManager->cache->flush();

        if( isset($result['success']) && !$result['success']){
            Logger::log('wpis-cron', '[CRON] UPDATE | ERROR : ' . $result['message']);
            return [
                'status' => 'KO',
                'message' => $result['message']
            ];
        }
        else {
            Logger::log('wpis-cron', '[CRON] UPDATE | Estate Updated: ' . $result['estatesUpdatedCount'] . ' | Duration: ' . $result['time']);
        }

        return [
            'status'      => 'OK',
            'updateCount' => $result['estatesUpdatedCount'],
            'time'        => $result['time']
        ];
    }

    private function remove($restrictToImageChanges = false) {
        $i = 1;
        $start = microtime(true);
        $syncManager = SyncManager::init();
        $result = $syncManager->removeEstates($restrictToImageChanges);

        if( isset($result['success']) && !$result['success']){
            Logger::log('wpis-cron', '[CRON] REMOVE | ERROR : ' . $result['message']);
            return [
                'status'  => 'KO',
                'message' => $result['message']
            ];
        }

        $total = count($result['estatesRemovedList']);
        $removedList = [];
        foreach( $result['estatesRemovedList'] as $estate){
            Logger::log('wpis-cron', '[CRON] REMOVE | ' . "Post ID: {$estate->postId} | Estate ID: {$estate->estateId}  ({$i}/{$total})");
            $removedList[] = [
                'postId' =>  $estate->postId,
                'estateId' =>  $estate->estateId,
            ];
            $i++;
            if( $i > self::DELETE_LIMIT ){
                break;
            }
        }


        $syncManager->cache->flush();
        $elapsedTime = round(microtime(true) - $start, 3);

        Logger::log('wpis-cron', '[CRON] REMOVE | Estate Removed: ' . ($i - 1) . ' | Duration: ' . $elapsedTime);

        return [
            'status'      => 'OK',
            'removeCount' => $i - 1,
            'removeList'  => $removedList,
            'time'        => $elapsedTime,
        ];
    }

    private function response( Array $response ) {
        header('Content-Type: application/json');
        echo json_encode( $response );
    }
}

new CronManager();