<?php

declare( strict_types=1 );

namespace Limb_Chatbot\Includes\Services\System_Message\Chunks;

/**
 * Abstract base class for system message chunks.
 *
 * Each chunk represents a logical section of a system message that can be
 * independently generated and merged into a complete system message.
 *
 * This architecture allows:
 * - Modular composition of system messages
 * - Easy integration of domain-specific guidance (e.g., WooCommerce)
 * - Conditional inclusion/exclusion of chunks
 * - Consistent formatting and structure
 *
 * @since 1.1.1
 */
abstract class System_Message_Chunk {

	/**
	 * Get the chunk's title/heading.
	 *
	 * @return string The section title.
	 */
	abstract public function get_title(): string;

	/**
	 * Get the chunk's content as an array of lines.
	 *
	 * Each line will be joined with newlines when building the final message.
	 * Return an associative array for structured data, or numeric for bullets.
	 *
	 * @return array Lines or structured content.
	 */
	abstract public function get_content(): array;

	/**
	 * Get the chunk's priority/order in the final message.
	 *
	 * Lower numbers render first. Used by the assembler to order chunks.
	 *
	 * @return int Priority level (default 100).
	 */
	public function get_priority(): int {
		return 100;
	}

	/**
	 * Whether this chunk should be included in the final message.
	 *
	 * Can be used to conditionally include chunks based on state.
	 *
	 * @return bool True if the chunk should be included.
	 */
	public function should_include(): bool {
		return true;
	}

	/**
	 * Render this chunk as a formatted section string.
	 *
	 * Can be overridden for custom formatting.
	 *
	 * @return string Formatted section with title and content.
	 */
	public function render(): string {
		$content = $this->render_content();
		if ( empty( $content ) ) {
			return '';
		}

		return ( $this->get_title() ? ("###{$this->get_title()}\n") : '' ) . $content;
	}

	/**
	 * Render the chunk's content into a string.
	 *
	 * Handles arrays and strings, converting them to readable format.
	 *
	 * @return string Rendered content.
	 */
	protected function render_content(): string {
		$content = $this->get_content();

		if ( empty( $content ) ) {
			return '';
		}

		if ( is_string( $content ) ) {
			return trim( $content );
		}

		if ( ! is_array( $content ) ) {
			return '';
		}

		// Check if associative array
		$is_assoc = ! empty( $content ) && array_keys( $content ) !== range( 0, count( $content ) - 1 );

		if ( $is_assoc ) {
			// Render as key-value pairs
			$lines = [];
			foreach ( $content as $key => $value ) {
				$label = ucfirst( str_replace( '_', ' ', $key ) );
				if ( is_array( $value ) ) {
					$lines[] = "{$label}:";
					foreach ( $value as $item ) {
						$lines[] = "{$item}";
					}
				} else {
					$lines[] = "{$label}: {$value}";
				}
			}
			return implode( "\n", $lines );
		}

		// Render as bullet list
		$lines = [];
		foreach ( $content as $item ) {
			if ( is_array( $item ) ) {
				// Nested structure
				foreach ( $item as $key => $value ) {
					$lines[] = "{$key}: {$value}";
				}
			} else {
				$lines[] = "{$item}";
			}
		}

		return implode( "\n", $lines );
	}
}
