<?php
/**
 * CPT Builder PHP code export.
 *
 * @package CptBuilder
 * @since 1.2.0
 */

namespace CptBuilder;

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

/**
 * Generates register_post_type() PHP snippets from stored definitions.
 */
final class PhpExport {

	private Storage $storage;

	private Registrar $registrar;

	public function __construct( Storage $storage, Registrar $registrar ) {
		$this->storage   = $storage;
		$this->registrar = $registrar;
	}

	/**
	 * Export one or all CPTs as PHP source.
	 *
	 * @param string|null $key Specific key or null for all.
	 */
	public function exportPhp( ?string $key = null ): string {
		$definitions = $this->storage->all();
		if ( $key !== null ) {
			$definitions = isset( $definitions[ $key ] ) ? [ $key => $definitions[ $key ] ] : [];
		}

		$blocks = [
			'<?php',
			'/**',
			' * Custom post types exported from WP PowerSuite CPT Builder.',
			' * Generated: ' . gmdate( 'Y-m-d H:i:s' ) . ' UTC',
			' *',
			' * Paste into a theme functions.php or a custom plugin.',
			' */',
			'',
			"add_action( 'init', function () {",
		];

		foreach ( $definitions as $pt_key => $definition ) {
			if ( ! is_array( $definition ) || empty( $definition['enabled'] ) ) {
				continue;
			}
			$blocks[] = $this->renderPostType( (string) $pt_key, $definition );
			$blocks[] = '';
		}

		$blocks[] = '}, 9 );';
		$blocks[] = '';

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

	/**
	 * @param string               $key        Post type key.
	 * @param array<string, mixed> $definition Stored definition.
	 */
	private function renderPostType( string $key, array $definition ): string {
		$args = $this->registrar->buildArgs( $key, $definition );
		$taxonomies = isset( $definition['taxonomies'] ) && is_array( $definition['taxonomies'] )
			? array_values( array_filter( array_map( 'strval', $definition['taxonomies'] ) ) )
			: [];

		$lines   = [];
		$lines[] = "\t// " . (string) ( $definition['title'] ?? $key );
		$lines[] = "\tregister_post_type( '" . $key . "', " . $this->exportVar( $args, 1 ) . ' );';

		foreach ( $taxonomies as $taxonomy ) {
			$lines[] = "\tif ( taxonomy_exists( '" . $taxonomy . "' ) ) {";
			$lines[] = "\t\tregister_taxonomy_for_object_type( '" . $taxonomy . "', '" . $key . "' );";
			$lines[] = "\t}";
		}

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

	/**
	 * @param mixed $value  PHP value.
	 * @param int   $indent Indent depth.
	 */
	private function exportVar( mixed $value, int $indent = 0 ): string {
		$pad = str_repeat( "\t", $indent );

		if ( is_array( $value ) ) {
			if ( $value === [] ) {
				return '[]';
			}
			$is_list = array_is_list( $value );
			$parts   = [];
			foreach ( $value as $k => $v ) {
				$key_part = $is_list ? '' : $this->exportVar( $k, 0 ) . ' => ';
				$parts[]  = $pad . "\t" . $key_part . $this->exportVar( $v, $indent + 1 );
			}

			return "[\n" . implode( ",\n", $parts ) . ",\n" . $pad . ']';
		}

		if ( is_bool( $value ) ) {
			return $value ? 'true' : 'false';
		}

		if ( is_int( $value ) || is_float( $value ) ) {
			return (string) $value;
		}

		if ( $value === null ) {
			return 'null';
		}

		return var_export( (string) $value, true );
	}
}
