<?php

namespace Fab\Controller;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

use Fab\Interfaces\JIT_Interface;
use Fab\View;

/**
 * Plugin hooks in a backend
 *
 * @package    Fab
 * @subpackage Fab/Controller
 */
class Frontend extends Base implements JIT_Interface {

    /**
     * Enqueue scripts to @frontend
     *
     * @param string $hook_suffix The current admin page.
     * @return void
     */
    public function frontend_enequeue( $hook_suffix ) {
        global $post;

        // Default Variables.
        $options        = \Fab\Plugin\Config::getInstance()->getConfig()->options;
        $fabTypes       = array();
        $require_hotkey = false;

        // Get FAB for JS Manipulation.
        $fab_to_display             = \Fab\Model\Fab::getInstance();
        $fab_to_display             = $fab_to_display->get_lists_of_fab()['items'];
        $standalones                = array();
        $fab_to_display_by_position = array();
        foreach ( $fab_to_display as $key => &$fab ) {
            $fabTypes[ $fab->getType() ] = $fab->getType();
            // TODO: FIX THE LOGIC, still unsure about the logic
            if ( $fab->getModal() ) {
                $fabTypes['modal'] = 'modal';
            }

            // Check if standalone is set.
            if ( 'yes' === $fab->getStandalone() && $fab->getIsButton() ) {
                $standalones[] = $fab->getVars();
                // unset( $fab_to_display[ $key ] ); // TODO: AFAB-287 Migrate frontend modules to svelte app
            }

            // Group by position.
            $fab_to_display_by_position[ $fab->getTemplate()['position'] ][] = $fab->getVars();

            $fab = $fab->getVars();
        }

        // Get Features for JS Manipulation.
        $features = \FAB()->getFeatures();
        foreach ( $features as $key => &$feature ) {
            $feature = $feature->getOptions();
            if ( ! $feature ) {
                unset( $features[ $key ] );
            }
        }

        // Load Inline Script.
        \FAB()->Helper->wp_enqueue_script( 'fab-local', 'local/fab.js', array(), FAB_VERSION, true );
        wp_localize_script(
            'fab-local',
            'FAB_PLUGIN',
            array(
                'name'        => FAB_NAME,
                'version'     => FAB_VERSION,
                'screen'      => FAB_SCREEN,
                'path'        => FAB_PATH,
                'premium'     => \FAB()->Helper->isPremiumPlan(),
                'rest_url'    => esc_url_raw( rest_url() ),
                'options'     => $options,
                'by_position' => $fab_to_display_by_position,
                'to_display'  => array_values( $fab_to_display ),
                'standalones' => $standalones,
                'features'    => $features,
                'nonce'       => array(
                    'clicked' => wp_create_nonce( 'wp_rest' ),
                ),
            )
        );

        // Load WP Core jQuery.
        wp_enqueue_script( 'jquery' );

        // Load Google Fonts.
        if ( isset( $options->fab_design->font->family ) ) {
            $font_url = sprintf( 'https://fonts.googleapis.com/css2?family=%s&display=swap', $options->fab_design->font->family );
            wp_enqueue_style( 'fab-google-fonts', $font_url, array(), FAB_VERSION );
        }

        // Load Vendors.
        if ( isset( $options->fab_animation->enable ) && $options->fab_animation->enable ) {
            \FAB()->Helper->wp_enqueue_style( 'animatecss', 'vendor/animatecss/animate.min.css' );
        }
        \FAB()->Helper->enqueue_vendor( 'frontend' );

        // Load Plugin Assets.
        \FAB()->Helper->wp_enqueue_style_sass( 'fab', 'assets/css/frontend/style.scss' );

        // Load Components.
        foreach ( $fab_to_display as $component ) {
            $type = str_contains( $component['type'], 'toast' ) ? 'toast' : $component['type'];

            \FAB()->Helper->wp_enqueue_style( sprintf( 'fab-%s-component', $type ), sprintf( 'build/components/%s/bundle.css', $type ) );
            \FAB()->Helper->wp_enqueue_script( sprintf( 'fab-%s-component', $type ), sprintf( 'build/components/%s/bundle.js', $type ), array(), FAB_VERSION, true );
        }

        // Load FAB Component.
        \FAB()->Helper->wp_enqueue_style( 'fab-fab-component', sprintf( 'build/components/fab/bundle.css' ) );
        \FAB()->Helper->wp_enqueue_script( 'fab-fab-component', sprintf( 'build/components/fab/bundle.js' ), array(), FAB_VERSION, true );

        // Special Template/Styles.
        if ( $options->fab_design->template->name === 'shape' ) {
            \FAB()->Helper->wp_enqueue_style_sass( 'fab-shapes', 'assets/css/fab-shapes/style.scss' );
        }
        if ( isset( $fabTypes['modal'] ) ) {
            \FAB()->Helper->wp_enqueue_style_sass( 'fab-modal', 'assets/css/fab-modal/style.scss' );
        } else {
            // Dequeue vendor assets.
            wp_dequeue_script( 'fab-jconfirm-js' );
            wp_dequeue_style( 'fab-jconfirm-css' );
        }
    }

    /**
     * Display the html element from view Frontend/float_button.php
     *
     * @return  void
     */
    public function fab_loader() {
        global $post;

        // Grab Data.
        $Fab            = \Fab\Model\Fab::getInstance();
        $args           = array(
            'filtercustommodule' => true,
        );
        $lists          = $Fab->get_lists_of_fab( $args );
        $fab_to_display = $lists['items'];

        // Show FAB Button.
        View::RenderStatic( 'Frontend.button' );

        // Show Modal - Only Default.
        if ( ! is_admin() && ( $fab_to_display ) ) {
            $args['builder'] = array( 'default' );
            $fab_to_display  = $Fab->get_lists_of_fab( $args )['items'];
            View::RenderStatic(
                'Frontend.modal',
                compact( 'post', 'fab_to_display' )
            );
        }
    }

    /**
     * Show FAB preview notice.
     *
     * @return void
     */
    public function fab_preview_notice() {
        if ( \FAB()->Helper->isPremiumPlan() && \FAB()->Helper->is_preview_page() ) {
            $notice = array(
                'id'      => 'fab-preview-notice',
                'message' => __( 'This is a preview of the FAB, all location rules will be ignored.', 'floating-awesome-button' ),
            );
            View::RenderStatic( 'Frontend.notice', compact( 'notice' ) );
        }
    }

    /**
     * Register widgets.
     *
     * @return void
     */
    public function fab_register_widget() {
        // Get Widgets Type.
        $widgetsType = apply_filters( 'fab_types_group_widget', array() );

        // Load FAB.
        $FAB   = \Fab\Model\Fab::getInstance();
        $items = $FAB->get_lists_of_fab(
            array(
                'filterbyType' => $widgetsType,
            )
        )['items'];

        // Register Sidebar.
        foreach ( $items as $widget ) {
            register_sidebar(
                array(
                    'name'          => $widget->getTitle(),
                    'id'            => sprintf( 'fab-widget-%s', $widget->getSlug() ),
                    'before_widget' => '<div id="%1$s" class="widget fab-container %2$s">',
                    'after_widget'  => '</div>',
                    'before_title'  => '<h3 class="widgettitle">',
                    'after_title'   => '</h3>',
                )
            );
        }
    }

    /**
     * Filter wpkses posts accept iframe, used to embed iframe (youtube, vimeo, etc) with FAB Content
     *
     * @param array  $tags The tags to filter.
     * @param string $context The context of the filter.
     * @return array The filtered tags.
     */
    public function filter_wpkses_posts( $tags, $context ) {
        $tags['iframe'] = array(
            'src'             => true,
            'height'          => true,
            'width'           => true,
            'frameborder'     => true,
            'allowfullscreen' => true,
        );
        return $tags;
    }

    /*
    |--------------------------------------------------------------------------
    | Fulfill implemented interface contracts
    |--------------------------------------------------------------------------
     */

    /**
     * JIT method.
     *
     * @return void
     */
    public static function jit() {
        // Add table of content widget.
        add_action( 'widgets_init', array( __CLASS__, 'jit_fab_register_widget' ) );

        // Enqueue scripts.
        add_action( 'wp_enqueue_scripts', array( __CLASS__, 'jit_frontend_enequeue' ), 20, 1 );

        // Display the html element from view Frontend/float_button.php.
        add_action( 'wp_footer', array( __CLASS__, 'jit_fab_loader' ), 10, 0 );

        // Show FAB preview notice.
        add_action( 'wp_footer', array( __CLASS__, 'jit_fab_preview_notice' ), 10, 0 );

        // Filter wpkses post.
        add_filter( 'wp_kses_allowed_html', array( __CLASS__, 'jit_filter_wpkses_posts' ), 10, 2 );
    }
}
