<?php
/**
 * Dynamic content widgets (site / post / taxonomy context).
 *
 * @package AuraBuilder
 */

declare(strict_types=1);

namespace AuraBuilder\Widgets\Basic;

use AuraBuilder\Document\Node;
use AuraBuilder\Widgets\WidgetBase;

final class DynamicWidget extends WidgetBase {

	/** @var list<string> */
	public const SOURCES = array(
		'site_logo',
		'site_title',
		'site_tagline',
		'navigation',
		'avatar',
		'featured_image',
		'post_title',
		'post_content',
		'post_excerpt',
		'post_date',
		'post_modified',
		'post_author',
		'author_bio',
		'comment_count',
		'categories',
		'tags',
		'read_time',
		'word_count',
		'prev_post',
		'next_post',
		'breadcrumbs',
		'archive_title',
		'search_title',
		'term_name',
		'term_description',
		'term_count',
		'login_logout',
		'read_more',
	);

	public function get_type(): string {
		return 'dynamic';
	}

	public function get_title(): string {
		return 'Dinâmico';
	}

	public function get_category(): string {
		return 'dynamic';
	}

	public function get_icon(): string {
		return 'dynamic';
	}

	public function get_defaults(): array {
		return array(
			'source' => 'site_title',
			'align'  => 'left',
			'link'   => '1',
			'menu'   => '',
		);
	}

	public function sanitize_settings( array $settings ): array {
		$source = sanitize_key( (string) ( $settings['source'] ?? 'site_title' ) );
		if ( ! in_array( $source, self::SOURCES, true ) ) {
			$source = 'site_title';
		}
		$align = (string) ( $settings['align'] ?? 'left' );
		if ( ! in_array( $align, array( 'left', 'center', 'right' ), true ) ) {
			$align = 'left';
		}
		return array(
			'source' => $source,
			'align'  => $align,
			'link'   => empty( $settings['link'] ) || $settings['link'] === '0' || $settings['link'] === false ? '0' : '1',
			'menu'   => sanitize_text_field( (string) ( $settings['menu'] ?? '' ) ),
		);
	}

	public function render( Node $node, array $context = array() ): string {
		$s      = $node->settings;
		$source = (string) ( $s['source'] ?? 'site_title' );
		$align  = esc_attr( (string) ( $s['align'] ?? 'left' ) );
		$link   = ( $s['link'] ?? '1' ) !== '0';
		$editor = ! empty( $context['editor'] );

		$inner = $this->render_source( $source, $s, $link, $editor );
		if ( $inner === '' ) {
			return $editor
				? '<div class="ab-dynamic ab-dynamic--empty" style="text-align:' . $align . '">[' . esc_html( $source ) . ']</div>'
				: '';
		}
		return '<div class="ab-dynamic ab-dynamic--' . esc_attr( $source ) . '" style="text-align:' . $align . '" data-dynamic="' . esc_attr( $source ) . '">' . $inner . '</div>';
	}

	/**
	 * @param array<string, mixed> $s
	 */
	private function render_source( string $source, array $s, bool $link, bool $editor ): string {
		$post = get_post();
		$pid  = $post ? (int) $post->ID : 0;

		switch ( $source ) {
			case 'site_logo':
				if ( function_exists( 'has_custom_logo' ) && has_custom_logo() ) {
					$html = get_custom_logo();
					return is_string( $html ) ? $html : '';
				}
				$name = get_bloginfo( 'name' );
				return $link
					? '<a class="ab-dynamic-logo-text" href="' . esc_url( home_url( '/' ) ) . '">' . esc_html( $name ) . '</a>'
					: '<span class="ab-dynamic-logo-text">' . esc_html( $name ) . '</span>';

			case 'site_title':
				$name = get_bloginfo( 'name' );
				return $link
					? '<a href="' . esc_url( home_url( '/' ) ) . '">' . esc_html( $name ) . '</a>'
					: esc_html( $name );

			case 'site_tagline':
				return esc_html( (string) get_bloginfo( 'description' ) );

			case 'navigation':
				$menu = (string) ( $s['menu'] ?? '' );
				$args = array(
					'container'   => 'nav',
					'container_class' => 'ab-dynamic-nav',
					'menu_class'  => 'ab-dynamic-menu',
					'fallback_cb' => static function () use ( $editor ): string {
						return $editor ? '<span class="ab-dynamic-placeholder">Menu — defina em Aparência → Menus</span>' : '';
					},
					'echo'        => false,
				);
				if ( $menu !== '' && is_numeric( $menu ) ) {
					$args['menu'] = (int) $menu;
				} else {
					$args['theme_location'] = $menu !== '' ? $menu : 'primary';
					// Try common locations if primary missing.
					$locs = get_nav_menu_locations();
					if ( empty( $locs[ $args['theme_location'] ] ) && ! empty( $locs ) ) {
						$args['theme_location'] = (string) array_key_first( $locs );
					}
				}
				$html = wp_nav_menu( $args );
				return is_string( $html ) ? $html : '';

			case 'avatar':
				$id = get_current_user_id();
				if ( ! $id && $pid ) {
					$id = (int) get_post_field( 'post_author', $pid );
				}
				if ( ! $id ) {
					return $editor ? '<span class="ab-dynamic-placeholder">Avatar</span>' : '';
				}
				return get_avatar( $id, 96, '', '', array( 'class' => 'ab-dynamic-avatar' ) );

			case 'featured_image':
				if ( ! $pid || ! has_post_thumbnail( $pid ) ) {
					return $editor ? '<div class="ab-img-ph">Imagem destacada</div>' : '';
				}
				$img = get_the_post_thumbnail( $pid, 'large', array( 'class' => 'ab-dynamic-featured' ) );
				return is_string( $img ) ? $img : '';

			case 'post_title':
				if ( ! $pid ) {
					return $editor ? esc_html( 'Título do post' ) : '';
				}
				$t = get_the_title( $pid );
				return $link
					? '<a href="' . esc_url( get_permalink( $pid ) ?: '#' ) . '">' . esc_html( $t ) . '</a>'
					: esc_html( $t );

			case 'post_content':
				// FSE "Conteúdo" — corpo do post para templates Single.
				if ( ! $pid ) {
					return $editor
						? '<div class="ab-dynamic-post-content ab-dynamic-placeholder entry-content">'
							. '<p><strong>Conteúdo do post</strong></p>'
							. '<p>Exibe o conteúdo real do post no site (parágrafos, imagens, galerias…).</p>'
							. '</div>'
						: '';
				}
				$post = get_post( $pid );
				if ( ! $post ) {
					return '';
				}
				// Posts built with Aura: miolo já é o builder — evitar reentrância.
				if ( defined( 'AURA_BUILDER_META_ON' ) && get_post_meta( $pid, AURA_BUILDER_META_ON, true ) === '1' ) {
					return $editor
						? '<div class="ab-dynamic-post-content ab-dynamic-placeholder">Conteúdo desta página é o layout Aura (miolo).</div>'
						: '';
				}
				$prev = $GLOBALS['post'] ?? null;
				// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
				$GLOBALS['post'] = $post;
				setup_postdata( $post );
				// Skip Aura ContentFilter (Single re-entry → OOM). Keep other WP filters.
				$GLOBALS['ab_skip_content_filter'] = true;
				$rendered = apply_filters( 'the_content', (string) $post->post_content );
				unset( $GLOBALS['ab_skip_content_filter'] );
				wp_reset_postdata();
				if ( $prev ) {
					// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
					$GLOBALS['post'] = $prev;
				}
				return '<div class="ab-dynamic-post-content entry-content">' . $rendered . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

			case 'post_excerpt':
				if ( ! $pid ) {
					return $editor ? esc_html( 'Resumo do post…' ) : '';
				}
				$ex = get_the_excerpt( $pid );
				return esc_html( wp_strip_all_tags( (string) $ex ) );

			case 'post_date':
				$fmt = (string) get_option( 'date_format', 'd/m/Y' );
				if ( ! $pid ) {
					return $editor ? esc_html( wp_date( $fmt ) ) : '';
				}
				return esc_html( get_the_date( $fmt, $pid ) );

			case 'post_modified':
				$fmt = (string) get_option( 'date_format', 'd/m/Y' );
				if ( ! $pid ) {
					return $editor ? esc_html( wp_date( $fmt ) ) : '';
				}
				return esc_html( get_the_modified_date( $fmt, $pid ) );

			case 'post_author':
				if ( ! $pid ) {
					return $editor ? esc_html( 'Autor' ) : '';
				}
				$name = get_the_author_meta( 'display_name', (int) get_post_field( 'post_author', $pid ) );
				$url  = get_author_posts_url( (int) get_post_field( 'post_author', $pid ) );
				return $link
					? '<a href="' . esc_url( $url ) . '">' . esc_html( $name ) . '</a>'
					: esc_html( $name );

			case 'author_bio':
				if ( ! $pid ) {
					return $editor ? esc_html( 'Biografia do autor' ) : '';
				}
				$bio = get_the_author_meta( 'description', (int) get_post_field( 'post_author', $pid ) );
				return esc_html( (string) $bio );

			case 'comment_count':
				if ( ! $pid ) {
					return $editor ? '0 comentários' : '';
				}
				$n = (int) get_comments_number( $pid );
				return esc_html( sprintf( _n( '%s comentário', '%s comentários', $n, 'auranet-page-theme-builder' ), number_format_i18n( $n ) ) );

			case 'categories':
				if ( ! $pid ) {
					return $editor ? esc_html( 'Categorias' ) : '';
				}
				$list = get_the_term_list( $pid, 'category', '', ', ', '' );
				return is_string( $list ) ? $list : '';

			case 'tags':
				if ( ! $pid ) {
					return $editor ? esc_html( 'Tags' ) : '';
				}
				$list = get_the_term_list( $pid, 'post_tag', '', ', ', '' );
				return is_string( $list ) ? $list : '';

			case 'read_time':
				if ( ! $pid ) {
					return $editor ? '3 min' : '';
				}
				$content = (string) get_post_field( 'post_content', $pid );
				$words   = str_word_count( wp_strip_all_tags( $content ) );
				$mins    = max( 1, (int) ceil( $words / 200 ) );
				return esc_html( sprintf( /* translators: minutes */ __( '%d min de leitura', 'auranet-page-theme-builder' ), $mins ) );

			case 'word_count':
				if ( ! $pid ) {
					return $editor ? '0 palavras' : '';
				}
				$content = (string) get_post_field( 'post_content', $pid );
				$words   = str_word_count( wp_strip_all_tags( $content ) );
				return esc_html( sprintf( /* translators: word count */ __( '%s palavras', 'auranet-page-theme-builder' ), number_format_i18n( $words ) ) );

			case 'prev_post':
				$p = $pid ? get_adjacent_post( false, '', true ) : null;
				if ( ! $p instanceof \WP_Post ) {
					return $editor ? esc_html( 'Post anterior' ) : '';
				}
				return '<a href="' . esc_url( get_permalink( $p ) ?: '#' ) . '">« ' . esc_html( get_the_title( $p ) ) . '</a>';

			case 'next_post':
				$p = $pid ? get_adjacent_post( false, '', false ) : null;
				if ( ! $p instanceof \WP_Post ) {
					return $editor ? esc_html( 'Próximo post' ) : '';
				}
				return '<a href="' . esc_url( get_permalink( $p ) ?: '#' ) . '">' . esc_html( get_the_title( $p ) ) . ' »</a>';

			case 'breadcrumbs':
				$parts = array( '<a href="' . esc_url( home_url( '/' ) ) . '">' . esc_html__( 'Início', 'auranet-page-theme-builder' ) . '</a>' );
				if ( is_singular() && $pid ) {
					$parts[] = esc_html( get_the_title( $pid ) );
				} elseif ( is_category() || is_tag() || is_tax() ) {
					$parts[] = esc_html( single_term_title( '', false ) );
				} elseif ( is_search() ) {
					$parts[] = esc_html__( 'Busca', 'auranet-page-theme-builder' );
				} elseif ( is_archive() ) {
					$parts[] = esc_html( get_the_archive_title() );
				}
				return '<nav class="ab-breadcrumbs">' . implode( ' <span class="ab-bc-sep">/</span> ', $parts ) . '</nav>';

			case 'archive_title':
				if ( is_archive() ) {
					return esc_html( wp_strip_all_tags( get_the_archive_title() ) );
				}
				return $editor ? esc_html( 'Título do arquivo' ) : '';

			case 'search_title':
				if ( is_search() ) {
					return esc_html( sprintf( __( 'Resultados para: %s', 'auranet-page-theme-builder' ), get_search_query() ) );
				}
				return $editor ? esc_html( 'Título da busca' ) : '';

			case 'term_name':
				$term = get_queried_object();
				if ( $term instanceof \WP_Term ) {
					return esc_html( $term->name );
				}
				return $editor ? esc_html( 'Nome do termo' ) : '';

			case 'term_description':
				$term = get_queried_object();
				if ( $term instanceof \WP_Term ) {
					return wp_kses_post( term_description( $term ) );
				}
				return $editor ? esc_html( 'Descrição do termo' ) : '';

			case 'term_count':
				$term = get_queried_object();
				if ( $term instanceof \WP_Term ) {
					return esc_html( (string) $term->count );
				}
				return $editor ? '0' : '';

			case 'login_logout':
				if ( is_user_logged_in() ) {
					return '<a href="' . esc_url( wp_logout_url( home_url( '/' ) ) ) . '">' . esc_html__( 'Sair', 'auranet-page-theme-builder' ) . '</a>';
				}
				return '<a href="' . esc_url( wp_login_url() ) . '">' . esc_html__( 'Acessar', 'auranet-page-theme-builder' ) . '</a>';

			case 'read_more':
				if ( ! $pid ) {
					return $editor ? '<a href="#">Leia mais</a>' : '';
				}
				return '<a class="ab-read-more" href="' . esc_url( get_permalink( $pid ) ?: '#' ) . '">' . esc_html__( 'Leia mais', 'auranet-page-theme-builder' ) . '</a>';

			default:
				return $editor ? esc_html( $source ) : '';
		}
	}
}
