<?php

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

trait Niwa_AI_Tools_Cache {

    /**
     * Preview a native Seraphinite Accelerator refresh.
     */
    private function preview_accelerator_cache_refresh( $args ) {
        unset( $args );

        if ( ! class_exists( '\\seraph_accel\\API' ) ) {
            return array(
                'success' => false,
                'error'   => 'Seraphinite Accelerator nije instaliran ili aktivan na ovom sajtu.',
            );
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'accelerator_cache_refresh',
                'label'            => 'Osvezi Seraphinite Accelerator cache',
                'summary'          => 'Brise aktivni Accelerator cache i pokrece njegov native Cleanup old proces.',
                'rollback_plan'    => 'Cache se automatski regenerise pri narednim posetama.',
                'rollback_support' => 'none',
                'targets'          => array(),
                'args'             => array(),
            ),
        );
    }

    /**
     * Execute a native Seraphinite Accelerator refresh.
     */
    private function execute_accelerator_cache_refresh_action( $action ) {
        unset( $action );

        $result = Niwa_AI_External_Page_Cache::refresh_seraphinite( true );
        if ( empty( $result['success'] ) ) {
            return $result;
        }
        if ( empty( $result['detected'] ) ) {
            return array(
                'success' => false,
                'error'   => 'Seraphinite Accelerator nije instaliran ili aktivan na ovom sajtu.',
            );
        }

        return array(
            'success'          => true,
            'summary'          => 'Seraphinite Accelerator cache je obrisan i Cleanup old proces je pokrenut.',
            'data'             => $result,
            'executed_actions' => array(
                array( 'type' => 'accelerator_cache_refresh' ),
            ),
            'rollback_entries' => array(),
        );
    }

    /* ==================================================================
     *  HELPER — Safe LiteSpeed config reader
     * ================================================================== */

    /**
     * Safely read a single LiteSpeed config value.
     *
     * Different LiteSpeed Cache versions expose different constants,
     * so every read is wrapped in a try/catch to prevent fatal errors.
     *
     * @param  object $conf    LiteSpeed\Conf instance.
     * @param  string $key     The Base constant name (e.g. 'O_CACHE').
     * @param  mixed  $default Fallback when the constant or method is unavailable.
     * @return mixed
     */
    private function get_litespeed_conf_safe( $conf, $key, $default = false ) {
        try {
            $full = 'LiteSpeed\\Base::' . $key;
            if ( defined( $full ) ) {
                return $conf->conf( constant( $full ) );
            }
        } catch ( \Throwable $e ) {
            /* Intentionally ignored — constant or method may not exist in this version. */
        }

        return $default;
    }

    /**
     * Check whether LiteSpeed Cache plugin is available at the minimum level.
     *
     * @return array  array('success' => true) or error array.
     */
    private function check_litespeed_available() {
        if ( ! defined( 'LSCWP_V' ) ) {
            return array(
                'success' => false,
                'error'   => 'LiteSpeed Cache plugin nije instaliran ili nije aktivan na ovom sajtu.',
            );
        }

        return array( 'success' => true );
    }

    /* ==================================================================
     *  1. CACHE_SETTINGS_GET — Read-only
     * ================================================================== */

    /**
     * Preview cache_settings_get — read-only, no approval needed.
     */
    private function preview_cache_settings_get( $args ) {
        $check = $this->check_litespeed_available();
        if ( empty( $check['success'] ) ) {
            return $check;
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'cache_settings_get',
                'label'            => 'Prikazi LiteSpeed Cache podesavanja',
                'summary'          => 'Citanje trenutnih LiteSpeed Cache konfiguracionih vrednosti (cache, optimizacija, lazy load, itd.).',
                'rollback_plan'    => 'Ovo je read-only operacija, nema potrebe za rollback.',
                'rollback_support' => 'none',
                'targets'          => array(),
                'args'             => array(),
            ),
        );
    }

    /**
     * Execute cache_settings_get — gather and return LiteSpeed Cache settings.
     */
    private function execute_cache_settings_get_action( $action ) {
        $check = $this->check_litespeed_available();
        if ( empty( $check['success'] ) ) {
            return $check;
        }

        if ( ! class_exists( 'LiteSpeed\\Conf' ) ) {
            return array(
                'success' => false,
                'error'   => 'LiteSpeed Cache Conf klasa nije dostupna. Moguce je da verzija plugina ne podrzava ovaj pristup.',
            );
        }

        try {
            $conf = \LiteSpeed\Conf::cls();
        } catch ( \Throwable $e ) {
            return array(
                'success' => false,
                'error'   => 'Greska pri instanciranju LiteSpeed Conf: ' . $e->getMessage(),
            );
        }

        $settings = array(
            'plugin_version'             => defined( 'LSCWP_V' ) ? LSCWP_V : 'unknown',
            'cache_enabled'              => (bool) $this->get_litespeed_conf_safe( $conf, 'O_CACHE', false ),
            'cache_mobile_enabled'       => (bool) $this->get_litespeed_conf_safe( $conf, 'O_CACHE_MOBILE', false ),
            'cache_browser_enabled'      => (bool) $this->get_litespeed_conf_safe( $conf, 'O_CACHE_BROWSER', false ),
            'cache_ttl_public'           => (int) $this->get_litespeed_conf_safe( $conf, 'O_CACHE_TTL_PUB', 0 ),
            'cache_ttl_private'          => (int) $this->get_litespeed_conf_safe( $conf, 'O_CACHE_TTL_PRIV', 0 ),
            'cache_ttl_frontpage'        => (int) $this->get_litespeed_conf_safe( $conf, 'O_CACHE_TTL_FRONTPAGE', 0 ),
            'cache_ttl_browser'          => (int) $this->get_litespeed_conf_safe( $conf, 'O_CACHE_TTL_BROWSER', 0 ),
            'object_cache_enabled'       => (bool) $this->get_litespeed_conf_safe( $conf, 'O_OBJECT', false ),
            'css_minify_enabled'         => (bool) $this->get_litespeed_conf_safe( $conf, 'O_OPTM_CSS_MIN', false ),
            'js_minify_enabled'          => (bool) $this->get_litespeed_conf_safe( $conf, 'O_OPTM_JS_MIN', false ),
            'html_minify_enabled'        => (bool) $this->get_litespeed_conf_safe( $conf, 'O_OPTM_HTML_MIN', false ),
            'css_combine_enabled'        => (bool) $this->get_litespeed_conf_safe( $conf, 'O_OPTM_CSS_COMB', false ),
            'js_combine_enabled'         => (bool) $this->get_litespeed_conf_safe( $conf, 'O_OPTM_JS_COMB', false ),
            'image_optimization_enabled' => (bool) $this->get_litespeed_conf_safe( $conf, 'O_IMG_OPTM_AUTO', false ),
            'lazy_load_images_enabled'   => (bool) $this->get_litespeed_conf_safe( $conf, 'O_MEDIA_LAZY', false ),
        );

        return array(
            'success'          => true,
            'summary'          => 'LiteSpeed Cache podesavanja ucitana (verzija ' . $settings['plugin_version'] . ', cache ' . ( $settings['cache_enabled'] ? 'uklj.' : 'isklj.' ) . ').',
            'data'             => $settings,
            'executed_actions' => array(
                array(
                    'type' => 'cache_settings_get',
                ),
            ),
            'rollback_entries' => array(),
        );
    }

    /* ==================================================================
     *  2. CACHE_FLUSH — Flush all LiteSpeed caches
     * ================================================================== */

    /**
     * Preview cache_flush — safe but irreversible.
     */
    private function preview_cache_flush( $args ) {
        $check = $this->check_litespeed_available();
        if ( empty( $check['success'] ) ) {
            return $check;
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'cache_flush',
                'label'            => 'Isprazni sve LiteSpeed keseve',
                'summary'          => 'Brisanje kompletnog LiteSpeed kesa (page cache, object cache, CSS/JS cache). Sajt ce ponovo kirati kes pri sledecim zahtevima.',
                'rollback_plan'    => 'Kes ce se automatski regenerisati pri narednim posetama. Rollback nije moguc niti potreban.',
                'rollback_support' => 'none',
                'targets'          => array(),
                'args'             => array(),
            ),
        );
    }

    /**
     * Execute cache_flush — purge all LiteSpeed caches.
     */
    private function execute_cache_flush_action( $action ) {
        $check = $this->check_litespeed_available();
        if ( empty( $check['success'] ) ) {
            return $check;
        }

        $purged = false;

        /* Primary method: LiteSpeed\Purge class. */
        if ( class_exists( 'LiteSpeed\\Purge' ) ) {
            try {
                \LiteSpeed\Purge::purge_all();
                $purged = true;
            } catch ( \Throwable $e ) {
                /* Will try fallback below. */
            }
        }

        /* Fallback: WordPress action hook (works with older versions too). */
        if ( ! $purged ) {
            try {
                do_action( 'litespeed_purge_all' );
                $purged = true;
            } catch ( \Throwable $e ) {
                return array(
                    'success' => false,
                    'error'   => 'LiteSpeed cache flush nije uspeo: ' . $e->getMessage(),
                );
            }
        }

        if ( ! $purged ) {
            return array(
                'success' => false,
                'error'   => 'LiteSpeed Purge klasa nije dostupna i action hook nije izvrsio flush.',
            );
        }

        return array(
            'success'          => true,
            'summary'          => 'Svi LiteSpeed kesevi su isprazneni. Kes ce se regenerisati pri narednim posetama sajtu.',
            'executed_actions' => array(
                array(
                    'type' => 'cache_flush',
                ),
            ),
            'rollback_entries' => array(),
        );
    }

    /* ==================================================================
     *  3. CACHE_PRESETS_LIST — Read-only, list available presets
     * ================================================================== */

    /**
     * Return the static list of LiteSpeed Cache presets.
     *
     * Presets are hardcoded because the LiteSpeed\Preset class
     * does not always expose them through a public getter.
     *
     * @return array
     */
    private function get_litespeed_preset_definitions() {
        return array(
            'essentials' => array(
                'name'        => 'Essentials',
                'risk_level'  => 'no-risk',
                'description' => 'Default Cache, Higher TTL, Browser Cache',
            ),
            'basic'      => array(
                'name'        => 'Basic',
                'risk_level'  => 'low-risk',
                'description' => 'Essentials + Image Optimization, Mobile Cache',
            ),
            'advanced'   => array(
                'name'        => 'Advanced (Recommended)',
                'risk_level'  => 'low-risk',
                'description' => 'Basic + Guest Mode, CSS/JS/HTML Minification, Font Display, JS Defer, DNS Prefetch',
            ),
            'aggressive' => array(
                'name'        => 'Aggressive',
                'risk_level'  => 'medium-risk',
                'description' => 'Advanced + CSS & JS Combine, Async CSS, Removed Unused CSS, Lazy Load Iframes',
            ),
            'extreme'    => array(
                'name'        => 'Extreme',
                'risk_level'  => 'high-risk',
                'description' => 'Aggressive + Lazy Load Images, Viewport Generation, JS Delayed, Inline JS/CSS Combine',
            ),
        );
    }

    /**
     * Preview cache_presets_list — read-only.
     */
    private function preview_cache_presets_list( $args ) {
        $check = $this->check_litespeed_available();
        if ( empty( $check['success'] ) ) {
            return $check;
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'cache_presets_list',
                'label'            => 'Prikazi LiteSpeed Cache preset-e',
                'summary'          => 'Pregled dostupnih LiteSpeed Cache preset konfiguracija (essentials, basic, advanced, aggressive, extreme).',
                'rollback_plan'    => 'Ovo je read-only operacija, nema potrebe za rollback.',
                'rollback_support' => 'none',
                'targets'          => array(),
                'args'             => array(),
            ),
        );
    }

    /**
     * Execute cache_presets_list — return preset definitions.
     */
    private function execute_cache_presets_list_action( $action ) {
        $check = $this->check_litespeed_available();
        if ( empty( $check['success'] ) ) {
            return $check;
        }

        if ( ! class_exists( 'LiteSpeed\\Preset' ) ) {
            return array(
                'success' => false,
                'error'   => 'LiteSpeed Preset klasa nije dostupna. Ova verzija LiteSpeed Cache mozda ne podrzava preset-e.',
            );
        }

        $presets = $this->get_litespeed_preset_definitions();

        return array(
            'success'          => true,
            'summary'          => 'Dostupno je ' . count( $presets ) . ' LiteSpeed Cache preset-a: ' . implode( ', ', array_keys( $presets ) ) . '.',
            'data'             => array(
                'presets' => $presets,
                'count'   => count( $presets ),
            ),
            'executed_actions' => array(
                array(
                    'type' => 'cache_presets_list',
                ),
            ),
            'rollback_entries' => array(),
        );
    }

    /* ==================================================================
     *  4. CACHE_PRESET_APPLY — Apply a LiteSpeed Cache preset
     * ================================================================== */

    /**
     * Validate cache_preset_apply arguments.
     */
    private function validate_cache_preset_apply_action_args( $args ) {
        $preset = isset( $args['preset'] ) ? trim( strtolower( (string) $args['preset'] ) ) : '';
        $valid  = array( 'essentials', 'basic', 'advanced', 'aggressive', 'extreme' );

        if ( '' === $preset ) {
            return array(
                'success' => false,
                'error'   => 'Preset parametar je obavezan. Dozvoljene vrednosti: ' . implode( ', ', $valid ) . '.',
            );
        }

        if ( ! in_array( $preset, $valid, true ) ) {
            return array(
                'success' => false,
                'error'   => 'Nepoznat preset "' . $preset . '". Dozvoljene vrednosti: ' . implode( ', ', $valid ) . '.',
            );
        }

        return array( 'success' => true );
    }

    /**
     * Preview cache_preset_apply — shows which preset will be applied and its risk level.
     */
    private function preview_cache_preset_apply( $args ) {
        $check = $this->check_litespeed_available();
        if ( empty( $check['success'] ) ) {
            return $check;
        }

        /* Validate preset parameter. */
        $validation = $this->validate_cache_preset_apply_action_args( $args );
        if ( empty( $validation['success'] ) ) {
            return $validation;
        }

        $preset_name = trim( strtolower( (string) $args['preset'] ) );
        $presets     = $this->get_litespeed_preset_definitions();

        if ( ! isset( $presets[ $preset_name ] ) ) {
            return array(
                'success' => false,
                'error'   => 'Preset "' . $preset_name . '" nije pronadjen u definicijama.',
            );
        }

        $preset_info = $presets[ $preset_name ];

        if ( ! class_exists( 'LiteSpeed\\Preset' ) ) {
            return array(
                'success' => false,
                'error'   => 'LiteSpeed Preset klasa nije dostupna. Ova verzija LiteSpeed Cache mozda ne podrzava preset-e.',
            );
        }

        $risk_label = isset( $preset_info['risk_level'] ) ? (string) $preset_info['risk_level'] : 'unknown';
        $risk_note  = '';
        if ( 'medium-risk' === $risk_label || 'high-risk' === $risk_label ) {
            $risk_note = ' UPOZORENJE: Ovaj preset ima ' . $risk_label . ' nivo rizika i moze uticati na vizuelni prikaz sajta.';
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'             => 'cache_preset_apply',
                'label'            => 'Primeni LiteSpeed Cache preset "' . $preset_info['name'] . '"',
                'summary'          => 'Primena LiteSpeed Cache preset-a "' . $preset_info['name'] . '" (' . $risk_label . '): ' . $preset_info['description'] . '.' . $risk_note,
                'rollback_plan'    => 'Prethodna podesavanja ce biti prepisana novim preset vrednostima. Delimican rollback je moguc ponovnom primenom drugog preset-a.',
                'rollback_support' => 'partial',
                'targets'          => array(
                    array(
                        'preset'      => $preset_name,
                        'name'        => $preset_info['name'],
                        'risk_level'  => $risk_label,
                        'description' => $preset_info['description'],
                    ),
                ),
                'args'             => array(
                    'preset' => $preset_name,
                ),
            ),
        );
    }

    /**
     * Execute cache_preset_apply — apply the selected LiteSpeed Cache preset.
     */
    private function execute_cache_preset_apply_action( $action ) {
        $check = $this->check_litespeed_available();
        if ( empty( $check['success'] ) ) {
            return $check;
        }

        if ( ! class_exists( 'LiteSpeed\\Preset' ) ) {
            return array(
                'success' => false,
                'error'   => 'LiteSpeed Preset klasa nije dostupna.',
            );
        }

        $args        = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $preset_name = isset( $args['preset'] ) ? trim( strtolower( (string) $args['preset'] ) ) : '';

        if ( '' === $preset_name ) {
            return array(
                'success' => false,
                'error'   => 'Preset parametar nedostaje u akciji.',
            );
        }

        $presets = $this->get_litespeed_preset_definitions();
        if ( ! isset( $presets[ $preset_name ] ) ) {
            return array(
                'success' => false,
                'error'   => 'Nepoznat preset "' . $preset_name . '".',
            );
        }

        $preset_info = $presets[ $preset_name ];

        try {
            $preset_instance = new \LiteSpeed\Preset();
            $result          = $preset_instance->apply( $preset_name );
        } catch ( \Throwable $e ) {
            return array(
                'success' => false,
                'error'   => 'Greska pri primeni preset-a "' . $preset_name . '": ' . $e->getMessage(),
            );
        }

        /*
         * LiteSpeed's apply() may return void, a bool, or an array
         * depending on the version. Treat non-false as success.
         */
        if ( false === $result ) {
            return array(
                'success' => false,
                'error'   => 'LiteSpeed Preset::apply() je vratio false za preset "' . $preset_name . '". Moguce je da preset nije podrzana na ovoj verziji.',
            );
        }

        /* Flush caches after applying preset for immediate effect. */
        try {
            if ( class_exists( 'LiteSpeed\\Purge' ) ) {
                \LiteSpeed\Purge::purge_all();
            } else {
                do_action( 'litespeed_purge_all' );
            }
        } catch ( \Throwable $e ) {
            /* Non-critical — preset was applied, cache flush is a bonus. */
        }

        $risk_label = isset( $preset_info['risk_level'] ) ? (string) $preset_info['risk_level'] : 'unknown';

        return array(
            'success'          => true,
            'summary'          => 'LiteSpeed Cache preset "' . $preset_info['name'] . '" (' . $risk_label . ') je uspesno primenjen. Kes je ispraznjen radi primene novih podesavanja.',
            'executed_actions' => array(
                array(
                    'type'       => 'cache_preset_apply',
                    'preset'     => $preset_name,
                    'name'       => $preset_info['name'],
                    'risk_level' => $risk_label,
                ),
            ),
            'data'             => array(
                'preset'      => $preset_name,
                'name'        => $preset_info['name'],
                'risk_level'  => $risk_label,
                'description' => $preset_info['description'],
            ),
            'rollback_entries' => array(),
        );
    }
}
