<?php

namespace Limb_Chatbot\Includes\Integrations\Slack\Services;

use Exception;
use Limb_Chatbot\Includes\Data_Objects\Parameter;
use Limb_Chatbot\Includes\Services\Actions\Action_Callback_Execution_Context;
use Limb_Chatbot\Includes\Services\User_Manager;

class Slack_Bot_Message_Builder {
	public function build( string $content, string $channel, Action_Callback_Execution_Context $context ) {
		$blocks = [];

		// Header block
		$blocks[] = [
			'type' => 'header',
			'text' => [
				'type'  => 'plain_text',
				'text'  => '🤖 New Action Submission',
				'emoji' => true,
			],
		];

		// Divider
		$blocks[] = [
			'type' => 'divider',
		];

		// Main content block
		$blocks[] = [
			'type' => 'section',
			'text' => [
				'type' => 'mrkdwn',
				'text' => $content,
			],
		];

		// User information block
		$user_info = $this->get_user_info();
		if ( ! empty( $user_info ) ) {
			$blocks[] = [
				'type'   => 'section',
				'fields' => $this->format_user_info_fields( $user_info ),
			];
		}

		// Parameters block (if any submitted)
		$parameters = $context->get_parameters();
		if ( ! empty( $parameters ) ) {
			$blocks[] = [
				'type' => 'divider',
			];

			$blocks[] = [
				'type' => 'section',
				'text' => [
					'type' => 'mrkdwn',
					'text' => '*📋 Submitted Parameters:*',
				],
			];

			$blocks[] = [
				'type'   => 'section',
				'fields' => $this->format_parameters_fields( $parameters, $context->get_variables() ),
			];
		}

		// Footer with timestamp
		$blocks[] = [
			'type'     => 'context',
			'elements' => [
				[
					'type' => 'mrkdwn',
					'text' => sprintf(
						'Sent via Limb Chatbot • %s',
						current_time( 'F j, Y g:i a' )
					),
				],
			],
		];

		return [
			'channel'  => $channel,
			'text'     => $content, // Fallback text for notifications
			'blocks'   => $blocks,
		];
	}

	/**
	 * Get current user information.
	 *
	 * @return array User information.
	 * @throws Exception
	 * @since 1.0.0
	 */
	private function get_user_info(): array {
		$user_manager = User_Manager::instance();
		$current_user = $user_manager->get_current_user();

		if ( ! $current_user ) {
			return [];
		}

		$user_info = [
			'name'  => $current_user->name(),
			'email' => $current_user->email(),
			'ip'    => $current_user->get_ip(),
		];

		// Add role if available

		if ( $current_user->is_wp_user() ) {
			$user = get_userdata( $current_user->get_wp_user_id() );

			if ( ! $user || empty( $user->roles ) ) {
				$role = '';
			} else {
				$primaryRole = $user->roles[0];

				global $wp_roles;

				$role = $wp_roles->roles[ $primaryRole ]['name'] ?? '';
			}
		} else {
			$role = __( 'Guest', 'limb-chatbot' );
		}
		$user_info['role'] = $role;


		return $user_info;
	}

	/**
	 * Format user information as Slack fields.
	 *
	 * @param  array  $user_info  User information.
	 *
	 * @return array Slack fields.
	 * @since 1.0.0
	 */
	private function format_user_info_fields( array $user_info ): array {
		$fields = [];

		if ( ! empty( $user_info['name'] ) ) {
			$fields[] = [
				'type' => 'mrkdwn',
				'text' => '*👤 User:*' . " " . $user_info['name'],
			];
		}

		if ( ! empty( $user_info['email'] ) ) {
			$fields[] = [
				'type' => 'mrkdwn',
				'text' => '*📧 Email:*' . " " . $user_info['email'],
			];
		}

		if ( ! empty( $user_info['role'] ) ) {
			$fields[] = [
				'type' => 'mrkdwn',
				'text' => '*🎭 Role:*' . " " . $user_info['role'],
			];
		}

		if ( ! empty( $user_info['ip'] ) ) {
			$fields[] = [
				'type' => 'mrkdwn',
				'text' => '*📍 User IP:*' . " " . $user_info['ip'],
			];
		}

		return $fields;
	}

	/**
	 * Format parameters as Slack fields.
	 *
	 * @param  array  $parameters  Parameters array.
	 *
	 * @return array Slack fields.
	 * @since 1.0.0
	 */
	private function format_parameters_fields( array $parameters, array $variables ): array {
		$fields = [];

		foreach ( $parameters as $key => $parameter ) {
			// Skip empty values
			if ( empty( $variables[ $key ] ) || ! $parameter instanceof Parameter ) {
				continue;
			}
			$value = $variables[ $key ];

			// Convert arrays and objects to readable format
			if ( is_array( $value ) || is_object( $value ) ) {
				$value = wp_json_encode( $value, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES );
			}

			// Convert value to string
			$value = (string) $value;

			// Truncate very long values
			if ( strlen( $value ) > 500 ) {
				$value = substr( $value, 0, 497 ) . '...';
			}

			// Escape special Slack markdown characters to prevent formatting issues
			// But keep intentional formatting
			$safe_key   = $this->escape_slack_text( $parameter->get_label() );
			$safe_value = $this->escape_slack_text( $value );

			$fields[] = [
				'type' => 'mrkdwn',
				'text' => '*' . $safe_key . ':*' . " " . $safe_value,
			];
		}

		return $fields;
	}

	/**
	 * Escape text for Slack to prevent unwanted markdown rendering.
	 *
	 * Only escapes special Slack characters that could break formatting.
	 *
	 * @param  string  $text  Text to escape.
	 *
	 * @return string Escaped text.
	 * @since 1.0.0
	 */
	private function escape_slack_text( string $text ): string {
		// Slack uses these special characters: & < >
		// We need to escape them to prevent issues
		$text = str_replace( '&', '&amp;', $text );
		$text = str_replace( '<', '&lt;', $text );
		$text = str_replace( '>', '&gt;', $text );

		return $text;
	}
}
