<?php
/**
 * EntryFoundry output shortcodes.
 *
 * @package EntryFoundry
 */

namespace EntryFoundry\Core\Controllers;

// Constructor and shortcode method types define this focused controller contract.
// phpcs:disable Squiz.Commenting, Generic.Commenting.DocComment

use EntryFoundry\Core\Models\Template\TemplateRepository;
use EntryFoundry\Core\Services\Generation\DocumentGenerationService;
use EntryFoundry\Core\Services\Security\SignedUrlService;
use RuntimeException;

/** Registers HTML, PDF-view, and download shortcodes. */
final class ShortcodeController {
	private const DOCUMENT_STYLE_HANDLE = 'entryfoundry-document';
	/** @var DocumentGenerationService */ private $generation;
	/** @var SignedUrlService */ private $signer;
	/** @var TemplateRepository */ private $templates;

	public function __construct( DocumentGenerationService $generation, SignedUrlService $signer, TemplateRepository $templates ) {
		$this->generation = $generation;
		$this->signer     = $signer;
		$this->templates  = $templates;
	}

	public function register(): void {
		add_action( 'wp_enqueue_scripts', array( $this, 'register_document_style' ) );
		add_shortcode( 'entryfoundry_template', array( $this, 'render_template' ) );
		add_shortcode( 'entryfoundry', array( $this, 'render_html' ) );
		add_shortcode( 'entryfoundry_download', array( $this, 'render_download' ) );
		add_shortcode( 'entryfoundry_view', array( $this, 'render_view' ) );
	}

	public function register_document_style(): void {
		wp_register_style(
			self::DOCUMENT_STYLE_HANDLE,
			plugins_url( 'build/entryfoundry-public.css', ENTRYFOUNDRY_PLUGIN_FILE ),
			array(),
			ENTRYFOUNDRY_VERSION
		);
		wp_enqueue_style( self::DOCUMENT_STYLE_HANDLE );
	}

	/** @param array<string,mixed> $attributes Shortcode attributes. */
	public function render_template( $attributes ): string {
		$attributes = is_array( $attributes ) ? $attributes : array();
		$output     = isset( $attributes['output'] ) ? sanitize_key( $attributes['output'] ) : 'download';

		if ( 'html' === $output ) {
			return $this->render_html( $attributes );
		}
		if ( 'view' === $output ) {
			return $this->render_view( $attributes );
		}

		return $this->render_download( $attributes );
	}

	/** @param array<string,mixed> $attributes Shortcode attributes. */
	public function render_html( $attributes ): string {
		$ids = $this->resolve_ids( $attributes );
		if ( ! $ids ) {
			return ''; }
		try {
			$payload = $this->generation->render_html_payload( $ids['template_id'], $ids['entry_id'] );
			if ( ! wp_style_is( self::DOCUMENT_STYLE_HANDLE, 'registered' ) ) {
				$this->register_document_style();
			}
			wp_enqueue_style( self::DOCUMENT_STYLE_HANDLE );
			wp_add_inline_style( self::DOCUMENT_STYLE_HANDLE, $payload['styles'] );
			return $payload['markup'];
		} catch ( RuntimeException $exception ) {
			return ''; }
	}

	/** @param array<string,mixed> $attributes Shortcode attributes. */
	public function render_download( $attributes ): string {
		$ids = $this->resolve_ids( $attributes );
		if ( ! $ids ) {
			return ''; }
		$label = isset( $attributes['label'] ) ? sanitize_text_field( (string) $attributes['label'] ) : '';
		$label = '' !== $label ? $label : __( 'Download PDF', 'entryfoundry-pdf-builder-for-formidable-forms' );
		$url   = $this->document_url( $ids['template_id'], $ids['entry_id'], 'download' );
		return '<a class="entryfoundry-download" href="' . esc_url( $url ) . '">' . esc_html( $label ) . '</a>';
	}

	/** @param array<string,mixed> $attributes Shortcode attributes. */
	public function render_view( $attributes ): string {
		$ids = $this->resolve_ids( $attributes );
		if ( ! $ids ) {
			return ''; }
		$url = $this->document_url( $ids['template_id'], $ids['entry_id'], 'view' );
		return '<iframe class="entryfoundry-view" src="' . esc_url( $url ) . '" title="' . esc_attr__( 'EntryFoundry PDF', 'entryfoundry-pdf-builder-for-formidable-forms' ) . '" loading="lazy"></iframe>';
	}

	private function document_url( int $template_id, int $entry_id, string $disposition ): string {
		$path = sprintf( '/entryfoundry/%s/%d/%d/', $disposition, $template_id, $entry_id );
		return $this->signer->create_pretty( home_url( $path ), $template_id, $entry_id, 'pdf', $disposition );
	}

	/** @param array<string,mixed> $attributes Shortcode attributes. @return array{template_id:int,entry_id:int}|null */
	private function resolve_ids( $attributes ): ?array {
		$attributes  = shortcode_atts(
			array(
				'id'    => 0,
				'entry' => 0,
			),
			is_array( $attributes ) ? $attributes : array(),
			'entryfoundry'
		);
		$template_id = absint( $attributes['id'] );
		$stored      = $template_id ? $this->templates->get( $template_id ) : null;
		if ( ! $stored ) {
			return null; }
		$entry_id = is_numeric( $attributes['entry'] ) ? absint( $attributes['entry'] ) : 0;
		if ( $entry_id < 1 ) {
			$entry_id = (int) ( $stored['template']['preview_entry_id'] ?? 0 ); }
		return $entry_id > 0 ? compact( 'template_id', 'entry_id' ) : null;
	}
}
