<?php


namespace ColibriWP\Theme\Core;


use ColibriWP\Theme\Components\CSSOutput;
use ColibriWP\Theme\Theme;
use function get_theme_mod;

abstract class ComponentBase implements ConfigurableInterface, PartialComponentInterface {

    const PEN_ON_LEFT = "left";
    const PEN_ON_RIGHT = "right";

    protected static $selective_refresh_container_inclusive = true;

    public static function selectiveRefreshKey() {
        return Utils::slugify( static::class );
    }

    public static function options() {

        $options = array_replace(
            array(
                "settings" => array(),
                "sections" => array(),
                "panels"   => array(),
            ),
            (array) static::getOptions()
        );

        foreach ( array_keys( $options['settings'] ) as $id ) {

            if ( ! array_key_exists( 'css_output', $options['settings'][ $id ] ) ) {
                continue;
            }


            if ( is_array( $options['settings'][ $id ]['css_output'] ) ) {

                foreach ( $options['settings'][ $id ]['css_output'] as $index => $css_output ) {
                    $options['settings'][ $id ]['css_output'][ $index ] = CSSOutput::normalizeOutput( $css_output );
                }

            }
        }

        $__class__ = static::class;

        Theme::getInstance()->getCustomizer()->isCustomizer(
            function () use ( &$options, $__class__ ) {
                foreach ( array_keys( $options['settings'] ) as $id ) {

                    $has_control = isset( $options['settings'][ $id ]['control'] ) ? true : false;
                    $has_control = $has_control && is_array( $options['settings'][ $id ]['control'] );

                    if ( $has_control ) {

                        if ( array_key_exists( 'selective_refresh', $options['settings'][ $id ]['control'] ) ) {
                            $selective_refresh = $options['settings'][ $id ]['control']['selective_refresh'];

                            if ( $selective_refresh === false ) {
                                continue;
                            }


                            unset( $options['settings'][ $id ]['control']['selective_refresh'] );

                            if ( array_key_exists( 'selector', $selective_refresh ) ) {
                                $options['settings'][ $id ]['control']['colibri_selective_refresh_selector']
                                    = $selective_refresh['selector'];
                            }

                            if ( array_key_exists( 'function', $selective_refresh ) ) {
                                $options['settings'][ $id ]['control']['colibri_selective_refresh_function']
                                    = $selective_refresh['function'];
                            }

                        } else {
                            $options['settings'][ $id ]['control']['colibri_selective_refresh_selector']
                                = static::selectiveRefreshSelector();

                        }

                        $options['settings'][ $id ]['control']['colibri_selective_refresh_class']       = $__class__;
                        $options['settings'][ $id ]['control']['selective_refresh_container_inclusive'] = static::$selective_refresh_container_inclusive;
                    }

                }
            }
        );

        return $options;
    }

    protected static abstract function getOptions();

    public static function selectiveRefreshSelector() {
        return false;
    }

    public function mod_e_esc_attr( $name ) {
        echo esc_attr( $this->mod( $name ) );
    }

    /**
     * @param      $name
     * @param null $fallback
     *
     * @return mixed
     */
    public function mod( $name, $fallback = null ) {
        return static::mabyDeserializeModValue( get_theme_mod( $name, static::settingDefault( $name, $fallback ) ) );
    }

    public static function mabyDeserializeModValue( $value ) {

        if ( is_string( $value ) ) {

            if ( empty( trim( $value ) ) ) {
                return $value;
            }

            $new_value = json_decode( urldecode( $value ), true );

            if ( json_last_error() === JSON_ERROR_NONE ) {
                $value = $new_value;
            }

        }

        return $value;
    }

    /**
     * @param      $name
     * @param null $fallback
     *
     * @return null
     */
    public static function settingDefault( $name, $fallback = null ) {
        $options = (array) static::getOptions();

        $default = $fallback;

        if ( isset( $options['settings'] ) && isset( $options['settings'][ $name ] ) ) {
            if ( array_key_exists( 'default', $options['settings'][ $name ] ) ) {
                $default = $options['settings'][ $name ]['default'];
            }

        }

        return $default;
    }

    /**
     * @return array
     */
    public function mods() {
        $result   = array();
        $settings = array_key_exists( 'settings', static::getOptions() ) ? static::getOptions()['settings'] : array();

        foreach ( array( $settings ) as $key => $value ) {
            $result[ $key ] = $this->mod( $key );
        }

        return $result;
    }

    public function render( $parameters = array() ) {

        $that = $this;

        Theme::getInstance()->getCustomizer()->inPreview(
            function () use ( $that ) {
                $that->addControlsFilter();
                $that->whenCustomizerPreview();
                $that->prinPenPosition();
            }
        );

        $this->renderContent( $parameters );
    }

    /**
     * @return array();
     */
    /** @noinspection PhpAbstractStaticMethodInspection */
    private function addControlsFilter() {

        $options = (array) static::getOptions();

        if ( isset( $options['settings'] ) ) {
            $options = array_keys( $options['settings'] );

        } else {
            $options = array();
        }

        foreach ( $options as $option ) {

            Hooks::prefixed_add_filter(
                "control_{$option}_rendered",
                function ( $value ) {
                    return true;
                },
                0,
                1
            );
        }

    }

    public function whenCustomizerPreview() {


    }

    private function prinPenPosition() {
        if ( $this->getPenPosition() === static::PEN_ON_RIGHT ) {
            $class = static::class;
            add_action( 'wp_footer',
                function () use ( $class ) {
                    $selector = call_user_func( array( $class, 'selectiveRefreshSelector' ) );
                    if ( $selector ) {
                        ?>
                        <style>
                            @media (min-width: 768px) {
                            <?php echo $selector; ?> > .customize-partial-edit-shortcut {
                                left: unset !important;
                                right: -30px !important;
                            }
                            }
                        </style>
                        <?php
                    }
                }
            );
        }
    }

    public function getPenPosition() {
        return static::PEN_ON_LEFT;
    }

    public abstract function renderContent();

    protected function addFrontendJSData( $key, $value ) {
        Hooks::add_filter(
            'frontend_js_data',
            function ( $current_data ) use ( $key, $value ) {
                $current_data[ $key ] = $value;

                return $current_data;
            }
        );

    }

}


