<?php
namespace Kanews\Assets;

use Kanews\Kai\Support\Options;

class FrontEndAsset {
	private static $instance;

	/**
	 * Get singleton instance
	 * 
	 * @return self
	 */
	public static function getInstance() {
		if ( null === static::$instance ) {
			static::$instance = new static();
		}
		return static::$instance;
	}

	/**
	 * Constructor
	 */
	public function __construct() {
		add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
		// add_action( 'wp_default_scripts', [ $this, 'remove_jquery_migrate' ] );
		// add_filter( 'style_loader_tag', [ $this, 'add_style_attributes' ], 10, 4 );
		// add_filter( 'wp_resource_hints', [ $this, 'google_fonts_preconnect' ], 10, 2 );
	}

	/**
	 * Enqueue scripts and styles
	 * 
	 * @return void
	 */
	public function enqueue_scripts() {
		wp_enqueue_script( 'jquery' );
		
		$this->register_assets();
		$this->enqueue_conditional_scripts();
		$this->localize_scripts();
		$this->handle_singular_assets();
		$this->dequeue_unused_assets();
	}

	/**
	 * Register assets
	 * 
	 * @return void
	 */
	private function register_assets() {
		wp_register_style( 
			'kanews-theme-single', 
			KAN_TEMPLATE_URL . '/assets/css/theme-single.min.css', 
			[ 'kanews-theme' ], 
			KAN_THEME_VER 
		);

		wp_register_script( 
			'kanews-infinite-scroll', 
			KAN_TEMPLATE_URL . '/assets/js/infinite-scroll.min.js', 
			[ 'jquery' ], 
			KAN_THEME_VER, 
			true 
		);
		
		wp_register_script( 
			'kanews-calculator', 
			KAN_TEMPLATE_URL . '/assets/js/calculator.min.js', 
			[ 'kanews-theme' ], 
			KAN_THEME_VER, 
			true 
		);
		
		wp_register_script( 
			'kanews-sticky', 
			KAN_TEMPLATE_URL . '/assets/js/sticky.min.js', 
			[ 'kanews-theme' ], 
			KAN_THEME_VER, 
			true 
		);

		wp_register_script( 
			'kanews-ilan-search', 
			KAN_TEMPLATE_URL . '/assets/js/ilan.js', 
			[ 'jquery' ], 
			KAN_THEME_VER, 
			true 
		);
	}

	/**
	 * Enqueue conditional scripts
	 * 
	 * @return void
	 */
	private function enqueue_conditional_scripts() {
		if ( kanews_get_option( 'sticky-sidebar', true ) ) {
			wp_enqueue_script( 'kanews-sticky' );
		}

		if ( $this->should_enqueue_infinite_scroll() ) {
			wp_enqueue_script( 'kanews-infinite-scroll' );
		}

		if ( kanews_get_option( 'pwa-status' ) && kanews_get_option( 'pwa-btn' ) ) {
			wp_enqueue_script( 
				'kanews-pwa', 
				KAN_TEMPLATE_URL . '/assets/js/pwa.js', 
				[ 'jquery' ], 
				KAN_THEME_VER, 
				true 
			);
		}

		if ( kanews_get_option( 'ajax-search', false ) ) {
			wp_enqueue_script( 
				'kanews-ajax-search', 
				KAN_TEMPLATE_URL . '/assets/js/ajax-search.min.js', 
				[ 'jquery' ], 
				KAN_THEME_VER, 
				true 
			);
		}
	}

	/**
	 * Check if infinite scroll should be enqueued
	 * 
	 * @return bool
	 */
	private function should_enqueue_infinite_scroll() {
		if ( is_singular() ) {
			return kanews_get_option( 'infinite-post-scroll', false ) 
				|| kanews_get_option( 'single-pagination', '' ) !== 'number';
		}

		if ( is_archive() || is_home() || is_front_page() ) {
			$pagination = kanews_get_option( 'archives-pagination', '' );
			return $pagination !== 'classic' && $pagination !== 'number';
		}

		return false;
	}

	/**
	 * Localize scripts with JavaScript variables
	 * 
	 * @return void
	 */
	private function localize_scripts() {
		$localize = $this->get_localize_data();
		
		wp_enqueue_script( 
			'kanews-theme', 
			KAN_TEMPLATE_URL . '/assets/js/theme.min.js', 
			[ 'jquery' ], 
			KAN_THEME_VER, 
			true 
		);
		
		wp_localize_script( 'kanews-theme', 'kan_vars', $localize );
		
		// Only localize chat data if chatbot is active
		$chatActive = Options::get( 'kai-chat-active', false );
		if ( $chatActive && is_singular() ) {
			$chat_data = $this->get_chat_localize_data();
			wp_localize_script( 'kanews-theme', 'kanews_chat', $chat_data );
		}
	}

	/**
	 * Get localize data for kan_vars
	 * 
	 * @return array
	 */
	private function get_localize_data() {
		$user_id = get_current_user_id();
		$pagination = kanews_get_option( 'archives-pagination', '' );

		return [
			'nonce' => wp_create_nonce( 'kanews-ajax-nonce' ),
			'isadmin' => current_user_can( 'administrator' ) ? 1 : 0,
			'isuser' => current_user_can( 'subscriber' ) ? 1 : 0,
			'ajax' => admin_url( 'admin-ajax.php' ),
			'assets' => KAN_TEMPLATE_URL . '/assets/',
			'emptydata' => esc_html__( 'Veri alınamadı!', 'kanews' ),
			'invalidapi' => esc_html__( 'API hatası', 'kanews' ),
			'infinite_scroll' => kanews_get_option( 'infinite-post-scroll' ) ? 1 : 0,
			'weather_api' => kanews_get_option( 'openweathermap-api' ),
			'noresult' => esc_html__( 'Sonuç bulunamadı', 'kanews' ),
			'new_tab' => kanews_get_option( 'open-link-new-tab' ) ? 1 : 0,
			'sticky_navbar' => kanews_get_option( 'sticky-navbar' ) ? 1 : 0,
			'text_share' => kanews_get_option( 'post-text-share' ) ? 1 : 0,
			'right_click' => kanews_get_option( 'right-click' ) ? 1 : 0,
			'copy_event' => kanews_get_option( 'copy-event' ) ? 1 : 0,
			'adblock' => kanews_get_option( 'adblock-detected' ) ? 1 : 0,
			'subscribe' => kanews_insights_control( $user_id ) ? 1 : 0,
			'lazy' => kanews_get_option( 'lazy' ),
			'mode' => kanews_get_option( 'default-mode', 'light' ),
			'dark_mode' => kanews_get_option( 'mode' ) ? 1 : 0,
			'like' => kanews_translate( 'like-text', esc_html__( 'Beğen', 'kanews' ) ),
			'unlike' => kanews_translate( 'unlike-text', esc_html__( 'Vazgeç', 'kanews' ) ),
			'bookmark' => kanews_translate( 'bookmark-text', esc_html__( 'Favorilerime Ekle', 'kanews' ) ),
			'unbookmark' => kanews_translate( 'unbookmark-text', esc_html__( 'Favorilerimden Çıkar', 'kanews' ) ),
			'show_children' => kanews_translate( 'show-children', esc_html__( 'Yanıtları Göster', 'kanews' ) ),
			'hide_children' => kanews_translate( 'hide-children', esc_html__( 'Yanıtları Gizle', 'kanews' ) ),
			'pagination' => ! empty( $pagination ) ? $pagination : 'numbers',
			'insights' => kanews_insights_page_url(),
			'gotop' => kanews_get_option( 'back-to-top' ) ? 1 : 0,
			'translate' => $this->get_translate_strings(),
		];
	}

	/**
	 * Get translate strings
	 * 
	 * @return array
	 */
	private function get_translate_strings() {
		return [
			'days' => esc_html__( 'Gün', 'kanews' ),
			'showless' => esc_html__( 'Daha Az Göster', 'kanews' ),
			'showmore' => esc_html__( 'Daha Fazla Göster', 'kanews' ),
			'prev' => esc_html__( 'Önceki', 'kanews' ),
			'next' => esc_html__( 'Sonraki', 'kanews' ),
			'expand' => esc_html__( 'Daralt', 'kanews' ),
			'expand2' => esc_html__( 'Genişlet', 'kanews' ),
			'continue' => esc_html__( 'Devam Et', 'kanews' ),
			'copied' => esc_html__( 'Kopyalandı!', 'kanews' ),
			'insights' => esc_html__( 'Reklamsız Sürüm', 'kanews' ),
			'right_click' => esc_html__( 'Bu sayfada sağ tıklama işlemi yasaklanmıştır.', 'kanews' ),
			'copy_event' => esc_html__( 'Bu sayfada kopyalama işlemi yasaklanmıştır.', 'kanews' ),
			'adblock_text' => esc_html__( 'Sitemize katkıda bulunmak için lütfen reklam engelleyicinizi devredışı bırakın.', 'kanews' ),
			'adblock_title' => esc_html__( 'Reklam Engelleyicisi Tespit Edildi', 'kanews' ),
		];
	}

	/**
	 * Get chat localize data
	 * 
	 * @return array
	 */
	private function get_chat_localize_data() {
		return [
			'nonce' => wp_create_nonce( 'kanews_chat_nonce' ),
			'insights' => kanews_get_option( 'kanews-insights', false ),
			'subscription_url' => kanews_insights_page_url(),
			'free_limit' => Options::get( 'kai-chat-free-limit', 5 ),
			'premium_limit' => Options::get( 'kai-chat-premium-limit', 20 ),
		];
	}

	/**
	 * Handle singular post assets
	 * 
	 * @return void
	 */
	private function handle_singular_assets() {
		if ( ! is_singular() ) {
			$this->dequeue_block_styles();
			return;
		}

		wp_enqueue_script( 
			'kanews-singular', 
			KAN_TEMPLATE_URL . '/assets/js/theme-singular.min.js', 
			[ 'kanews-theme' ], 
			KAN_THEME_VER, 
			true 
		);

		global $post;
		
		if ( $post ) {
			$this->handle_contact_form_7( $post );
			$this->handle_gallery_assets( $post );
		}
		
		// Disable Gutenberg CSS if no blocks
		if ( function_exists( 'has_blocks' ) && has_blocks( $post->ID ) ) {
			// Keep block styles
		} else {
			$this->dequeue_block_styles();
		}

		// Comments
		if ( comments_open() && get_option( 'thread_comments' ) ) {
			wp_enqueue_script( 'comment-reply' );
		}
	}

	/**
	 * Handle Contact Form 7 assets
	 * 
	 * @param \WP_Post $post Post object
	 * @return void
	 */
	private function handle_contact_form_7( $post ) {
		if ( has_shortcode( $post->post_content, 'contact-form-7' ) 
			&& function_exists( 'wpcf7_enqueue_styles' ) 
		) {
			wpcf7_enqueue_styles();
		}
	}

	/**
	 * Handle gallery assets
	 * 
	 * @param \WP_Post $post Post object
	 * @return void
	 */
	private function handle_gallery_assets( $post ) {
		$has_gallery = has_shortcode( $post->post_content, 'gallery' );
		$is_ilan = is_singular( 'ilan' );

		if ( ! $has_gallery && ! $is_ilan ) {
			return;
		}

		wp_enqueue_style( 
			'mfp-popup', 
			KAN_TEMPLATE_URL . '/assets/css/magnific-popup.css', 
			[], 
			'1.1.0'
		);
		
		wp_enqueue_script( 
			'mfp-popup', 
			KAN_TEMPLATE_URL . '/assets/js/magnific-popup.min.js', 
			[ 'kanews-theme' ], 
			'1.1.0', 
			true 
		);

		if ( $is_ilan ) {
			$this->add_ilan_gallery_script();
		} else {
			$this->add_post_gallery_script();
		}
	}

	/**
	 * Add ilan gallery script
	 * 
	 * @return void
	 */
	private function add_ilan_gallery_script() {
		$script = "
		(function( $ ) {
			'use strict';
			$('.kanews-gallery-text').on('click', function () {
				$(this).closest('.kanews-gallery-lightbox').magnificPopup('open');
			});
			$('.kanews-gallery-lightbox').magnificPopup({
				delegate: 'figure',
				gallery: {
					enabled: true
				},
				type: 'image'
			});
		})(jQuery);
		";
		wp_add_inline_script( 'mfp-popup', kan_minify_js( $script ) );
	}

	/**
	 * Add post gallery script
	 * 
	 * @return void
	 */
	private function add_post_gallery_script() {
		$script = "
		(function( $ ) {
			'use strict';
			$('.kanews-gallery-lightbox').on('click', function() {
				$(this).magnificPopup('open');
			});
			jQuery('.kanews-gallery').each(function() {
				jQuery(this).magnificPopup({
					delegate: 'figure',
					type: 'image',
					mainClass: 'mfp-zoom-in kanews-post-gallery-lightbox',
					zoom: {
						enabled: true,
						duration: 300
					},
					cursor: 'mfp-zoom-out-cur',
					closeBtnInside: false,
					removalDelay: 400,
					overflowY: 'hidden',
					gallery: {
						enabled: true,
						arrowMarkup: '<button title=\"%title%\" type=\"button\" class=\"mfp-arrow mfp-arrow-%dir%\"></button>',
						tCounter: '<span class=\"mfp-counter\">%curr%/%total%</span>'
					},
					image: {
						titleSrc: false,
						markup: '<div class=\"mfp-figure d-flex flex-column\">' + '<div class=\"mfp-top-bar d-flex align-items-center justify-content-between\">' + '<div class=\"mfp-title\"></div>' + '<div class=\"mfp-counter\"></div>' + '</div>' + '<div class=\"mfp-inner row m-0\">' + '<div class=\"mfp-left-column col-12 col-md-7 col-lg-9\"><div class=\"mfp-img\"></div></div>' + '<div class=\"mfp-right-column col-12 col-md-5 col-lg-3\"><div class=\"mfp-inner-content\"></div></div>' + '</div>' + '</div>',
					},
					callbacks: {
						change: function() {
							$(this.content).find('.mfp-inner-content').html('<h5>' + $(this.currItem.el).attr('title') + '</h5>' + $(this.currItem.el).attr('content'));
						}
					},
				});
			});
		})(jQuery);
		";
		wp_add_inline_script( 'mfp-popup', kan_minify_js( $script ) );
	}

	/**
	 * Dequeue unused assets
	 * 
	 * @return void
	 */
	private function dequeue_unused_assets() {
		if ( function_exists( 'pvc_get_post_views' ) ) {
			wp_dequeue_style( 'post-views-counter-frontend' );
		}

		if ( class_exists( 'TOC_Plus' ) ) {
			wp_dequeue_style( 'toc-screen' );
			wp_dequeue_script( 'toc-front' );
		}

		wp_dequeue_style( 'classic-theme-styles' );

		if ( ! is_user_logged_in() ) {
			wp_dequeue_style( 'dashicons' );
		}

		if ( ! is_singular() ) {
			wp_dequeue_style( 'global-styles' );
			$this->dequeue_block_styles();
		}

		if ( class_exists( 'WooCommerce' ) ) {
			wp_dequeue_style( 'wc-blocks-style' );
			wp_dequeue_style( 'wc-block-style' );
			wp_dequeue_script( 'sourcebuster-js' );
		}
	}

	/**
	 * Dequeue block styles
	 * 
	 * @return void
	 */
	private function dequeue_block_styles() {
		wp_dequeue_style( 'wp-block-library' );
		wp_dequeue_style( 'wp-block-library-theme' );
		wp_dequeue_style( 'wc-block-style' );
		wp_dequeue_style( 'kanews-blocks' );
	}

	/**
	 * Remove jQuery migrate
	 * 
	 * @param \WP_Scripts $scripts Scripts object
	 * @return void
	 */
	public function remove_jquery_migrate( $scripts ) {
		if ( is_admin() || ! isset( $scripts->registered['jquery'] ) ) {
			return;
		}

		$script = $scripts->registered['jquery'];
		if ( $script->deps ) {
			$script->deps = array_diff( $script->deps, [ 'jquery-migrate' ] );
		}
	}

	/**
	 * Google fonts preconnect
	 * 
	 * @param array $urls URLs array
	 * @param string $relationship_type Relationship type
	 * @return array
	 */
	public function google_fonts_preconnect( array $urls, string $relationship_type ): array {
		if ( 'preconnect' !== $relationship_type ) {
			return $urls;
		}

		$urls[] = [
			'rel' => 'preconnect',
			'href' => 'https://fonts.gstatic.com',
			'crossorigin',
		];

		return $urls;
	}

	/**
	 * Add style attributes for Google Fonts
	 * 
	 * @param string $html HTML output
	 * @param string $handle Style handle
	 * @param string $href Style URL
	 * @param string $media Media attribute
	 * @return string
	 */
	public function add_style_attributes( string $html = '', string $handle = '', string $href = '', string $media = '' ): string {
		if ( ! in_array( $handle, [ 'kanews-google-font', 'kanews-google-font-single' ], true ) ) {
			return $html;
		}

		// Revamp thanks to Harry: https://csswizardry.com/2020/05/the-fastest-google-fonts/
		$href = str_replace( [ '|', ' ' ], [ '%7C', '%20' ], urldecode( $href ) );
		$escaped_href = esc_attr( $href );
		
		$new_html = '<link rel="preload" as="style" href="' . $escaped_href . '" />';
		$new_html .= '<link rel="stylesheet" href="' . $escaped_href . '" media="print" onload="this.media=\'all\'">';  // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet
		$new_html .= '<noscript><link rel="stylesheet" href="' . $escaped_href . '" /></noscript>'; // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet

		return $new_html;
	}

}