<?php
/**
 * Social Links Class
 *
 * @package errigal
 * @since 1.0.3
 */

namespace Errigal\Social;

defined( 'ABSPATH' ) || exit;

use Errigal\Constant\{
	Errigal_Html_Attr as Html_Attr,
	Errigal_Html_Option as Html_Option,
	Errigal_Social_Hook as Social_Hook,
};
use Errigal\Icon\Errigal_Icon as Icon;
use Errigal\Shared\{
	Errigal_Html_Builder as Html_Builder,
	Errigal_Html_Schema as Html_Schema,
	Errigal_Utility as Utility,
	Errigal_Validator as Validator,
};

/**
 * This class is in charge of displaying social links.
 *
 * @since 1.0.0
 */
class Errigal_Social_Link {
	/**
	 * URL: Facebook.
	 *
	 * @since 1.1.0
	 *
	 * @var string
	 */
	public const URL_FACEBOOK = 'facebook_url';

	/**
	 * URL: GitHub.
	 *
	 * @since 1.1.0
	 *
	 * @var string
	 */
	public const URL_GITHUB = 'github_url';

	/**
	 * URL: Instagram.
	 *
	 * @since 1.1.0
	 *
	 * @var string
	 */
	public const URL_INSTAGRAM = 'instagram_url';

	/**
	 * URL: LINE.
	 *
	 * @since 1.1.0
	 *
	 * @var string
	 */
	public const URL_LINE = 'line_url';

	/**
	 * URL: LinkedIn.
	 *
	 * @since 1.1.0
	 *
	 * @var string
	 */
	public const URL_LINKEDIN = 'linkedin_url';

	/**
	 * URL: Twitter.
	 *
	 * @since 1.1.0
	 *
	 * @var string
	 */
	public const URL_TWITTER = 'twitter_url';

	/**
	 * URL: X.
	 *
	 * @since 1.1.0
	 *
	 * @var string
	 */
	public const URL_X = 'x_url';

	/**
	 * URL: YouTube.
	 *
	 * @since 1.1.0
	 *
	 * @var string
	 */
	public const URL_YOUTUBE = 'youtube_url';

	/**
	 * Social media: Name
	 *
	 * @since 1.1.0
	 *
	 * @var string
	 */
	private const SOCIAL_MEDIA_NAME = 'name';

	/**
	 * Social media: Icon
	 *
	 * @since 1.1.0
	 *
	 * @var string
	 */
	private const SOCIAL_MEDIA_ICON = 'icon';

	/**
	 * Gets social links.
	 *
	 * @since 1.0.3
	 *
	 * @param array  $social_link_urls Associative array of social link URLs. See self::get_supported_social_links()
	 *                                 for information on accepted social links.
	 * @param string $icon_size        Optional. Icon size. See Errigal\Icon\Errigal_Icon::SUPPORTED_SIZES
	 *                                 for information on accepted icon sizes. Default md.
	 * @return string
	 */
	final public static function get_social_links( $social_link_urls, $icon_size = Icon::SIZE_MD ) {
		if (
			! Validator::is_associative_array( $social_link_urls ) ||
			! Icon::is_supported_size( $icon_size )
		) {
			return '';
		}

		/**
		 * Filters social links.
		 *
		 * @since 1.2.0
		 *
		 * @param array $social_links Associative array of social links.
		 */
		$supported_social_links = apply_filters(
			Social_Hook::SOCIAL_LINKS,
			self::get_supported_social_links()
		);

		if ( ! Validator::is_associative_array( $supported_social_links ) ) {
			return '';
		}

		$social_link_urls = wp_parse_args(
			$social_link_urls,
			self::get_default_social_link_urls( $supported_social_links )
		);

		$social_links    = array();
		$visited_url_ids = array();

		foreach ( $supported_social_links as $id => $social_media ) {
			if (
				! Validator::is_non_empty_string( $id ) ||
				! Validator::is_associative_array( $social_media ) ||
				! Validator::has_array_key( $social_link_urls, $id ) ||
				Validator::has_string_list_item( $visited_url_ids, $id )
			) {
				continue;
			}

			$social_link_url = $social_link_urls[ $id ];

			if (
				! Validator::is_non_empty_string( $social_link_url ) ||
				! Validator::has_array_key( $social_media, self::SOCIAL_MEDIA_NAME ) ||
				! Validator::has_array_key( $social_media, self::SOCIAL_MEDIA_ICON )
			) {
				continue;
			}

			$social_media_name = $social_media[ self::SOCIAL_MEDIA_NAME ];
			$social_media_icon = $social_media[ self::SOCIAL_MEDIA_ICON ];

			if (
				! Validator::is_non_empty_string( $social_media_name ) ||
				! Icon::is_supported_icon( $social_media_icon )
			) {
				continue;
			}

			$social_icon = Icon::get_icon( $social_media_icon, $icon_size );

			if ( ! Icon::is_valid_icon( $social_icon ) ) {
				continue;
			}

			$social_link = self::get_social_link(
				$social_link_url,
				$social_media_name,
				$social_icon
			);

			if ( ! Validator::is_non_empty_string( $social_link ) ) {
				continue;
			}

			$social_links[]    = $social_link;
			$visited_url_ids[] = $id;
		}

		if ( ! Validator::is_string_list( $social_links ) ) {
			return '';
		}

		return wp_kses(
			Utility::join(
				Utility::SEPARATOR_EMPTY,
				...$social_links
			),
			Html_Schema::get_allowed_html_post_svg()
		);
	}

	/**
	 * Gets supported social links.
	 *
	 * @since 1.1.0
	 *
	 * @return array
	 */
	private static function get_supported_social_links() {
		return array(
			self::URL_FACEBOOK  => array(
				self::SOCIAL_MEDIA_NAME => esc_html__( 'Facebook', 'errigal' ),
				self::SOCIAL_MEDIA_ICON => Icon::FACEBOOK,
			),
			self::URL_X         => array(
				self::SOCIAL_MEDIA_NAME => esc_html__( 'X', 'errigal' ),
				self::SOCIAL_MEDIA_ICON => Icon::X,
			),
			self::URL_TWITTER   => array(
				self::SOCIAL_MEDIA_NAME => esc_html__( 'Twitter', 'errigal' ),
				self::SOCIAL_MEDIA_ICON => Icon::TWITTER,
			),
			self::URL_INSTAGRAM => array(
				self::SOCIAL_MEDIA_NAME => esc_html__( 'Instagram', 'errigal' ),
				self::SOCIAL_MEDIA_ICON => Icon::INSTAGRAM,
			),
			self::URL_LINKEDIN  => array(
				self::SOCIAL_MEDIA_NAME => esc_html__( 'LinkedIn', 'errigal' ),
				self::SOCIAL_MEDIA_ICON => Icon::LINKEDIN,
			),
			self::URL_YOUTUBE   => array(
				self::SOCIAL_MEDIA_NAME => esc_html__( 'YouTube', 'errigal' ),
				self::SOCIAL_MEDIA_ICON => Icon::YOUTUBE,
			),
			self::URL_GITHUB    => array(
				self::SOCIAL_MEDIA_NAME => esc_html__( 'GitHub', 'errigal' ),
				self::SOCIAL_MEDIA_ICON => Icon::GITHUB,
			),
			self::URL_LINE      => array(
				self::SOCIAL_MEDIA_NAME => esc_html__( 'LINE', 'errigal' ),
				self::SOCIAL_MEDIA_ICON => Icon::LINE,
			),
		);
	}

	/**
	 * Gets default social link URLS.
	 *
	 * @since 1.2.0
	 *
	 * @param array $supported_social_links Associative array of default URLs for supported social links.
	 * @return array
	 */
	private static function get_default_social_link_urls( $supported_social_links ) {
		if ( ! Validator::is_associative_array( $supported_social_links ) ) {
			return array();
		}

		return array_fill_keys( array_keys( $supported_social_links ), '' );
	}

	/**
	 * Gets social link.
	 *
	 * @since 1.0.3
	 *
	 * @param string $social_link_url   Social link URL.
	 * @param string $social_media_name Social media name.
	 * @param string $social_icon       Social icon.
	 * @return string
	 */
	private static function get_social_link( $social_link_url, $social_media_name, $social_icon ) {
		if (
			! Validator::is_non_empty_string( $social_link_url ) ||
			! Validator::is_non_empty_string( $social_media_name ) ||
			! Icon::is_valid_icon( $social_icon )
		) {
			return '';
		}

		return Html_Builder::create()->create_a(
			array(
				Html_Option::ATTRS => array(
					Html_Attr::CLASS_NAME => 'social-icon-link',
					Html_Attr::HREF       => $social_link_url,
					Html_Attr::TARGET     => Html_Attr::VALUE_BLANK,
					Html_Attr::ARIA_LABEL => $social_media_name,
				),
			)
		)->get_element( $social_icon );
	}
}
