<?php
/**
 * Tooto 面包屑组件。
 */

namespace Tooto_Elementor\Widgets;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use Elementor\Controls_Manager;
use Elementor\Group_Control_Typography;
use Elementor\Widget_Base;

class Breadcrumbs extends Widget_Base {
	public function get_name(): string {
		return 'tooto-breadcrumbs';
	}

	public function get_title(): string {
		return __( 'Tooto 面包屑', 'tooto-elementor' );
	}

	public function get_icon(): string {
		return 'eicon-navigation-menu';
	}

	public function get_categories(): array {
		return [ 'tooto' ];
	}

	public function get_keywords(): array {
		return [ 'breadcrumb', 'breadcrumbs', 'nav', '导航', '路径', '面包屑', 'tooto' ];
	}

	public function get_style_depends(): array {
		return [ 'tooto-elementor' ];
	}

	protected function register_controls(): void {
		$this->start_controls_section(
			'section_content',
			[
				'label' => __( '内容', 'tooto-elementor' ),
			]
		);

		$this->add_control(
			'show_home',
			[
				'label'        => __( '显示首页', 'tooto-elementor' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => __( '显示', 'tooto-elementor' ),
				'label_off'    => __( '隐藏', 'tooto-elementor' ),
				'return_value' => 'yes',
				'default'      => 'yes',
			]
		);

		$this->add_control(
			'home_label',
			[
				'label'       => __( '首页文字', 'tooto-elementor' ),
				'type'        => Controls_Manager::TEXT,
				'placeholder' => __( '首页', 'tooto-elementor' ),
				'default'     => __( '首页', 'tooto-elementor' ),
				'condition'   => [
					'show_home' => 'yes',
				],
			]
		);

		$this->add_control(
			'include_current',
			[
				'label'        => __( '显示当前页', 'tooto-elementor' ),
				'description'  => __( '关闭后仅展示层级，不包含当前页面标题。', 'tooto-elementor' ),
				'type'         => Controls_Manager::SWITCHER,
				'label_on'     => __( '显示', 'tooto-elementor' ),
				'label_off'    => __( '隐藏', 'tooto-elementor' ),
				'return_value' => 'yes',
				'default'      => 'yes',
			]
		);

		$this->add_control(
			'separator',
			[
				'label'       => __( '分隔符', 'tooto-elementor' ),
				'type'        => Controls_Manager::TEXT,
				'default'     => '/',
				'placeholder' => '/',
			]
		);

		$this->end_controls_section();

		$this->start_controls_section(
			'section_style',
			[
				'label' => __( '样式', 'tooto-elementor' ),
				'tab'   => Controls_Manager::TAB_STYLE,
			]
		);

		$this->add_group_control(
			Group_Control_Typography::get_type(),
			[
				'name'     => 'typography',
				'label'    => __( '文字排版', 'tooto-elementor' ),
				'selector' => '{{WRAPPER}} .tooto-breadcrumbs',
			]
		);

		$this->add_control(
			'text_color',
			[
				'label'     => __( '文字颜色', 'tooto-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => [
					'{{WRAPPER}} .tooto-breadcrumbs' => 'color: {{VALUE}};',
				],
			]
		);

		$this->add_control(
			'link_color',
			[
				'label'     => __( '链接颜色', 'tooto-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => [
					'{{WRAPPER}} .tooto-breadcrumbs a' => 'color: {{VALUE}};',
				],
			]
		);

		$this->add_control(
			'link_hover_color',
			[
				'label'     => __( '链接悬停颜色', 'tooto-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => [
					'{{WRAPPER}} .tooto-breadcrumbs a:hover' => 'color: {{VALUE}};',
				],
			]
		);

		$this->add_control(
			'separator_color',
			[
				'label'     => __( '分隔符颜色', 'tooto-elementor' ),
				'type'      => Controls_Manager::COLOR,
				'selectors' => [
					'{{WRAPPER}} .tooto-breadcrumbs__separator' => 'color: {{VALUE}};',
				],
			]
		);

		$this->add_responsive_control(
			'gap',
			[
				'label'      => __( '间距', 'tooto-elementor' ),
				'type'       => Controls_Manager::SLIDER,
				'size_units' => [ 'px', 'em', 'rem' ],
				'range'      => [
					'px' => [
						'min' => 0,
						'max' => 32,
					],
				],
				'default'    => [
					'size' => 8,
					'unit' => 'px',
				],
				'selectors'  => [
					'{{WRAPPER}} .tooto-breadcrumbs' => 'gap: {{SIZE}}{{UNIT}};',
				],
			]
		);

		$this->end_controls_section();
	}

	protected function render(): void {
		$settings = $this->get_settings_for_display();

		$items = $this->generate_items( $settings );

		if ( empty( $items ) ) {
			return;
		}

		$separator = isset( $settings['separator'] ) ? $settings['separator'] : '/';
		$count     = count( $items );

		echo '<nav class="tooto-breadcrumbs" aria-label="' . esc_attr__( 'Breadcrumbs', 'tooto-elementor' ) . '">';

		foreach ( $items as $index => $item ) {
			if ( $index > 0 ) {
				echo '<span class="tooto-breadcrumbs__separator" aria-hidden="true">' . esc_html( $separator ) . '</span>';
			}

			$is_last = ( $index === $count - 1 );
			$label   = esc_html( $item['label'] );

			if ( ! empty( $item['url'] ) && ! $is_last ) {
				printf(
					'<a class="tooto-breadcrumbs__link" href="%1$s">%2$s</a>',
					esc_url( $item['url'] ),
					$label
				);
			} else {
				echo '<span class="tooto-breadcrumbs__item" aria-current="' . ( $is_last ? 'page' : 'false' ) . '">' . $label . '</span>';
			}
		}

		echo '</nav>';
	}

	/**
	 * 生成面包屑条目。
	 *
	 * @param array $settings 控件配置。
	 *
	 * @return array<int,array{label:string,url?:string}>
	 */
	private function generate_items( array $settings ): array {
		$items = [];

		$home_label = ! empty( $settings['home_label'] ) ? $settings['home_label'] : __( '首页', 'tooto-elementor' );
		$include    = ( 'yes' === ( $settings['include_current'] ?? 'yes' ) );
		$show_home  = ( 'yes' === ( $settings['show_home'] ?? 'yes' ) );

		if ( $show_home ) {
			$items[] = [
				'label' => $home_label,
				'url'   => home_url( '/' ),
			];
		}

		if ( is_front_page() ) {
			return $items;
		}

		if ( is_home() ) {
			if ( $include ) {
				$items[] = [
					'label' => get_the_title( get_option( 'page_for_posts' ) ) ?: __( '博客', 'tooto-elementor' ),
				];
			}

			return $items;
		}

		if ( is_singular( 'page' ) ) {
			$post_id   = get_the_ID();
			$ancestors = array_reverse( get_post_ancestors( $post_id ) );

			foreach ( $ancestors as $ancestor_id ) {
				$items[] = [
					'label' => get_the_title( $ancestor_id ),
					'url'   => get_permalink( $ancestor_id ),
				];
			}

			if ( $include ) {
				$items[] = [
					'label' => get_the_title( $post_id ),
				];
			}

			return $items;
		}

		if ( is_singular() ) {
			$post_id    = get_the_ID();
			$post_type  = get_post_type_object( get_post_type( $post_id ) );
			$taxonomy   = $post_type && ! empty( $post_type->taxonomies ) ? reset( $post_type->taxonomies ) : 'category';
			$categories = get_the_terms( $post_id, $taxonomy );

			if ( $categories && ! is_wp_error( $categories ) ) {
				$primary = $this->pick_primary_term( $categories );
				$items   = array_merge( $items, $this->build_term_ancestors( $primary, $taxonomy ) );
				$items[] = [
					'label' => $primary->name,
					'url'   => get_term_link( $primary ),
				];
			}

			if ( $include ) {
				$items[] = [
					'label' => get_the_title( $post_id ),
				];
			}

			return $items;
		}

		if ( is_category() || is_tag() || is_tax() ) {
			$term     = get_queried_object();
			$taxonomy = $term->taxonomy ?? 'category';
			$items    = array_merge( $items, $this->build_term_ancestors( $term, $taxonomy ) );

			if ( $include ) {
				$items[] = [
					'label' => $term->name,
				];
			}

			return $items;
		}

		if ( is_post_type_archive() ) {
			$post_type = get_queried_object();
			if ( $include && $post_type && isset( $post_type->labels->name ) ) {
				$items[] = [
					'label' => $post_type->labels->name,
				];
			}

			return $items;
		}

		if ( is_search() ) {
			if ( $include ) {
				$items[] = [
					'label' => sprintf( __( '搜索：%s', 'tooto-elementor' ), get_search_query() ),
				];
			}

			return $items;
		}

		if ( is_404() ) {
			if ( $include ) {
				$items[] = [
					'label' => __( '404 未找到', 'tooto-elementor' ),
				];
			}

			return $items;
		}

		if ( is_author() ) {
			if ( $include ) {
				$items[] = [
					'label' => sprintf( __( '作者：%s', 'tooto-elementor' ), get_the_author_meta( 'display_name' ) ),
				];
			}

			return $items;
		}

		if ( is_date() ) {
			$date_label = get_the_date();
			if ( $include && $date_label ) {
				$items[] = [
					'label' => $date_label,
				];
			}
		}

		return $items;
	}

	/**
	 * 获取主要分类或第一个分类。
	 *
	 * @param array<int,\WP_Term> $terms 分类集合。
	 *
	 * @return \WP_Term
	 */
	private function pick_primary_term( array $terms ): \WP_Term {
		foreach ( $terms as $term ) {
			if ( isset( $term->parent ) && 0 === (int) $term->parent ) {
				return $term;
			}
		}

		return $terms[0];
	}

	/**
	 * 构造分类父级链路。
	 *
	 * @param \WP_Term $term     目标分类。
	 * @param string   $taxonomy 分类法。
	 *
	 * @return array<int,array{label:string,url:string}>
	 */
	private function build_term_ancestors( \WP_Term $term, string $taxonomy ): array {
		$items     = [];
		$ancestors = array_reverse( get_ancestors( $term->term_id, $taxonomy ) );

		foreach ( $ancestors as $ancestor_id ) {
			$ancestor = get_term( $ancestor_id, $taxonomy );
			if ( $ancestor && ! is_wp_error( $ancestor ) ) {
				$items[] = [
					'label' => $ancestor->name,
					'url'   => get_term_link( $ancestor ),
				];
			}
		}

		return $items;
	}
}

