<?php
/**
 * REST — Templates library + kit import.
 *
 * @package AuraBuilder
 */

declare(strict_types=1);

namespace AuraBuilder\REST;

use AuraBuilder\Document\DocumentSanitizer;
use AuraBuilder\Templates\DesignSystemLibrary;
use AuraBuilder\Templates\KitImporter;
use AuraBuilder\Templates\TemplateExporter;
use AuraBuilder\Templates\TemplateFavorites;
use AuraBuilder\Templates\TemplateIdRemapper;
use AuraBuilder\Templates\TemplateRepository;
use AuraBuilder\Templates\TemplateTokens;
use AuraBuilder\Templates\TemplateTypes;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

final class TemplatesController {

	public function register( string $ns ): void {
		register_rest_route(
			$ns,
			'/templates',
			array(
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'list_templates' ),
					'permission_callback' => array( $this, 'can_edit' ),
				),
				array(
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'create_template' ),
					'permission_callback' => array( $this, 'can_edit' ),
				),
			)
		);
		register_rest_route(
			$ns,
			'/templates/export',
			array(
				array(
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'export_template' ),
					'permission_callback' => array( $this, 'can_edit' ),
				),
			)
		);
		// Static paths before parameterized /templates/{id}.
		register_rest_route(
			$ns,
			'/templates/favorites',
			array(
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'list_favorites' ),
					'permission_callback' => array( $this, 'can_edit' ),
				),
			)
		);
		register_rest_route(
			$ns,
			'/templates/(?P<id>[a-zA-Z0-9_\-]+)/insert',
			array(
				array(
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'insert_template' ),
					'permission_callback' => array( $this, 'can_edit' ),
				),
			)
		);
		register_rest_route(
			$ns,
			'/templates/(?P<id>[a-zA-Z0-9_\-]+)/favorite',
			array(
				array(
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'toggle_favorite' ),
					'permission_callback' => array( $this, 'can_edit' ),
				),
			)
		);
		register_rest_route(
			$ns,
			'/templates/(?P<id>[a-zA-Z0-9_\-]+)',
			array(
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'get_template' ),
					'permission_callback' => array( $this, 'can_edit' ),
				),
				array(
					'methods'             => WP_REST_Server::DELETABLE,
					'callback'            => array( $this, 'delete_template' ),
					'permission_callback' => array( $this, 'can_edit' ),
				),
			)
		);
		register_rest_route(
			$ns,
			'/kits/(?P<id>[a-zA-Z0-9_\-]+)/import',
			array(
				array(
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'import_kit' ),
					'permission_callback' => array( $this, 'can_import_kit' ),
				),
			)
		);
		register_rest_route(
			$ns,
			'/design-systems',
			array(
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'list_design_systems' ),
					'permission_callback' => array( $this, 'can_edit' ),
				),
			)
		);
		register_rest_route(
			$ns,
			'/design-systems/(?P<id>[a-zA-Z0-9_\-]+)/apply',
			array(
				array(
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'apply_design_system' ),
					'permission_callback' => array( $this, 'can_import_kit' ),
				),
			)
		);
		register_rest_route(
			$ns,
			'/site-wizard',
			array(
				array(
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'site_wizard' ),
					'permission_callback' => array( $this, 'can_import_kit' ),
				),
			)
		);
	}

	public function can_edit(): bool {
		return \AuraBuilder\Support\Capabilities::can_use_builder();
	}

	public function can_import_kit(): bool {
		return current_user_can( 'edit_pages' ) && ( current_user_can( 'edit_theme_options' ) || current_user_can( 'manage_options' ) );
	}

	public function list_templates( WP_REST_Request $req ): WP_REST_Response {
		$repo  = new TemplateRepository();
		$items = $repo->list(
			array(
				'type'     => (string) $req->get_param( 'type' ),
				'source'   => (string) $req->get_param( 'source' ),
				'category' => (string) $req->get_param( 'category' ),
				'q'        => (string) $req->get_param( 'q' ),
			)
		);
		$favs = TemplateFavorites::list();
		foreach ( $items as &$tpl ) {
			$tpl['favorite'] = in_array( (string) ( $tpl['id'] ?? '' ), $favs, true );
		}
		unset( $tpl );
		// Optional: only favorites.
		if ( $req->get_param( 'favorites' ) === '1' || $req->get_param( 'favorites' ) === 'true' ) {
			$items = array_values(
				array_filter(
					$items,
					static fn( $t ) => ! empty( $t['favorite'] )
				)
			);
		}
		return new WP_REST_Response(
			array(
				'ok'        => true,
				'templates' => $items,
				'count'     => count( $items ),
				'favorites' => $favs,
			)
		);
	}

	/**
	 * @return WP_REST_Response|WP_Error
	 */
	public function get_template( WP_REST_Request $req ) {
		$repo = new TemplateRepository();
		$tpl  = $repo->get( (string) $req['id'] );
		if ( ! $tpl ) {
			return new WP_Error( 'ab_tpl', 'Template não encontrado.', array( 'status' => 404 ) );
		}
		return new WP_REST_Response(
			array(
				'ok'       => true,
				'template' => $tpl,
			)
		);
	}

	/**
	 * @return WP_REST_Response|WP_Error
	 */
	public function create_template( WP_REST_Request $req ) {
		$body = $req->get_json_params();
		if ( ! is_array( $body ) ) {
			return new WP_Error( 'ab_invalid', 'Payload inválido', array( 'status' => 400 ) );
		}
		$repo = new TemplateRepository();
		$tpl  = $repo->save_user( $body );
		if ( is_wp_error( $tpl ) ) {
			return $tpl;
		}
		return new WP_REST_Response(
			array(
				'ok'       => true,
				'template' => $tpl,
			),
			201
		);
	}

	/**
	 * @return WP_REST_Response|WP_Error
	 */
	public function export_template( WP_REST_Request $req ) {
		$body = $req->get_json_params();
		if ( ! is_array( $body ) ) {
			return new WP_Error( 'ab_invalid', 'Payload inválido', array( 'status' => 400 ) );
		}
		$exp = new TemplateExporter();
		$tpl = $exp->export( $body );
		if ( is_wp_error( $tpl ) ) {
			return $tpl;
		}
		return new WP_REST_Response(
			array(
				'ok'       => true,
				'template' => $tpl,
			),
			201
		);
	}

	/**
	 * @return WP_REST_Response|WP_Error
	 */
	public function delete_template( WP_REST_Request $req ) {
		$id  = (string) $req['id'];
		$repo = new TemplateRepository();
		$tpl  = $repo->get( $id );
		if ( ! $tpl ) {
			return new WP_Error( 'ab_tpl', 'Template não encontrado.', array( 'status' => 404 ) );
		}
		if ( ( $tpl['source'] ?? '' ) !== TemplateTypes::SOURCE_USER ) {
			return new WP_Error( 'ab_tpl_core', 'Templates oficiais não podem ser excluídos.', array( 'status' => 403 ) );
		}
		$repo->delete_user( $id );
		return new WP_REST_Response( array( 'ok' => true, 'deleted' => $id ) );
	}

	/**
	 * Prepare template document for insertion (tokens + new IDs).
	 *
	 * @return WP_REST_Response|WP_Error
	 */
	public function insert_template( WP_REST_Request $req ) {
		$repo = new TemplateRepository();
		$tpl  = $repo->get( (string) $req['id'] );
		if ( ! $tpl ) {
			return new WP_Error( 'ab_tpl', 'Template não encontrado.', array( 'status' => 404 ) );
		}
		if ( ( $tpl['type'] ?? '' ) === TemplateTypes::KIT ) {
			return new WP_Error( 'ab_tpl_kit', 'Use /kits/{id}/import para kits.', array( 'status' => 400 ) );
		}
		$doc = is_array( $tpl['document'] ?? null ) ? $tpl['document'] : null;
		if ( ! $doc ) {
			return new WP_Error( 'ab_tpl_doc', 'Template sem documento.', array( 'status' => 400 ) );
		}
		$doc = TemplateTokens::apply( $doc );
		$doc = DocumentSanitizer::sanitize( $doc )->to_array();
		$doc = TemplateIdRemapper::remap( $doc );
		return new WP_REST_Response(
			array(
				'ok'       => true,
				'type'     => $tpl['type'] ?? TemplateTypes::COMPONENT,
				'name'     => $tpl['name'] ?? '',
				'document' => $doc,
			)
		);
	}

	/**
	 * @return WP_REST_Response|WP_Error
	 */
	public function import_kit( WP_REST_Request $req ) {
		$body = $req->get_json_params();
		if ( ! is_array( $body ) ) {
			$body = array();
		}
		$imp = new KitImporter();
		$res = $imp->import( (string) $req['id'], $body );
		if ( is_wp_error( $res ) ) {
			return $res;
		}
		return new WP_REST_Response( $res );
	}

	public function list_design_systems(): WP_REST_Response {
		return new WP_REST_Response(
			array(
				'ok'             => true,
				'designSystems'  => DesignSystemLibrary::list(),
			)
		);
	}

	/**
	 * @return WP_REST_Response|WP_Error
	 */
	public function apply_design_system( WP_REST_Request $req ) {
		$res = DesignSystemLibrary::apply( (string) $req['id'] );
		if ( is_wp_error( $res ) ) {
			return $res;
		}
		return new WP_REST_Response(
			array(
				'ok'      => true,
				'globals' => $res,
				'message' => 'Design system aplicado. Conteúdo das páginas não foi alterado.',
			)
		);
	}

	public function list_favorites(): WP_REST_Response {
		return new WP_REST_Response(
			array(
				'ok'        => true,
				'favorites' => TemplateFavorites::list(),
			)
		);
	}

	/**
	 * @return WP_REST_Response|WP_Error
	 */
	public function toggle_favorite( WP_REST_Request $req ) {
		$id = (string) $req['id'];
		if ( $id === '' ) {
			return new WP_Error( 'ab_fav', 'ID inválido', array( 'status' => 400 ) );
		}
		$list = TemplateFavorites::toggle( $id );
		return new WP_REST_Response(
			array(
				'ok'        => true,
				'id'        => $id,
				'favorite'  => in_array( $id, $list, true ),
				'favorites' => $list,
			)
		);
	}

	/**
	 * Site wizard: pick kit by category/style + optional site tokens + import.
	 *
	 * @return WP_REST_Response|WP_Error
	 */
	public function site_wizard( WP_REST_Request $req ) {
		$body = $req->get_json_params();
		if ( ! is_array( $body ) ) {
			return new WP_Error( 'ab_invalid', 'Payload inválido', array( 'status' => 400 ) );
		}
		$kit_id = sanitize_key( (string) ( $body['kitId'] ?? $body['kit_id'] ?? '' ) );
		if ( $kit_id === '' ) {
			// Map category → default kit.
			$cat = sanitize_key( (string) ( $body['category'] ?? 'business' ) );
			$map = array(
				'business'   => 'business-pro',
				'education'  => 'school-classic',
				'blog'       => 'blog-clean',
				'news'       => 'news-portal',
				'landing'    => 'landing-boost',
				'school'     => 'school-classic',
				'restaurant' => 'restaurant-bistro',
				'portfolio'  => 'portfolio-studio',
				'realestate' => 'real-estate',
			);
			$kit_id = $map[ $cat ] ?? 'business-pro';
		}

		// Optional: apply design system first / override kit DS.
		$ds_id = sanitize_key( (string) ( $body['designSystem'] ?? $body['design_system'] ?? '' ) );
		if ( $ds_id !== '' ) {
			DesignSystemLibrary::apply( $ds_id );
		}

		// Optional bloginfo overrides (name only — requires manage_options).
		$site_name = sanitize_text_field( (string) ( $body['siteName'] ?? $body['site_name'] ?? '' ) );
		if ( $site_name !== '' && current_user_can( 'manage_options' ) ) {
			update_option( 'blogname', $site_name );
		}

		$opts = array(
			'globals'  => ! isset( $body['globals'] ) || ! empty( $body['globals'] ),
			'header'   => ! isset( $body['header'] ) || ! empty( $body['header'] ),
			'footer'   => ! isset( $body['footer'] ) || ! empty( $body['footer'] ),
			'pages'    => ! isset( $body['pages'] ) || ! empty( $body['pages'] ),
			'single'   => ! isset( $body['single'] ) || ! empty( $body['single'] ),
			'set_home' => ! empty( $body['set_home'] ) || ! empty( $body['setHome'] ),
		);
		// If DS already applied above, skip kit globals unless requested.
		if ( $ds_id !== '' && empty( $body['force_kit_globals'] ) ) {
			$opts['globals'] = false;
		}

		$imp = new KitImporter();
		$res = $imp->import( $kit_id, $opts );
		if ( is_wp_error( $res ) ) {
			return $res;
		}
		$res['wizard'] = array(
			'kitId'         => $kit_id,
			'designSystem'  => $ds_id,
			'siteName'      => $site_name,
		);
		$res['message'] = 'Site criado a partir do assistente. Edite páginas e header no Aura Builder.';
		return new WP_REST_Response( $res );
	}
}
