<?php
/**
 * Message generator class.
 *
 * @package Shrikant\SocialPostBuilder
 */

namespace Shrikant\SocialPostBuilder;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Class Shrikant_Generator
 * Generates formatted social media messages based on post selection, templates, and options.
 */
class Shrikant_Generator {

	/**
	 * Generate social media message from posts, template, and options.
	 *
	 * @param array  $post_ids         Array of WordPress post IDs.
	 * @param string $template_content The raw template string with placeholders.
	 * @param array  $options          Formatting options.
	 * @return string The generated message text.
	 */
	public static function generate( array $post_ids, string $template_content, array $options = [] ): string {
		$settings_instance = Shrikant_Settings::get_instance();
		$settings = $settings_instance->get_settings();

		// Default options.
		$options = wp_parse_args( $options, [
			'number_posts'      => true,
			'show_emojis'       => true,
			'truncate_titles'   => false,
			'title_max_length'  => 75,
			'uppercase_titles'  => false,
			'add_footer'        => true,
			'add_website'       => true,
			'add_hashtags'      => true,
			'remove_duplicates' => true,
			'use_short_links'   => false,
		] );

		// 1. Process posts placeholder.
		$posts_text = '';
		$seen_ids   = [];
		$counter    = 1;

		foreach ( $post_ids as $post_id ) {
			$post_id = absint( $post_id );
			if ( ! $post_id ) {
				continue;
			}

			// Deduplicate if selected.
			if ( $options['remove_duplicates'] && in_array( $post_id, $seen_ids, true ) ) {
				continue;
			}
			$seen_ids[] = $post_id;

			$post = get_post( $post_id );
			if ( ! $post || 'publish' !== $post->post_status ) {
				continue;
			}

			$title = get_the_title( $post );

			// 1a. Capitalize / UPPERCASE title if enabled.
			if ( ! empty( $options['uppercase_titles'] ) ) {
				$title = mb_strtoupper( $title, 'UTF-8' );
			}

			// 1b. Truncate long titles with ellipsis (...) if enabled.
			if ( ! empty( $options['truncate_titles'] ) ) {
				$max_length = ! empty( $options['title_max_length'] ) ? absint( $options['title_max_length'] ) : 75;
				if ( $max_length > 0 && mb_strlen( $title, 'UTF-8' ) > $max_length ) {
					$title = mb_substr( $title, 0, max( 1, $max_length - 3 ), 'UTF-8' ) . '...';
				}
			}

			$url = get_permalink( $post );

			if ( ! empty( $options['use_short_links'] ) ) {
				$url = self::get_short_link( $post_id, $url );
			}

			$post_line = '';
			if ( $options['number_posts'] ) {
				$post_line .= $counter . '. ';
			}

			if ( $options['show_emojis'] && ! empty( $settings['default_emoji'] ) ) {
				$post_line .= $settings['default_emoji'] . ' ';
			}

			$post_line .= $title . "\n" . $url;
			$posts_text .= $post_line . "\n\n";

			$counter++;
		}

		$posts_text = trim( $posts_text );

		// 2. Prepare place holders values.
		$website_val  = $options['add_website'] ? $settings['website_url'] : '';
		$footer_val   = $options['add_footer'] ? $settings['footer_text'] : '';
		$hashtags_val = $options['add_hashtags'] ? $settings['default_hashtags'] : '';
		$date_val     = date_i18n( get_option( 'date_format' ) );
		$time_val     = date_i18n( get_option( 'time_format' ) );

		// Placeholders mapping.
		$placeholders = [
			'{{posts}}'    => $posts_text,
			'{{website}}'  => $website_val,
			'{{footer}}'   => $footer_val,
			'{{hashtags}}' => $hashtags_val,
			'{{date}}'     => $date_val,
			'{{time}}'     => $time_val,
		];

		// Apply replacements.
		$output = $template_content;
		foreach ( $placeholders as $placeholder => $value ) {
			$output = str_replace( $placeholder, $value, $output );
		}

		// Clean up empty lines where blocks were excluded (e.g. double newlines from removed footer/hashtags).
		$output = preg_replace( "/\n{3,}/", "\n\n", $output );

		return trim( $output );
	}

	/**
	 * Retrieve or automatically generate a short link using Shrikant Short Links plugin.
	 *
	 * @param int    $post_id    Post ID.
	 * @param string $default_url Fallback target URL.
	 * @return string Short URL or default URL on fallback.
	 */
	private static function get_short_link( int $post_id, string $default_url ): string {
		if ( ! class_exists( '\Shrikant_Short_Links_Shortlink' ) ) {
			return $default_url;
		}

		try {
			$post = get_post( $post_id );
			if ( ! $post ) {
				return $default_url;
			}

			// Check if a short link already exists for this post.
			$shortlink = \Shrikant_Short_Links_Shortlink::get_by_post_id( $post_id );
			if ( $shortlink && ! empty( $shortlink->slug ) ) {
				// If existing slug was created using full post_name (which is long or equal to post_name), update to a short random slug.
				if ( $shortlink->slug === $post->post_name && strlen( $post->post_name ) > 7 ) {
					$new_slug = self::generate_random_slug( 5 );
					if ( $new_slug ) {
						\Shrikant_Short_Links_Shortlink::update( $shortlink->id, [ 'slug' => $new_slug ] );
						$shortlink->slug = $new_slug;
					}
				}

				if ( function_exists( '\shrikant_short_links_get_short_url' ) ) {
					return \shrikant_short_links_get_short_url( $shortlink->slug );
				}
				return esc_url( home_url( '/' . $shortlink->slug ) );
			}

			// Generate a unique 5-character random short slug for this post.
			$slug = self::generate_random_slug( 5 );

			$created_id = \Shrikant_Short_Links_Shortlink::create( [
				'post_id'    => $post_id,
				'slug'       => $slug,
				'target_url' => $default_url,
			] );

			if ( $created_id ) {
				if ( function_exists( '\shrikant_short_links_get_short_url' ) ) {
					return \shrikant_short_links_get_short_url( $slug );
				}
				return esc_url( home_url( '/' . $slug ) );
			}
		} catch ( \Throwable $e ) {
			// Fallback on any unexpected database or class error.
			return $default_url;
		}

		return $default_url;
	}

	/**
	 * Generate a unique 5-character random alphanumeric slug.
	 *
	 * @param int $length Slug length.
	 * @return string Unique slug.
	 */
	private static function generate_random_slug( int $length = 5 ): string {
		$chars    = 'abcdefghijklmnopqrstuvwxyz0123456789';
		$max      = strlen( $chars ) - 1;
		$attempts = 0;

		while ( $attempts < 20 ) {
			$slug = '';
			for ( $i = 0; $i < $length; $i++ ) {
				$slug .= $chars[ wp_rand( 0, $max ) ];
			}

			if ( class_exists( '\Shrikant_Short_Links_Shortlink' ) && \Shrikant_Short_Links_Shortlink::is_slug_available( $slug ) ) {
				return $slug;
			}
			$attempts++;
		}

		return wp_generate_password( $length, false, false );
	}
}
