<?php
/**
 * Profile Widget Class
 *
 * @package errigal
 * @since 1.0.3
 */

namespace Errigal\Widget;

defined( 'ABSPATH' ) || exit;

use Errigal\Constant\Errigal_Accessibility_Class as Accessibility_Class;
use Errigal\Shared\{
	Errigal_Theme_Info as Theme_Info,
	Errigal_Utility as Utility,
	Errigal_Validator as Validator,
};
use Errigal\Social\Errigal_Social_Link as Social_Link;

/**
 * This class is in charge of adding profile widget to theme.
 *
 * @since 1.0.3
 */
class Errigal_Profile_Widget extends Errigal_Widget_Base {
	/**
	 * Profile page URL.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	public const PROFILE_PAGE_URL = 'profile_page_url';

	/**
	 * Profile page title.
	 *
	 * @since 1.1.0
	 *
	 * @var string
	 */
	public const PROFILE_PAGE_TITLE = 'profile_page_title';

	/**
	 * Name.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	public const NAME = self::ID_NAME;

	/**
	 * Description.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	public const DESCRIPTION = self::ID_DESCRIPTION;

	/**
	 * URL: Facebook.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	public const URL_FACEBOOK = self::ID_FACEBOOK_URL;

	/**
	 * URL: GitHub.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	public const URL_GITHUB = self::ID_GITHUB_URL;

	/**
	 * URL: Instagram.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	public const URL_INSTAGRAM = self::ID_INSTAGRAM_URL;

	/**
	 * URL: LINE.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	public const URL_LINE = self::ID_LINE_URL;

	/**
	 * URL: LinkedIn.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	public const URL_LINKEDIN = self::ID_LINKEDIN_URL;

	/**
	 * URL: Twitter.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	public const URL_TWITTER = self::ID_TWITTER_URL;

	/**
	 * URL: X.
	 *
	 * @since 1.0.5
	 *
	 * @var string
	 */
	public const URL_X = self::ID_X_URL;

	/**
	 * URL: YouTube.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	public const URL_YOUTUBE = self::ID_YOUTUBE_URL;

	/**
	 * Base ID for widget.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	private const ID_BASE = 'errigal_profile';

	/**
	 * Setting ID: Profile page ID.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	private const ID_PROFILE_PAGE_ID = 'profile_page_id';

	/**
	 * Setting ID: Image URL.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	private const ID_IMAGE_URL = self::IMAGE_URL;

	/**
	 * Setting ID: Name.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	private const ID_NAME = 'name';

	/**
	 * Setting ID: Description.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	private const ID_DESCRIPTION = 'description';

	/**
	 * Setting ID: Facebook URL.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	private const ID_FACEBOOK_URL = Social_Link::URL_FACEBOOK;

	/**
	 * Setting ID: GitHub URL.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	private const ID_GITHUB_URL = Social_Link::URL_GITHUB;

	/**
	 * Setting ID: Instagram URL.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	private const ID_INSTAGRAM_URL = Social_Link::URL_INSTAGRAM;

	/**
	 * Setting ID: LINE URL.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	private const ID_LINE_URL = Social_Link::URL_LINE;

	/**
	 * Setting ID: LinkedIn URL.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	private const ID_LINKEDIN_URL = Social_Link::URL_LINKEDIN;

	/**
	 * Setting ID: Twitter URL.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	private const ID_TWITTER_URL = Social_Link::URL_TWITTER;

	/**
	 * Setting ID: X URL.
	 *
	 * @since 1.0.5
	 *
	 * @var string
	 */
	private const ID_X_URL = Social_Link::URL_X;

	/**
	 * Setting ID: YouTube URL.
	 *
	 * @since 1.0.3
	 *
	 * @var string
	 */
	private const ID_YOUTUBE_URL = Social_Link::URL_YOUTUBE;

	/**
	 * Constructor.
	 *
	 * @since 1.0.3
	 *
	 * @link https://developer.wordpress.org/reference/classes/wp_widget/__construct/
	 */
	public function __construct() {
		parent::__construct(
			self::ID_BASE,
			esc_html(
				sprintf(
				/* translators: %s: Name of the current theme. */
					__( '(%s) Profile', 'errigal' ),
					Theme_Info::get_theme_name()
				)
			),
			array(
				self::WIDGET_CLASSNAME                   => 'errigal-profile-widget',
				self::WIDGET_DESCRIPTION                 => esc_html__( 'A widget to display your profile.', 'errigal' ),
				self::WIDGET_CUSTOMIZE_SELECTIVE_REFRESH => true,
			)
		);
	}

	/**
	 * Renders HTML with content for current profile widget instance.
	 *
	 * @since 1.0.3
	 *
	 * @link https://developer.wordpress.org/reference/classes/wp_widget/widget/
	 *
	 * @param array $args     Associative array of display arguments for widget including 'before_title',
	 *                        'after_title', 'before_widget', and 'after_widget'.
	 * @param array $instance Associative array of arguments for current profile widget instance.
	 * @return void
	 */
	public function widget( $args, $instance ) {
		if (
			! Validator::is_associative_array( $args ) ||
			! is_array( $instance )
		) {
			return;
		}

		$args = wp_parse_args(
			$args,
			array(
				self::WIDGET_ARG_BEFORE_WIDGET => '',
				self::WIDGET_ARG_AFTER_WIDGET  => '',
				self::WIDGET_ARG_BEFORE_TITLE  => '',
				self::WIDGET_ARG_AFTER_TITLE   => '',
			)
		);

		$before_widget = $args[ self::WIDGET_ARG_BEFORE_WIDGET ];
		$after_widget  = $args[ self::WIDGET_ARG_AFTER_WIDGET ];
		$before_title  = $args[ self::WIDGET_ARG_BEFORE_TITLE ];
		$after_title   = $args[ self::WIDGET_ARG_AFTER_TITLE ];

		if (
			! Validator::is_non_empty_string( $after_widget ) ||
			! Validator::is_non_empty_string( $before_widget ) ||
			! Validator::is_non_empty_string( $before_title ) ||
			! Validator::is_non_empty_string( $after_title )
		) {
			return;
		}

		$instance = wp_parse_args(
			$instance,
			array(
				self::ID_PROFILE_PAGE_ID => '',
				self::ID_IMAGE_URL       => '',
				self::ID_NAME            => '',
				self::ID_DESCRIPTION     => '',
				self::ID_FACEBOOK_URL    => '',
				self::ID_X_URL           => '',
				self::ID_TWITTER_URL     => '',
				self::ID_INSTAGRAM_URL   => '',
				self::ID_LINKEDIN_URL    => '',
				self::ID_YOUTUBE_URL     => '',
				self::ID_GITHUB_URL      => '',
				self::ID_LINE_URL        => '',
			)
		);

		$profile_page_id          = $instance[ self::ID_PROFILE_PAGE_ID ];
		$is_profile_page_selected = Validator::is_page_selected( $profile_page_id );
		$profile_page_url         = Validator::is_true( $is_profile_page_selected )
			? get_permalink( $profile_page_id )
			: '';
		$profile_page_title       = Validator::is_true( $is_profile_page_selected )
			? get_the_title( $profile_page_id )
			: '';

		echo wp_kses_post( $before_widget ) .
			wp_kses_post(
				Utility::add_class(
					$before_title,
					Accessibility_Class::SCREEN_READER_TEXT,
				)
			) .
			esc_html__( 'Profile', 'errigal' ) .
			wp_kses_post( $after_title );

		get_template_part(
			'template-parts/widget/profile',
			null,
			array(
				self::PROFILE_PAGE_URL   => esc_url( $profile_page_url ),
				self::PROFILE_PAGE_TITLE => esc_attr( $profile_page_title ),
				self::IMAGE_URL          => esc_url( $instance[ self::ID_IMAGE_URL ] ),
				self::IMAGE_ALT          => esc_attr__( 'Profile image', 'errigal' ),
				self::NAME               => esc_html( $instance[ self::ID_NAME ] ),
				self::DESCRIPTION        => wp_kses_post( $instance[ self::ID_DESCRIPTION ] ),
				self::URL_FACEBOOK       => esc_url( $instance[ self::ID_FACEBOOK_URL ] ),
				self::URL_X              => esc_url( $instance[ self::ID_X_URL ] ),
				self::URL_TWITTER        => esc_url( $instance[ self::ID_TWITTER_URL ] ),
				self::URL_INSTAGRAM      => esc_url( $instance[ self::ID_INSTAGRAM_URL ] ),
				self::URL_LINKEDIN       => esc_url( $instance[ self::ID_LINKEDIN_URL ] ),
				self::URL_YOUTUBE        => esc_url( $instance[ self::ID_YOUTUBE_URL ] ),
				self::URL_GITHUB         => esc_url( $instance[ self::ID_GITHUB_URL ] ),
				self::URL_LINE           => esc_url( $instance[ self::ID_LINE_URL ] ),
			)
		);

		echo wp_kses_post( $after_widget );
	}

	/**
	 * Renders HTML with settings form for profile widget.
	 *
	 * @since 1.0.3
	 *
	 * @link https://developer.wordpress.org/reference/classes/wp_widget/form/
	 *
	 * @param array $instance Associative array of arguments for form.
	 * @return void
	 */
	public function form( $instance ) {
		$controls = $this->get_form_controls( $instance );

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

		$this->render_form( $controls );
	}

	/**
	 * Handles updating arguments for current profile widget instance.
	 *
	 * @since 1.0.3
	 *
	 * @link https://developer.wordpress.org/reference/classes/wp_widget/update/
	 *
	 * @param array $new_instance Associative array of new arguments for instance as input by user via WP_Widget::form().
	 * @param array $old_instance Associative array of old arguments for this instance.
	 * @return array
	 */
	public function update( $new_instance, $old_instance ) {
		if ( ! is_array( $new_instance ) || ! is_array( $old_instance ) ) {
			return array();
		}

		$new_instance = wp_parse_args(
			$new_instance,
			array(
				self::ID_NAME            => '',
				self::ID_IMAGE_URL       => '',
				self::ID_PROFILE_PAGE_ID => '',
				self::ID_DESCRIPTION     => '',
				self::ID_FACEBOOK_URL    => '',
				self::ID_X_URL           => '',
				self::ID_TWITTER_URL     => '',
				self::ID_INSTAGRAM_URL   => '',
				self::ID_LINKEDIN_URL    => '',
				self::ID_YOUTUBE_URL     => '',
				self::ID_GITHUB_URL      => '',
				self::ID_LINE_URL        => '',
			)
		);

		$instance                             = $old_instance;
		$instance[ self::ID_NAME ]            = sanitize_text_field( $new_instance[ self::ID_NAME ] );
		$instance[ self::ID_IMAGE_URL ]       = esc_url_raw( $new_instance[ self::ID_IMAGE_URL ] );
		$instance[ self::ID_PROFILE_PAGE_ID ] = intval( $new_instance[ self::ID_PROFILE_PAGE_ID ] );
		$instance[ self::ID_DESCRIPTION ]     = wp_kses_post( $new_instance[ self::ID_DESCRIPTION ] );
		$instance[ self::ID_FACEBOOK_URL ]    = esc_url_raw( $new_instance[ self::ID_FACEBOOK_URL ] );
		$instance[ self::ID_X_URL ]           = esc_url_raw( $new_instance[ self::ID_X_URL ] );
		$instance[ self::ID_TWITTER_URL ]     = esc_url_raw( $new_instance[ self::ID_TWITTER_URL ] );
		$instance[ self::ID_INSTAGRAM_URL ]   = esc_url_raw( $new_instance[ self::ID_INSTAGRAM_URL ] );
		$instance[ self::ID_LINKEDIN_URL ]    = esc_url_raw( $new_instance[ self::ID_LINKEDIN_URL ] );
		$instance[ self::ID_YOUTUBE_URL ]     = esc_url_raw( $new_instance[ self::ID_YOUTUBE_URL ] );
		$instance[ self::ID_GITHUB_URL ]      = esc_url_raw( $new_instance[ self::ID_GITHUB_URL ] );
		$instance[ self::ID_LINE_URL ]        = esc_url_raw( $new_instance[ self::ID_LINE_URL ] );

		return $instance;
	}

	/**
	 * Gets form controls.
	 *
	 * @since 1.1.0
	 *
	 * @param array $instance Associative array of arguments for form controls.
	 * @return array
	 */
	private function get_form_controls( $instance ) {
		if ( ! is_array( $instance ) ) {
			return array();
		}

		$instance = wp_parse_args(
			$instance,
			array(
				self::ID_NAME            => '',
				self::ID_IMAGE_URL       => '',
				self::ID_PROFILE_PAGE_ID => '',
				self::ID_DESCRIPTION     => '',
				self::ID_FACEBOOK_URL    => '',
				self::ID_X_URL           => '',
				self::ID_TWITTER_URL     => '',
				self::ID_INSTAGRAM_URL   => '',
				self::ID_LINKEDIN_URL    => '',
				self::ID_YOUTUBE_URL     => '',
				self::ID_GITHUB_URL      => '',
				self::ID_LINE_URL        => '',
			)
		);

		$controls = array(
			self::ID_NAME            => array(
				self::CONTROL_LABEL => esc_html__( 'Profile name', 'errigal' ),
				self::CONTROL_VALUE => esc_attr( $instance[ self::ID_NAME ] ),
			),
			self::ID_IMAGE_URL       => array(
				self::CONTROL_LABEL   => esc_html__( 'Profile image', 'errigal' ),
				self::CONTROL_TYPE    => self::CONTROL_TYPE_IMAGE,
				self::CONTROL_VALUE   => esc_url( $instance[ self::ID_IMAGE_URL ] ),
				self::CONTROL_OPTIONS => array(
					/* translators: Must be lowercase when appropriate for the language in use. */
					self::CONTROL_OPTIONS_IMAGE_TYPE      => esc_html_x( 'profile image', 'Image type used as part of widget image button captions', 'errigal' ),
					self::CONTROL_OPTIONS_IS_CIRCLE_IMAGE => true,
				),
			),
			self::ID_PROFILE_PAGE_ID => array(
				self::CONTROL_LABEL   => esc_html__( 'Profile page link on profile image', 'errigal' ),
				self::CONTROL_TYPE    => self::CONTROL_TYPE_DROPDOWN_PAGES,
				self::CONTROL_VALUE   => esc_html( $instance[ self::ID_PROFILE_PAGE_ID ] ),
				self::CONTROL_DEFAULT => esc_html__( 'No link', 'errigal' ),
			),
			self::ID_DESCRIPTION     => array(
				self::CONTROL_LABEL => esc_html__( 'Profile description (HTML tags can be used)', 'errigal' ),
				self::CONTROL_TYPE  => self::CONTROL_TYPE_TEXTAREA,
				self::CONTROL_VALUE => esc_textarea( $instance[ self::ID_DESCRIPTION ] ),
			),
			self::ID_FACEBOOK_URL    => array(
				self::CONTROL_LABEL => esc_html__( 'Facebook URL', 'errigal' ),
				self::CONTROL_TYPE  => self::CONTROL_TYPE_URL,
				self::CONTROL_VALUE => esc_url( $instance[ self::ID_FACEBOOK_URL ] ),
			),
			self::ID_X_URL           => array(
				self::CONTROL_LABEL => esc_html__( 'X URL', 'errigal' ),
				self::CONTROL_TYPE  => self::CONTROL_TYPE_URL,
				self::CONTROL_VALUE => esc_url( $instance[ self::ID_X_URL ] ),
			),
			self::ID_TWITTER_URL     => array(
				self::CONTROL_LABEL => esc_html__( 'Twitter URL', 'errigal' ),
				self::CONTROL_TYPE  => self::CONTROL_TYPE_URL,
				self::CONTROL_VALUE => esc_url( $instance[ self::ID_TWITTER_URL ] ),
			),
			self::ID_INSTAGRAM_URL   => array(
				self::CONTROL_LABEL => esc_html__( 'Instagram URL', 'errigal' ),
				self::CONTROL_TYPE  => self::CONTROL_TYPE_URL,
				self::CONTROL_VALUE => esc_url( $instance[ self::ID_INSTAGRAM_URL ] ),
			),
			self::ID_LINKEDIN_URL    => array(
				self::CONTROL_LABEL => esc_html__( 'LinkedIn URL', 'errigal' ),
				self::CONTROL_TYPE  => self::CONTROL_TYPE_URL,
				self::CONTROL_VALUE => esc_url( $instance[ self::ID_LINKEDIN_URL ] ),
			),
			self::ID_YOUTUBE_URL     => array(
				self::CONTROL_LABEL => esc_html__( 'YouTube URL', 'errigal' ),
				self::CONTROL_TYPE  => self::CONTROL_TYPE_URL,
				self::CONTROL_VALUE => esc_url( $instance[ self::ID_YOUTUBE_URL ] ),
			),
			self::ID_GITHUB_URL      => array(
				self::CONTROL_LABEL => esc_html__( 'GitHub URL', 'errigal' ),
				self::CONTROL_TYPE  => self::CONTROL_TYPE_URL,
				self::CONTROL_VALUE => esc_url( $instance[ self::ID_GITHUB_URL ] ),
			),
			self::ID_LINE_URL        => array(
				self::CONTROL_LABEL => esc_html__( 'LINE URL', 'errigal' ),
				self::CONTROL_TYPE  => self::CONTROL_TYPE_URL,
				self::CONTROL_VALUE => esc_url( $instance[ self::ID_LINE_URL ] ),
			),
		);

		if ( ! Validator::is_non_empty_string( $instance[ self::ID_TWITTER_URL ] ) ) {
			unset( $controls[ self::ID_TWITTER_URL ] );
		}

		return $controls;
	}
}
