<?php
namespace hakoniwa\blocks\ssr\card;

use hakoniwa\blocks\init\Define;
use hakoniwa\blocks\util\Misc;

class Register {

	/**
	 * Construct.
	 */
	public function __construct() {
		add_action( 'init', array( $this, 'register_dynamic_block' ) );
	}

	/**
	 * ダイナミックブロック登録
	 *
	 * @return void
	 */
	public function register_dynamic_block() {
		register_block_type(
			Define::value( 'plugin_path' ) . 'build/card',
			array(
				'attributes'      => array(
					'cardUrl'                  => array(
						'type'    => 'string',
						'default' => '',
					),
					'cardTarget'               => array(
						'type'    => 'boolean',
						'default' => false,
					),
					'cardBackgroundColor'      => array(
						'type'    => 'string',
					),
					'cardBorderColor'          => array(
						'type'    => 'string',
					),
					'cardTextMainColor'        => array(
						'type'    => 'string',
					),
					'cardTextSubColor'         => array(
						'type'    => 'string',
					),
					'cardImageAlign'           => array(
						'type'    => 'string',
						'default' => 'card-image-left',
					),
					'cardImageAlt'             => array(
						'type'    => 'string',
						'default' => '',
					),
					'cardLabel'                => array(
						'type'    => 'string',
						'default' => '',
					),
					'cardLabelBackgroundColor' => array(
						'type'    => 'string',
					),
					'cardLabelTextColor'       => array(
						'type'    => 'string',
					),
					'cardLayout'               => array(
						'type'    => 'string',
						'default' => 'horizontal',
					),
					'cardAspectRatio'          => array(
						'type'    => 'string',
						'default' => '16-9',
					),
					'cardTitleEllipsis'        => array(
						'type'    => 'string',
						'default' => '',
					),
					'cardDescEllipsis'         => array(
						'type'    => 'string',
						'default' => '',
					),
					'cardDescription'          => array(
						'type'    => 'boolean',
						'default' => true,
					),
					'cardDomain'               => array(
						'type'    => 'boolean',
						'default' => true,
					),
				),
				'render_callback' => array( $this, 'block_callback' ),
			)
		);
	}

	/**
	 * レンダリング
	 *
	 * @param array $attributes 属性
	 * @return $card
	 */
	public function block_callback( $attributes, $content, $block ) {
		$card = '';

		if ( ! empty( $attributes['cardUrl'] ) ) {
			$get_post_id = url_to_postid( $attributes['cardUrl'] );

			if ( 0 !== $get_post_id ) {
				$card = $this->get_internal_post( $get_post_id, $attributes );
			} else {
				$card = $this->get_external_post( $attributes );
			}
		}

		return $card;
	}

	/**
	 * 内部リンク
	 *
	 * @param int   $post_id 投稿 ID
	 * @param array $attributes 属性
	 * @return $output
	 */
	public function get_internal_post( $post_id, $attributes ) {
		setup_postdata( $post_id );

		$desc        = '';
		$domain_name = '';
		$class       = '';

		$domain = ! empty( $_SERVER['SERVER_NAME'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_NAME'] ) ) : getenv( 'SERVER_NAME' );

		// Card Style
		$card_styles = array();

		if ( isset( $attributes['cardBorderColor'] ) ) {
			$card_styles['border-color'] = $attributes['cardBorderColor'];
		}

		if ( isset( $attributes['cardBackgroundColor'] ) ) {
			$card_styles['background-color'] = $attributes['cardBackgroundColor'];
		}

		$card_styles_output = $this->get_attrs_styles( $card_styles );

		// Card Title Style
		$card_title_styles = array();

		if ( isset( $attributes['cardTextMainColor'] ) ) {
			$card_title_styles['color'] = $attributes['cardTextMainColor'];
		}

		$card_title_styles_output = $this->get_attrs_styles( $card_title_styles );

		// Card Domain Style
		$card_domain_styles = array();

		if ( isset( $attributes['cardTextSubColor'] ) ) {
			$card_domain_styles['color'] = $attributes['cardTextSubColor'];
		}

		$card_domain_styles_output = $this->get_attrs_styles( $card_domain_styles );

		if ( ! empty( $attributes['cardDomain'] ) && $domain ) {
			$domain_name = '<span class="card-domain"' . $card_domain_styles_output . '>' . $domain . '</span>';
		}

		if ( get_post_field( 'post_excerpt', $post_id ) ) {
			$excerpt = trim( get_post_field( 'post_excerpt', $post_id ) );
		} else {
			$excerpt = wp_trim_words( get_post_field( 'post_content', $post_id ), 50 );
		}

		if ( ! empty( $attributes['cardTarget'] ) ) {
			$target = ' target="_blank" rel="noopener noreferrer"';
		} else {
			$target = '';
		}

		//クラス名などの属性を作成
		if ( isset( $attributes['cardImageAlign'] ) ) {
			$class .= $attributes['cardImageAlign'];
		}

		// Card Layout
		if ( isset( $attributes['cardLayout'] ) ) {
			$class .= ' ' . $attributes['cardLayout'];
		}

		// Card Label Style
		$card_label_styles = array();

		if ( isset( $attributes['cardLabelBackgroundColor'] ) ) {
			$card_label_styles['background-color'] = $attributes['cardLabelBackgroundColor'];
		}

		if ( isset( $attributes['cardLabelTextColor'] ) ) {
			$card_label_styles['color'] = $attributes['cardLabelTextColor'];
		}

		$card_label_styles_output = $this->get_attrs_styles( $card_label_styles );

		// Card Label
		if ( ! empty( $attributes['cardLabel'] ) ) {
			$label       = '<span class="card-label"' . $card_label_styles_output . '>' . $attributes['cardLabel'] . '</span>';
			$class      .= ' has-card-label';
		} else {
			$label       = '';
		}

		// AspectRatio
		if ( ! empty( $attributes['cardAspectRatio'] ) ) {
			$class .= ' has-aspect-ratio';
			$aspect_ratio       = ' aspect-ratio-' . $attributes['cardAspectRatio'];
		} else {
			$aspect_ratio       = '';
		}

		// Title Ellipsis
		if ( ! empty( $attributes['cardTitleEllipsis'] ) ) {
			$class .= ' has-title-ellipsis';
			$title_ellipsis       = ' title-ellipsis-' . $attributes['cardTitleEllipsis'];
		} else {
			$title_ellipsis       = '';
		}

		// Desc Ellipsis
		if ( ! empty( $attributes['cardDescEllipsis'] ) ) {
			$class .= ' has-desc-ellipsis';
			$desc_ellipsis       = ' desc-ellipsis-' . $attributes['cardDescEllipsis'];
		} else {
			$desc_ellipsis       = '';
		}

		if ( isset( $attributes['columns'] ) && $attributes['columns'] > 1 ) {
			$class .= ' flex gap-8 columns-' . absint( $attributes['columns'] );
		}

		if ( isset( $attributes['thumbnailPosition'] ) ) {
			$class .= ' featured-image-' . $attributes['thumbnailPosition'];
		}

		if ( isset( $attributes['displayThumbnail'] ) ) {
			$class .= ' has-featured-image';
		}

		$wrapper_attributes = get_block_wrapper_attributes( 
			array( 
				'class' => $class,
			)
		);

		$title = '<span class="card-title' . $title_ellipsis . '"' . $card_title_styles_output . '>' . get_the_title( $post_id ) . '</span>';

		if ( ! empty( $attributes['cardDescription'] ) ) {
			$desc = '<span class="card-desc' . $desc_ellipsis . '"' . $card_title_styles_output . '>' . $excerpt . '</span>';
		}

		if ( get_the_post_thumbnail( $post_id ) !== '' ) {
			$image = '<div class="card-image' . $aspect_ratio . '">' . get_the_post_thumbnail( $post_id, 'post-thumbnail', array( 'alt' => get_the_title( $post_id ) ) ) . '</div>';
		} else {
			$image = '';
		}

		$text = '<div class="card-text">' . $title . $desc . $domain_name . '</div>';

		$output = '<div ' . wp_kses_post( $wrapper_attributes ) . '><a class="card-link" ' . wp_kses_post( $target ) . ' href="' . esc_url( get_permalink( $post_id ) ) . '"' . wp_kses_post( $card_styles_output ) . '>' .  wp_kses_post( $label . $image . $text ) . '</a></div>';

		wp_reset_postdata();

		return $output;
	}

	/**
	 * 外部リンク
	 *
	 * @param array $attributes 属性
	 * @return $output
	 */
	public function get_external_post( $attributes ) {
		// delete_transient( Define::value( 'plugin_func_name' ) . '_card_' . $attributes['cardUrl'] . '_' . get_the_ID());
		$card_data = get_transient( Define::value( 'plugin_func_name' ) . '_card_' . $attributes['cardUrl'] . '_' . get_the_ID() );

		if ( false === $card_data ) {
			$request = wp_remote_get(
				$attributes['cardUrl'],
				array(
					'user-agent' => '',
				)
			);

			if ( isset( $request ) && ! empty( $request ) && ! is_wp_error( $request ) && 200 === $request['response']['code'] ) {

				$domain = wp_parse_url( $attributes['cardUrl'] );

				// Charset
				/* if ( preg_match( '/<meta.+?charset.*?=.*?["\'](.+)[ "\'].*?\/?>/i', $request['body'], $matches ) ) { */
				if ( preg_match( '/.+?charset=(.+)/i', $request['headers']['content-type'], $matches ) ) {
					if ( $matches[1] ) {
						$charset = $matches[1];
					} else {
						$charset = '';
					}
				}
				if ( $domain ) {
					// $favicon = '<img class="card-favicon" src="https://www.google.com/s2/favicons?domain=' . $domain['host'] . '">';
					// $domain_name = '<span class="card-domain" style="color:' . $attributes['cardTextSubColor'] . ';">' . $favicon . $domain['host'] . '</span>';
					$domain = $domain['host'];
				} else {
					$domain = '';
				}

				// Image
				if ( preg_match( '/<meta.+?(property|name)=["\'](og:image|twitter:image)["\'][^\/>]*?content=["\']([^"\']+?)["\'].*?\/?>/is', $request['body'], $matches ) ) {
					if ( $matches[3] ) {
						$thumbnail = $matches[3];
					} else {
						$thumbnail = $this->get_content_image( $request['body'] );
					}
				} else {
					$thumbnail = $this->get_content_image( $request['body'] );
				}

				// Title
				if ( preg_match( '/<title.*?>(.+?)<\/title>/is', $request['body'], $matches ) ) {
					if ( ! empty( $charset ) && mb_detect_encoding( $charset, 'UTF-8' ) ) {
						$title = mb_convert_encoding( $matches[1], 'UTF-8', $charset );
					} else {
						$title = $matches[1];
					}
				} else {
					$title = '';
				}

				//var_dump($title);

				// Description
				if ( preg_match( '/<meta.+?name=["\']description["\'][^\/>]*?content=["\']([^"\']+?)["\'].*?\/?>/is', $request['body'], $matches ) ) {

					if ( ! empty( $charset ) && mb_detect_encoding( $charset, 'UTF-8' ) ) {
						$desc = mb_convert_encoding( $matches[1], 'UTF-8', $charset );
					} else {
						$desc = $matches[1];
					}
				} else {
					$desc = '';
				}

				$card_data = array(
					'title'     => $title,
					'desc'      => $desc,
					'domain'    => $domain,
					'thumbnail' => $thumbnail,
				);

				set_transient( Define::value( 'plugin_func_name' ) . '_card_' . $attributes['cardUrl'] . '_' . get_the_ID(), $card_data, 60 * 60 * 24 * 10 );
			}
		}

		if ( ! empty( $card_data ) ) {
			$desc        = '';
			$domain_name = '';
			$class       = '';

			if ( ! empty( $attributes['cardTarget'] ) ) {
				$target = ' target="_blank" rel="noopener noreferrer"';
			} else {
				$target = '';
			}

			// Card Style
			$card_styles = array();

			if ( isset( $attributes['cardBorderColor'] ) ) {
				$card_styles['border-color'] = $attributes['cardBorderColor'];
			}

			if ( isset( $attributes['cardBackgroundColor'] ) ) {
				$card_styles['background-color'] = $attributes['cardBackgroundColor'];
			}

			$card_styles_output = $this->get_attrs_styles( $card_styles );

			// Card Title Style
			$card_title_styles = array();

			if ( isset( $attributes['cardTextMainColor'] ) ) {
				$card_title_styles['color'] = $attributes['cardTextMainColor'];
			}

			$card_title_styles_output = $this->get_attrs_styles( $card_title_styles );

			// Card Domain Style
			$card_domain_styles = array();

			if ( isset( $attributes['cardTextSubColor'] ) ) {
				$card_domain_styles['color'] = $attributes['cardTextSubColor'];
			}

			$card_domain_styles_output = $this->get_attrs_styles( $card_domain_styles );

			//クラス名などの属性を作成
			if ( isset( $attributes['cardImageAlign'] ) ) {
				$class .= $attributes['cardImageAlign'];
			}

			// Card Layout
			if ( isset( $attributes['cardLayout'] ) ) {
				$class .= ' ' . $attributes['cardLayout'];
			}

			// Card Label Style
			$card_label_styles = array();

			if ( isset( $attributes['cardLabelBackgroundColor'] ) ) {
				$card_label_styles['background-color'] = $attributes['cardLabelBackgroundColor'];
			}

			if ( isset( $attributes['cardLabelTextColor'] ) ) {
				$card_label_styles['color'] = $attributes['cardLabelTextColor'];
			}

			$card_label_styles_output = $this->get_attrs_styles( $card_label_styles );

			// Card Label
			if ( ! empty( $attributes['cardLabel'] ) ) {
				$label       = '<span class="card-label"' . $card_label_styles_output . '>' . $attributes['cardLabel'] . '</span>';
				$class      .= ' has-card-label';
			} else {
				$label       = '';
			}

			// AspectRatio
			if ( ! empty( $attributes['cardAspectRatio'] ) ) {
				$class .= ' has-aspect-ratio';
				$aspect_ratio       = ' aspect-ratio-' . $attributes['cardAspectRatio'];
			} else {
				$aspect_ratio       = '';
			}			

			// Title Ellipsis
			if ( ! empty( $attributes['cardTitleEllipsis'] ) ) {
				$class .= ' has-title-ellipsis';
				$title_ellipsis       = ' title-ellipsis-' . $attributes['cardTitleEllipsis'];
			} else {
				$title_ellipsis       = '';
			}			

			// Desc Ellipsis
			if ( ! empty( $attributes['cardDescEllipsis'] ) ) {
				$class              .= ' has-desc-ellipsis';
				$desc_ellipsis       = ' desc-ellipsis-' . $attributes['cardDescEllipsis'];
			} else {
				$desc_ellipsis       = '';
			}			
			
			if ( isset( $attributes['columns'] ) && $attributes['columns'] > 1 ) {
				$class .= ' flex gap-8 columns-' . absint( $attributes['columns'] );
			}

			if ( isset( $attributes['thumbnailPosition'] ) ) {
				$class .= ' featured-image-' . $attributes['thumbnailPosition'];
			}

			if ( isset( $attributes['displayThumbnail'] ) ) {
				$class .= ' has-featured-image';
			}

			$wrapper_attributes = get_block_wrapper_attributes( 
				array(
					'class' => $class,
				)
			);

			$title = '<span class="card-title' . $title_ellipsis . '"' . $card_title_styles_output . '>' . $card_data['title'] . '</span>';

			if ( ! empty( $attributes['cardDescription'] ) && '' !== $card_data['desc'] ) {
				$desc = '<span class="card-desc' . $desc_ellipsis . '"' . $card_title_styles_output . '>' . $card_data['desc'] . '</span>';
			}

			if ( ! empty( $attributes['cardDomain'] ) && '' !== $card_data['domain'] ) {
				$domain_name = '<span class="card-domain"' . $card_domain_styles_output . '>' . $card_data['domain'] . '</span>';
			}

			$card_text = '<div class="card-text">' . wp_kses_post( $label . $title . $desc . $domain_name ) . '</div>';

			if ( ! empty( $card_data['thumbnail'] ) ) {
				$card_image = '<div class="card-image' . $aspect_ratio . '"><img src="' . $card_data['thumbnail'] . '" alt="' . $card_data['title'] . '"></div>';
			} else {
				$card_image = '';
			}

			$output = '<div ' . wp_kses_post( $wrapper_attributes ) . '><a class="card-link" ' . wp_kses_post( $target ) . ' href="' . esc_url( $attributes['cardUrl'] ) . '"' . wp_kses_post( $card_styles_output ) . '>' . wp_kses_post( $card_image . $card_text ) . '</a></div>';
		} else {
			return false;
		}

		return $output;
	}

	/**
	 * Get Contents First Image
	 *
	 * @param string $content 本文
	 * @return $thumbnail
	 */
	public function get_content_image( $content ) {
		ob_start();
		ob_end_clean();
		preg_match_all( '/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $content, $matches );

		if ( isset( $matches[1][0] ) && ! is_wp_error( $matches[1][0] ) ) {
			$thumbnail = $matches[1][0];
		} else {
			$thumbnail = '';
		}

		return $thumbnail;
	}

	/**
	 * Get Styles
	 *
	 * @param array $attributes 属性
	 * @return $output
	 */
	public function get_attrs_styles( $attributes = array() ) {
		if( empty( $attributes ) ){
			return false;
		}

		$output = ' style="';

		foreach( $attributes as $key => $val ) {
			$output .= $key . ':' . $val . ';';
		}

		$output .= '"';

		return $output;
	}
}

use hakoniwa\blocks\ssr\card\Register;
new Register();