<?php
    if ( ! defined( 'ABSPATH' ) ) exit;

    class cloudS3StoragePlugin {

        public $page;

        public $setup_field = array();
        public $setup_js = array();
        public $setup_css = array();
        public $options = array();
        public $layer = array();
        public $monitor = array();
        public $smart_monitor = array();

        public function __construct()
        {
            $this->startedDB();
            $this->mimeType();
            $this->getConfigurator();
            $this->startObserver();
        }

        public function startedDB(){
            $db = new CloudS3StorageDB();
        }

        public function mimeType(){
            $cloud_s3_mime = new cloudS3StorageMime();
        }

        public function addAction ($actions = array()) {
            foreach ($actions as $key =>$function) {
                add_action($key, array($this,$function));
            }
        }

        public function includeScript($scripts = array()) {
            foreach ($scripts as $key => $option) {
                global $pagenow;
                if (!array_key_exists('required',$option) || ($pagenow == 'admin.php' && isset($_GET['page']) && in_array($_GET['page'],$option['required']))) {
                    $file = plugin_dir_url(__FILE__) . $option['path'];
                    wp_enqueue_script($key, $file, array('jquery'), '1.0', true);
                }
                if (array_key_exists('item',$option) ) {
                    wp_localize_script($key, 'media_ids', $option['item']);
                }
            }
        }

        public function includeStyle($style = array()) {
            foreach ($style as $key => $option) {
                $file = plugin_dir_url(__FILE__) . $option['path'];
                wp_register_style($key, $file);
                wp_enqueue_style($key);
            }
            
        }

        public function getConfigurator () {
            $config = new cloudS3StorageConfigurator();
            $this->setup_field      = $config->getParameter();
            $init = true;
            
            if($this->option_checker()) {
                $this->layerChecker();
                $this->monitor          = $this->getMonitor();
                $this->smart_monitor    = $this->getSmartMonitor();
                $init = false;
            }

            if ( is_admin() ) {
                $this->setup_js         = $config->getJS($init);
                $this->setup_css        = $config->getCSS();
            }
        }

        public function option_checker() {
            $options = get_option('cloud_s3_settings');
            if(is_array($options)) {
                if (isset($options['access_key'], $options['secret_key'], $options['bucket_name'], $options['endpoint']) &&
                !empty($options['access_key']) && !empty($options['secret_key']) && !empty($options['bucket_name']) && !empty($options['endpoint'])) {
                    return true;
                }
            }

            return false;
        }

        public function validate_cloud_s3_settings($input) {
            $valid = array();
            
            if (isset($input['access_key']) && !empty($input['access_key'])) {
                $valid['access_key'] = sanitize_text_field($input['access_key']);
            } else {
                add_settings_error('cloud_s3_settings', 'invalid-access-key', __('Access Key is required.','cloud-s3-storage'));
            }
            
            if (isset($input['secret_key']) && !empty($input['secret_key'])) {
                $valid['secret_key'] = sanitize_text_field($input['secret_key']);
            } else {
                add_settings_error('cloud_s3_settings', 'invalid-secret-key', __('Secret Key is required.','cloud-s3-storage'));
            }
            
            if (isset($input['bucket_name']) && !empty($input['bucket_name'])) {
                $valid['bucket_name'] = sanitize_text_field($input['bucket_name']);
            } else {
                add_settings_error('cloud_s3_settings', 'invalid-bucket-name', __('Bucket Name is required.','cloud-s3-storage'));
            }
            
            if (isset($input['endpoint']) && !empty($input['endpoint'])) {
                if (filter_var($input['endpoint'], FILTER_VALIDATE_URL)) {
                    $valid['endpoint'] = sanitize_text_field($input['endpoint']);
                } else {
                    add_settings_error('cloud_s3_settings', 'invalid-endpoint', __('Endpoint is not a valid.', 'cloud-s3-storage'));
                }
            } else {
                add_settings_error('cloud_s3_settings', 'invalid-endpoint', __('Endpoint Key is required.','cloud-s3-storage'));
            }
                        
            if (count($valid) !== 4) {
                return get_option('cloud_s3_settings');
            }
            $fields = [
                'active_mode',
                'active_bihost',
                //'active_direct_url',
                'cron_job_timing',
                'image_max_cron'];
            foreach($fields as $field) {
                if(!array_key_exists($field,$input) || $input[$field] == '') $valid[$field] = sanitize_text_field("");
                else $valid[$field] = sanitize_text_field($input[$field]);
            }
            return $valid;
        }
        
        public function cloud_s3_settings_init() {
            register_setting('cloud_s3_options', 'cloud_s3_settings', array($this, 'validate_cloud_s3_settings'));

            add_settings_section(
                'cloud_s3_main_section',
                'S3 Configuration',
                array($this,'cloud_s3_section_callback'),
                'cloud-s3-settings'
            );
        
            $this->page->goForm($this->setup_field);
        }

        public function startTemplate () {
            $this->page = new cloudS3StoragePage($this->options);
        }

        public function startObserver() {
            $observer = new cloudS3StorageAttachmentClass((isset($this->layer['ajx-status'])&&$this->layer['ajx-status']=="OK"));
        }

        public function get_cloud_s3_storage_job_url($job_name) {
            $base_url = home_url('/wp-json/cloud-s3-storage/v1');
        
            switch ($job_name) {
                case 'reindex-image':
                    return $base_url . '/reindex-image/';
                    break;
                case 'clear-image':
                    return $base_url . '/clear-image/';
                    break;
                case 'rollback-image':
                    return $base_url . '/rollback-image/';
                    break;
                default:
                    return false;
            }
        }
        public function getSmartMonitor () {
            return 
                array(
                    'ajx-key'                   => $this->layer['ajx-key'],
                    'ajx-ibrid'                 => $this->layer['ajx-ibrid'],
                    'ajx-status'                => $this->layer['ajx-status'],
                    'ajx-mode'                  => $this->layer['ajx-mode'],
                    'ajx-mime-out'              => cloudS3StorageMime::get_unselected_mime_types()?:__('none', 'cloud-s3-storage'),
                    'ajx-mime-type'             => cloudS3StorageMime::get_mime_type(),
                    'ajx-media-count'           => count($this->layer['ajx-media']),
                    'ajx-wp-count'              => count($this->layer['ajx-media'])-count($this->layer['image-converted']),
                    'ajx-s3-count'              => count($this->layer['ajx-s3']),
                    'image-like-mode-count'     => count($this->layer['image-like-mode']),
                    'image-not-converted-count' => count($this->layer['image-not-converted']),
                    'ajx-url-index'             => $this->get_cloud_s3_storage_job_url('reindex-image'),
                    'ajx-url-delete'            => $this->get_cloud_s3_storage_job_url('clear-image'),
                    'ajx-url-rollback'          => $this->get_cloud_s3_storage_job_url('rollback-image')
                );
        }

        public function getMonitor () {
            return 
                array(
                    'ajx-mime-out'          => cloudS3StorageMime::get_unselected_mime_types()?:__('none', 'cloud-s3-storage'),
                    'ajx-mime-type'         => cloudS3StorageMime::get_mime_type(),
                    'ajx-key'               => $this->layer['ajx-key'],
                    'ajx-ibrid'             => $this->layer['ajx-ibrid'],
                    'ajx-status'            => $this->layer['ajx-status'],
                    'ajx-mode'              => $this->layer['ajx-mode'],
                    'ajx-media'             => $this->layer['ajx-media'],
                    'ajx-s3'                => $this->layer['ajx-s3'],
                    'image-like-mode'       => $this->layer['image-like-mode'],
                    'image-not-converted'   => $this->layer['image-not-converted']
                );
        }

        public function layerChecker() {
            $this->layer['ajx-mode']            = cloudS3Class::getModeLabel();
            $this->layer['ajx-ibrid']           = cloudS3Class::getIbridModeCheck();
            $this->layer['ajx-key']             = 'KO';
            $this->layer['ajx-status']          = 'KO';
            $this->layer['ajx-media']           = cloudS3StorageImageFunction::getFileAttachFullVersion();
            $this->layer['ajx-s3']              = [];
            $this->layer['image-like-mode']     = [];
            $this->layer['image-not-converted'] = [];
            $this->layer['image-converted'] = [];

            if(cloudS3Class::checkParameter()) {
                $this->layer['ajx-key'] ='OK';
                if(cloudS3Class::getConnectionStatus()) {
                    $this->layer['ajx-status']          = 'OK';
                    $this->layer['ajx-s3']              = CloudS3StorageDB::get_transferred_images_for_s3();
                    $this->layer['image-like-mode']     = $this->filterImageByModeAndType();
                    $this->layer['image-converted']     = $this->fileConverted();
                    $this->layer['image-not-converted'] = $this->fileToConverter();
                    $this->layer['image-to-del']        = $this->fileToDelete();
                }
            }
        }

        public function fileToDelete() {
            if(!$this->layer['ajx-s3']) return [];
            $keysArray = array_column($this->layer['ajx-s3'], 'Key');
            $media_to_del = [];

            foreach($this->layer['ajx-media'] as $k => $media) {
                
                if(in_array($media['url'],$keysArray) && file_exists($media['complete_path']) ) {
                    $media_to_del[$k] = $media;
                }
                
            }

            return $media_to_del;
                
        }

        public function filterImageByModeAndType() {
            $unselectedMimeTypes = cloudS3StorageMime::get_unselected_mime_types_array(); 

            $excludedExtensions = [];
            foreach ($unselectedMimeTypes as $mimeType) {
                $extensions = preg_split('/\|/', $mimeType);
                $excludedExtensions = array_merge($excludedExtensions, $extensions);
            }
        
            $shouldExclude = function($filename) use ($excludedExtensions) {
                $fileExtension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
        
                return in_array($fileExtension, $excludedExtensions);
            };
        
            if (cloudS3Class::getMode()) {
                $filteredArray = array_filter($this->layer['ajx-media'], function($item) use ($shouldExclude) {
                    return isset($item['checker']['enable']) && $item['checker']['enable'] !== "on" && !$shouldExclude($item['url']);
                });
            } else {
                $filteredArray = array_filter($this->layer['ajx-media'], function($item) use ($shouldExclude) {
                    return isset($item['checker']['disable']) && $item['checker']['disable'] === "on" && !$shouldExclude($item['url']);
                });
            }
            return $filteredArray;
        }
        
        public function fileConverted() {
            $firstArray = $this->layer['image-like-mode'];
            $secondArray = $this->layer['ajx-s3'];

            if ($secondArray === null) {
                $filteredArray = [];
            } else {
                $filteredArray = array_filter($firstArray, function ($value) use ($secondArray) {
                    $url = $value['url'];
                    foreach ($secondArray as $item) {
                        if ($item['Key'] === $url) {
                            return true;
                        }
                    }
                    return false;
                });
            }

            return $filteredArray;
            
        }

        public function fileToConverter() {
            $firstArray = $this->layer['image-like-mode'];
            $secondArray = $this->layer['ajx-s3'];

            if ($secondArray === null) {
                $filteredArray = [];
            } else {
                $filteredArray = array_filter($firstArray, function ($value) use ($secondArray) {
                    $url = $value['url'];
                    foreach ($secondArray as $item) {
                        if ($item['Key'] === $url) {
                            return false;
                        }
                    }
                    return true;
                });
            }
            return $filteredArray;
        }
   }
