<?php
/**
 * Form logic: step/field configuration, rendering helpers and AJAX submission.
 *
 * Field-group engine generalized from the "[portfolio_quote_form]" prototype
 * (6-step brief: Type → Goals → Content → Features → Budget → Contact).
 *
 * @package Briefify
 */

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

/**
 * Class Briefify_Form
 */
class Briefify_Form {

	/**
	 * @var Briefify_Email
	 */
	private $email;

	/**
	 * Whether front assets have already been localized on this request.
	 *
	 * @var bool
	 */
	private static $localized = false;

	/**
	 * Constructor.
	 *
	 * @param Briefify_Email $email Email handler instance.
	 */
	public function __construct( Briefify_Email $email ) {
		$this->email = $email;

		add_action( 'wp_enqueue_scripts', array( $this, 'register_assets' ) );
		add_action( 'wp_ajax_briefify_submit', array( $this, 'handle_submit' ) );
		add_action( 'wp_ajax_nopriv_briefify_submit', array( $this, 'handle_submit' ) );
	}

	/**
	 * Register (but do not enqueue) front-end assets.
	 *
	 * Hooked to `wp_enqueue_scripts` for the normal case, but also called
	 * defensively from render_form() itself (registration is idempotent —
	 * wp_register_*() is a safe no-op if the handle already exists). This
	 * matters because on some block/FSE themes the [nr_brief] shortcode's
	 * content can be parsed and rendered *before* `wp_enqueue_scripts`
	 * fires (block themes resolve which block assets to enqueue by parsing
	 * post content early), unlike classic PHP-template themes where the
	 * loop always runs after wp_head(). If render_form() ran first, calling
	 * wp_enqueue_script()/wp_localize_script() on a not-yet-registered
	 * handle fails silently — window.briefifyData ends up undefined, the
	 * front-end JS's fetch() falls back to an empty ajaxUrl, and the
	 * submission silently posts to the current page instead of
	 * admin-ajax.php. Calling this here as well closes that gap regardless
	 * of hook order or theme type.
	 */
	public function register_assets() {
		if ( ! wp_style_is( 'briefify-front', 'registered' ) ) {
			wp_register_style(
				'briefify-front',
				BRIEFIFY_PLUGIN_URL . 'assets/css/briefify-front.css',
				array(),
				BRIEFIFY_VERSION
			);
		}

		if ( ! wp_script_is( 'briefify-front', 'registered' ) ) {
			wp_register_script(
				'briefify-front',
				BRIEFIFY_PLUGIN_URL . 'assets/js/briefify-front.js',
				array(),
				BRIEFIFY_VERSION,
				true
			);
		}
	}

	/**
	 * List of steps in a fixed order. The free version caps configurable
	 * question steps at 5 (type/goals/content/features/budget) plus the
	 * final fixed contact + recap step.
	 *
	 * @return array<string,string> slug => label
	 */
	public static function get_step_labels() {
		return array(
			'type'     => __( 'Project', 'nr-brief-builder' ),
			'goals'    => __( 'Goals', 'nr-brief-builder' ),
			'content'  => __( 'Content', 'nr-brief-builder' ),
			'features' => __( 'Features', 'nr-brief-builder' ),
			'budget'   => __( 'Budget', 'nr-brief-builder' ),
			'contact'  => __( 'Contact', 'nr-brief-builder' ),
		);
	}

	/**
	 * Get a template configuration by key, falling back to "web".
	 *
	 * @param string $key Template key.
	 * @return array
	 */
	public static function get_template( $key ) {
		$templates = self::get_templates();

		return isset( $templates[ $key ] ) ? $templates[ $key ] : $templates['web'];
	}

	/**
	 * Preset templates: Website / Graphic design / Coaching.
	 *
	 * Each step holds a title, an optional note, and an ordered list of
	 * field groups rendered generically by render_field().
	 *
	 * @return array
	 */
	public static function get_templates() {
		static $templates = null;

		if ( null !== $templates ) {
			return $templates;
		}

		$templates = array(
			'web'        => array(
				'label' => __( 'Website', 'nr-brief-builder' ),
				'steps' => array(
					'type'     => array(
						'title'  => __( 'What type of project do you have?', 'nr-brief-builder' ),
						'fields' => array(
							self::field_type_grid(
								'project_type',
								array(
									array( 'value' => __( 'Showcase website', 'nr-brief-builder' ), 'label' => __( 'Showcase site', 'nr-brief-builder' ), 'sub' => __( 'Professional, polished presence', 'nr-brief-builder' ), 'icon' => 'globe' ),
									array( 'value' => __( 'Website redesign', 'nr-brief-builder' ), 'label' => __( 'Redesign', 'nr-brief-builder' ), 'sub' => __( 'Modernize an existing site', 'nr-brief-builder' ), 'icon' => 'refresh' ),
									array( 'value' => __( 'E-commerce site', 'nr-brief-builder' ), 'label' => __( 'E-commerce', 'nr-brief-builder' ), 'sub' => __( 'Online store', 'nr-brief-builder' ), 'icon' => 'cart' ),
									array( 'value' => __( 'SEO / performance optimization', 'nr-brief-builder' ), 'label' => __( 'SEO & Performance', 'nr-brief-builder' ), 'sub' => __( 'Audit and optimization', 'nr-brief-builder' ), 'icon' => 'search' ),
									array( 'value' => __( 'Maintenance', 'nr-brief-builder' ), 'label' => __( 'Maintenance', 'nr-brief-builder' ), 'sub' => __( 'Ongoing support and updates', 'nr-brief-builder' ), 'icon' => 'wrench' ),
									array( 'value' => __( 'Other', 'nr-brief-builder' ), 'label' => __( 'Other', 'nr-brief-builder' ), 'sub' => __( "Let's discuss it together", 'nr-brief-builder' ), 'icon' => 'help' ),
								)
							),
						),
					),
					'goals'    => array(
						'title'  => __( 'Goals & audience', 'nr-brief-builder' ),
						'fields' => array(
							self::field_chips( 'objective', __( 'What is the main goal of this site?', 'nr-brief-builder' ), false, array( __( 'Generate leads', 'nr-brief-builder' ), __( 'Sell online', 'nr-brief-builder' ), __( 'Showcase my services', 'nr-brief-builder' ), __( 'Recruit', 'nr-brief-builder' ), __( 'Build credibility', 'nr-brief-builder' ), __( 'Other', 'nr-brief-builder' ) ) ),
							self::field_chips( 'visitor_action', __( 'What action do you want visitors to take?', 'nr-brief-builder' ), true, array( __( 'Fill out a form', 'nr-brief-builder' ), __( 'Call directly', 'nr-brief-builder' ), __( 'Buy a product', 'nr-brief-builder' ), __( 'Book an appointment online', 'nr-brief-builder' ), __( 'Sign up for a newsletter', 'nr-brief-builder' ) ) ),
							self::field_chips( 'brand_kit', __( 'Do you already have a brand kit or logo?', 'nr-brief-builder' ), false, array( __( 'Yes, everything is ready', 'nr-brief-builder' ), __( 'Partially (logo only)', 'nr-brief-builder' ), __( 'No, I need help', 'nr-brief-builder' ) ) ),
						),
					),
					'content'  => array(
						'title'  => __( 'Content & structure', 'nr-brief-builder' ),
						'fields' => array(
							self::field_chips( 'volume', __( 'How many pages do you think you’ll need?', 'nr-brief-builder' ), false, array( __( '1 to 3 pages', 'nr-brief-builder' ), __( '4 to 7 pages', 'nr-brief-builder' ), __( '8 to 15 pages', 'nr-brief-builder' ), __( '15+ pages', 'nr-brief-builder' ), __( "I don't know yet", 'nr-brief-builder' ) ) ),
							self::field_chips( 'content_ready', __( 'Do you already have your copy and images?', 'nr-brief-builder' ), false, array( __( 'Yes, everything is ready', 'nr-brief-builder' ), __( 'Copy yes, images no', 'nr-brief-builder' ), __( 'Partially', 'nr-brief-builder' ), __( 'No, I need help', 'nr-brief-builder' ) ) ),
							self::field_chips( 'languages', __( 'Language needs?', 'nr-brief-builder' ), false, array( __( 'English only', 'nr-brief-builder' ), __( 'Bilingual', 'nr-brief-builder' ), __( 'More than 2 languages', 'nr-brief-builder' ) ) ),
							self::field_textarea( 'references', __( 'Do you have any visual references?', 'nr-brief-builder' ), true, __( 'URLs of sites you like, desired vibe, keywords…', 'nr-brief-builder' ) ),
						),
					),
					'features' => array(
						'title'  => __( 'Features & technical', 'nr-brief-builder' ),
						'fields' => array(
							self::field_chips( 'features', __( 'Which features would you like?', 'nr-brief-builder' ), true, array( __( 'Contact form', 'nr-brief-builder' ), __( 'Online booking', 'nr-brief-builder' ), __( 'WooCommerce store', 'nr-brief-builder' ), __( 'Member area', 'nr-brief-builder' ), __( 'Blog / news', 'nr-brief-builder' ), __( 'Photo / video gallery', 'nr-brief-builder' ), __( 'Live chat', 'nr-brief-builder' ), __( 'None in particular', 'nr-brief-builder' ) ) ),
							self::field_chips( 'logistics', __( 'Do you already have a domain and hosting?', 'nr-brief-builder' ), false, array( __( 'Yes, both', 'nr-brief-builder' ), __( 'Domain yes, hosting no', 'nr-brief-builder' ), __( 'No, I need help', 'nr-brief-builder' ), __( "I don't know", 'nr-brief-builder' ) ) ),
							self::field_chips( 'autonomy', __( 'Would you like to be able to update the site yourself?', 'nr-brief-builder' ), false, array( __( 'Yes, with training included', 'nr-brief-builder' ), __( 'Yes, without training', 'nr-brief-builder' ), __( "No, I'll leave it all to you", 'nr-brief-builder' ) ) ),
						),
					),
					'budget'   => array(
						'title'  => __( 'Budget & timeline', 'nr-brief-builder' ),
						'fields' => array(
							self::field_chips( 'budget', __( 'What is your budget range?', 'nr-brief-builder' ), false, array( __( 'Under €500', 'nr-brief-builder' ), __( '€500 – €1,500', 'nr-brief-builder' ), __( '€1,500 – €3,000', 'nr-brief-builder' ), __( '€3,000 – €5,000', 'nr-brief-builder' ), __( '€5,000+', 'nr-brief-builder' ), __( "Let's define it together", 'nr-brief-builder' ) ), __( 'No commitment — this just helps me tailor a proposal to your project.', 'nr-brief-builder' ) ),
							self::field_chips( 'timeline', __( 'Desired delivery date?', 'nr-brief-builder' ), false, array( __( 'No constraint', 'nr-brief-builder' ), __( 'Within 1 month', 'nr-brief-builder' ), __( 'Within 2 to 3 months', 'nr-brief-builder' ), __( 'Urgent (< 3 weeks)', 'nr-brief-builder' ) ) ),
							self::field_chips( 'followup', __( 'Do you need maintenance after launch?', 'nr-brief-builder' ), false, array( __( 'Yes, monthly', 'nr-brief-builder' ), __( 'Yes, occasional', 'nr-brief-builder' ), __( 'No', 'nr-brief-builder' ), __( 'To be discussed', 'nr-brief-builder' ) ) ),
						),
					),
					'contact'  => self::contact_step(),
				),
			),
			'graphisme'  => array(
				'label' => __( 'Graphic design', 'nr-brief-builder' ),
				'steps' => array(
					'type'     => array(
						'title'  => __( 'What type of design project do you have?', 'nr-brief-builder' ),
						'fields' => array(
							self::field_type_grid(
								'project_type',
								array(
									array( 'value' => __( 'Logo & visual identity', 'nr-brief-builder' ), 'label' => __( 'Visual identity', 'nr-brief-builder' ), 'sub' => __( 'Logo, colors, typography', 'nr-brief-builder' ), 'icon' => 'palette' ),
									array( 'value' => __( 'Full brand guidelines', 'nr-brief-builder' ), 'label' => __( 'Brand guidelines', 'nr-brief-builder' ), 'sub' => __( 'Complete brand universe', 'nr-brief-builder' ), 'icon' => 'layers' ),
									array( 'value' => __( 'Print materials', 'nr-brief-builder' ), 'label' => __( 'Print', 'nr-brief-builder' ), 'sub' => __( 'Flyers, cards, brochures', 'nr-brief-builder' ), 'icon' => 'file' ),
									array( 'value' => __( 'Digital materials', 'nr-brief-builder' ), 'label' => __( 'Digital', 'nr-brief-builder' ), 'sub' => __( 'Social media, banners', 'nr-brief-builder' ), 'icon' => 'globe' ),
									array( 'value' => __( 'Brand redesign', 'nr-brief-builder' ), 'label' => __( 'Rebranding', 'nr-brief-builder' ), 'sub' => __( 'Modernize an existing identity', 'nr-brief-builder' ), 'icon' => 'refresh' ),
									array( 'value' => __( 'Other', 'nr-brief-builder' ), 'label' => __( 'Other', 'nr-brief-builder' ), 'sub' => __( "Let's discuss it together", 'nr-brief-builder' ), 'icon' => 'help' ),
								)
							),
						),
					),
					'goals'    => array(
						'title'  => __( 'Goals & positioning', 'nr-brief-builder' ),
						'fields' => array(
							self::field_chips( 'objective', __( 'What is the main goal?', 'nr-brief-builder' ), false, array( __( 'Launch a new brand', 'nr-brief-builder' ), __( 'Modernize my image', 'nr-brief-builder' ), __( 'Stand out from competitors', 'nr-brief-builder' ), __( 'Bring consistency to my materials', 'nr-brief-builder' ), __( 'Other', 'nr-brief-builder' ) ) ),
							self::field_chips( 'visitor_action', __( 'What feeling should the brand convey?', 'nr-brief-builder' ), true, array( __( 'Premium', 'nr-brief-builder' ), __( 'Warm', 'nr-brief-builder' ), __( 'Minimalist', 'nr-brief-builder' ), __( 'Playful', 'nr-brief-builder' ), __( 'Reassuring', 'nr-brief-builder' ), __( 'Bold', 'nr-brief-builder' ) ) ),
							self::field_chips( 'brand_kit', __( 'Do you already have existing brand elements?', 'nr-brief-builder' ), false, array( __( 'Yes, to be refreshed', 'nr-brief-builder' ), __( 'A logo only', 'nr-brief-builder' ), __( 'Nothing yet, starting from scratch', 'nr-brief-builder' ) ) ),
						),
					),
					'content'  => array(
						'title'  => __( 'Content & inspiration', 'nr-brief-builder' ),
						'fields' => array(
							self::field_chips( 'volume', __( 'How many variations / materials do you estimate?', 'nr-brief-builder' ), false, array( __( '1 to 2 materials', 'nr-brief-builder' ), __( '3 to 5 materials', 'nr-brief-builder' ), __( '6 to 10 materials', 'nr-brief-builder' ), __( '10+ materials', 'nr-brief-builder' ), __( "I don't know yet", 'nr-brief-builder' ) ) ),
							self::field_chips( 'content_ready', __( 'Do you already have copy to include?', 'nr-brief-builder' ), false, array( __( 'Yes, everything is ready', 'nr-brief-builder' ), __( 'Partially', 'nr-brief-builder' ), __( 'No, I need help', 'nr-brief-builder' ) ) ),
							self::field_chips( 'languages', __( 'Distribution area?', 'nr-brief-builder' ), false, array( __( 'Domestic only', 'nr-brief-builder' ), __( 'International', 'nr-brief-builder' ), __( 'Not defined yet', 'nr-brief-builder' ) ) ),
							self::field_textarea( 'references', __( 'Do you have any visual references?', 'nr-brief-builder' ), true, __( 'Brands, moodboards, Instagram accounts you like…', 'nr-brief-builder' ) ),
						),
					),
					'features' => array(
						'title'  => __( 'Deliverables & technical', 'nr-brief-builder' ),
						'fields' => array(
							self::field_chips( 'features', __( 'Which deliverables would you like?', 'nr-brief-builder' ), true, array( __( 'Logo (source files)', 'nr-brief-builder' ), __( 'Brand guidelines PDF', 'nr-brief-builder' ), __( 'Social media templates', 'nr-brief-builder' ), __( 'Printed materials', 'nr-brief-builder' ), __( 'Email signature', 'nr-brief-builder' ), __( 'None in particular', 'nr-brief-builder' ) ) ),
							self::field_chips( 'logistics', __( 'Is printing already arranged?', 'nr-brief-builder' ), false, array( __( 'Yes, with a printer', 'nr-brief-builder' ), __( 'No, I need advice', 'nr-brief-builder' ), __( 'Not applicable', 'nr-brief-builder' ) ) ),
							self::field_chips( 'autonomy', __( 'Would you like to be able to update materials yourself?', 'nr-brief-builder' ), false, array( __( 'Yes, with training included', 'nr-brief-builder' ), __( 'Yes, without training', 'nr-brief-builder' ), __( "No, I'll leave it all to you", 'nr-brief-builder' ) ) ),
						),
					),
					'budget'   => array(
						'title'  => __( 'Budget & timeline', 'nr-brief-builder' ),
						'fields' => array(
							self::field_chips( 'budget', __( 'What is your budget range?', 'nr-brief-builder' ), false, array( __( 'Under €300', 'nr-brief-builder' ), __( '€300 – €800', 'nr-brief-builder' ), __( '€800 – €1,500', 'nr-brief-builder' ), __( '€1,500 – €3,000', 'nr-brief-builder' ), __( '€3,000+', 'nr-brief-builder' ), __( "Let's define it together", 'nr-brief-builder' ) ), __( 'No commitment — this just helps me tailor a proposal to your project.', 'nr-brief-builder' ) ),
							self::field_chips( 'timeline', __( 'Desired delivery date?', 'nr-brief-builder' ), false, array( __( 'No constraint', 'nr-brief-builder' ), __( 'Within 2 weeks', 'nr-brief-builder' ), __( 'Within 1 month', 'nr-brief-builder' ), __( 'Urgent (< 1 week)', 'nr-brief-builder' ) ) ),
							self::field_chips( 'followup', __( 'Will you need future variations?', 'nr-brief-builder' ), false, array( __( 'Yes, regularly', 'nr-brief-builder' ), __( 'Yes, occasionally', 'nr-brief-builder' ), __( 'No', 'nr-brief-builder' ), __( 'To be discussed', 'nr-brief-builder' ) ) ),
						),
					),
					'contact'  => self::contact_step(),
				),
			),
			'coaching'   => array(
				'label' => __( 'Coaching', 'nr-brief-builder' ),
				'steps' => array(
					'type'     => array(
						'title'  => __( 'What type of support are you looking for?', 'nr-brief-builder' ),
						'fields' => array(
							self::field_type_grid(
								'project_type',
								array(
									array( 'value' => __( 'Individual coaching', 'nr-brief-builder' ), 'label' => __( 'Individual', 'nr-brief-builder' ), 'sub' => __( 'Personalized support', 'nr-brief-builder' ), 'icon' => 'user' ),
									array( 'value' => __( 'Group coaching', 'nr-brief-builder' ), 'label' => __( 'Group', 'nr-brief-builder' ), 'sub' => __( 'Small groups or teams', 'nr-brief-builder' ), 'icon' => 'users' ),
									array( 'value' => __( 'Online program', 'nr-brief-builder' ), 'label' => __( 'Online program', 'nr-brief-builder' ), 'sub' => __( 'Content at your own pace', 'nr-brief-builder' ), 'icon' => 'globe' ),
									array( 'value' => __( 'Workshop / masterclass', 'nr-brief-builder' ), 'label' => __( 'Workshop', 'nr-brief-builder' ), 'sub' => __( 'One-off session', 'nr-brief-builder' ), 'icon' => 'star' ),
									array( 'value' => __( 'Assessment / audit', 'nr-brief-builder' ), 'label' => __( 'Assessment', 'nr-brief-builder' ), 'sub' => __( 'Initial diagnosis', 'nr-brief-builder' ), 'icon' => 'search' ),
									array( 'value' => __( 'Other', 'nr-brief-builder' ), 'label' => __( 'Other', 'nr-brief-builder' ), 'sub' => __( "Let's discuss it together", 'nr-brief-builder' ), 'icon' => 'help' ),
								)
							),
						),
					),
					'goals'    => array(
						'title'  => __( 'Goals & situation', 'nr-brief-builder' ),
						'fields' => array(
							self::field_chips( 'objective', __( 'What is your main goal?', 'nr-brief-builder' ), false, array( __( 'Career growth', 'nr-brief-builder' ), __( 'Personal development', 'nr-brief-builder' ), __( 'Stress management', 'nr-brief-builder' ), __( 'Public speaking', 'nr-brief-builder' ), __( 'Career change', 'nr-brief-builder' ), __( 'Other', 'nr-brief-builder' ) ) ),
							self::field_chips( 'visitor_action', __( 'What do you expect from this support?', 'nr-brief-builder' ), true, array( __( 'Practical tools', 'nr-brief-builder' ), __( 'Regular support', 'nr-brief-builder' ), __( 'A turning point', 'nr-brief-builder' ), __( 'An action plan', 'nr-brief-builder' ), __( 'A space to be heard', 'nr-brief-builder' ) ) ),
							self::field_chips( 'brand_kit', __( 'Have you had similar support before?', 'nr-brief-builder' ), false, array( __( 'Yes, recently', 'nr-brief-builder' ), __( 'Yes, a while ago', 'nr-brief-builder' ), __( 'Never', 'nr-brief-builder' ) ) ),
						),
					),
					'content'  => array(
						'title'  => __( 'Context & availability', 'nr-brief-builder' ),
						'fields' => array(
							self::field_chips( 'volume', __( 'How many sessions are you considering?', 'nr-brief-builder' ), false, array( __( 'A discovery session', 'nr-brief-builder' ), __( '3 to 5 sessions', 'nr-brief-builder' ), __( '6 to 10 sessions', 'nr-brief-builder' ), __( 'Long-term support', 'nr-brief-builder' ), __( "I don't know yet", 'nr-brief-builder' ) ) ),
							self::field_chips( 'content_ready', __( 'Have you already thought through your specific goals?', 'nr-brief-builder' ), false, array( __( 'Yes, everything is clear', 'nr-brief-builder' ), __( 'Partially', 'nr-brief-builder' ), __( 'No, I need help defining them', 'nr-brief-builder' ) ) ),
							self::field_chips( 'languages', __( 'Preferred format?', 'nr-brief-builder' ), false, array( __( 'Video call', 'nr-brief-builder' ), __( 'In person', 'nr-brief-builder' ), __( 'No preference', 'nr-brief-builder' ) ) ),
							self::field_textarea( 'references', __( 'A word about your current situation?', 'nr-brief-builder' ), true, __( 'Context, constraints, what prompted you to seek support…', 'nr-brief-builder' ) ),
						),
					),
					'features' => array(
						'title'  => __( 'Format', 'nr-brief-builder' ),
						'fields' => array(
							self::field_chips( 'features', __( 'Which formats interest you?', 'nr-brief-builder' ), true, array( __( 'Individual sessions', 'nr-brief-builder' ), __( 'Messaging follow-up', 'nr-brief-builder' ), __( 'Written resources', 'nr-brief-builder' ), __( 'Practical exercises', 'nr-brief-builder' ), __( 'End-of-program review', 'nr-brief-builder' ), __( 'None in particular', 'nr-brief-builder' ) ) ),
							self::field_chips( 'logistics', __( 'Available time slots?', 'nr-brief-builder' ), false, array( __( 'Daytime', 'nr-brief-builder' ), __( 'Evening', 'nr-brief-builder' ), __( 'Weekend', 'nr-brief-builder' ), __( 'Flexible', 'nr-brief-builder' ) ) ),
							self::field_chips( 'autonomy', __( 'Preferred pace between sessions?', 'nr-brief-builder' ), false, array( __( 'Weekly', 'nr-brief-builder' ), __( 'Every 2 weeks', 'nr-brief-builder' ), __( 'Monthly', 'nr-brief-builder' ), __( "Let's define it together", 'nr-brief-builder' ) ) ),
						),
					),
					'budget'   => array(
						'title'  => __( 'Budget & availability', 'nr-brief-builder' ),
						'fields' => array(
							self::field_chips( 'budget', __( 'What budget do you have in mind?', 'nr-brief-builder' ), false, array( __( 'Under €100', 'nr-brief-builder' ), __( '€100 – €300', 'nr-brief-builder' ), __( '€300 – €800', 'nr-brief-builder' ), __( '€800+', 'nr-brief-builder' ), __( "Let's define it together", 'nr-brief-builder' ) ), __( 'No commitment — this just helps me tailor a proposal to your situation.', 'nr-brief-builder' ) ),
							self::field_chips( 'timeline', __( 'When would you like to start?', 'nr-brief-builder' ), false, array( __( 'As soon as possible', 'nr-brief-builder' ), __( 'Within 2 weeks', 'nr-brief-builder' ), __( 'Within the month', 'nr-brief-builder' ), __( 'Not decided yet', 'nr-brief-builder' ) ) ),
							self::field_chips( 'followup', __( 'Interested in follow-up after the program?', 'nr-brief-builder' ), false, array( __( 'Yes', 'nr-brief-builder' ), __( 'No', 'nr-brief-builder' ), __( 'To be discussed', 'nr-brief-builder' ) ) ),
						),
					),
					'contact'  => self::contact_step(),
				),
			),
		);

		return $templates;
	}

	/**
	 * Shared "contact" final step (coordinates + dynamic recap + submit).
	 *
	 * @return array
	 */
	private static function contact_step() {
		return array(
			'title'  => __( 'Your contact details', 'nr-brief-builder' ),
			'note'   => __( 'All your answers will be included in your brief.', 'nr-brief-builder' ),
			'fields' => array(
				self::field_text( 'name', __( 'Name', 'nr-brief-builder' ), false, __( 'First and last name', 'nr-brief-builder' ), true ),
				self::field_text( 'email', __( 'Email', 'nr-brief-builder' ), false, __( 'you@email.com', 'nr-brief-builder' ), true, 'email' ),
				self::field_text( 'company', __( 'Company / activity', 'nr-brief-builder' ), true, __( 'Name of your company or activity', 'nr-brief-builder' ) ),
				self::field_textarea( 'message', __( 'A note about your project', 'nr-brief-builder' ), true, __( 'Context, inspiration, specific constraints…', 'nr-brief-builder' ) ),
			),
		);
	}

	/**
	 * Field-group factory helpers.
	 */

	private static function field_type_grid( $key, $options ) {
		return array(
			'type'     => 'type_grid',
			'key'      => $key,
			// Shared label across every preset — surfaced in the dynamic recap
			// panel and reused (see get_field_labels_from_config()) anywhere a
			// human-readable label is needed for this field, e.g. the "brief
			// details" meta box and the notification email.
			'label'    => __( 'Project type', 'nr-brief-builder' ),
			'options'  => $options,
			'required' => true,
		);
	}

	private static function field_chips( $key, $label, $multi, $options, $hint = '' ) {
		// A small, consistent set of keys is surfaced in the dynamic recap
		// panel across all presets (mirrors the original prototype's recap).
		$recap_keys = array( 'objective', 'volume', 'features', 'budget', 'timeline' );

		return array(
			'type'     => 'chips',
			'key'      => $key,
			'label'    => $label,
			'multi'    => (bool) $multi,
			'options'  => $options,
			'hint'     => $hint,
			'required' => false,
			'recap'    => in_array( $key, $recap_keys, true ),
		);
	}

	private static function field_textarea( $key, $label, $optional = true, $placeholder = '' ) {
		return array( 'type' => 'textarea', 'key' => $key, 'label' => $label, 'optional' => $optional, 'placeholder' => $placeholder, 'required' => false );
	}

	private static function field_text( $key, $label, $optional = true, $placeholder = '', $required = false, $input_type = 'text' ) {
		return array( 'type' => $input_type, 'key' => $key, 'label' => $label, 'optional' => $optional, 'placeholder' => $placeholder, 'required' => $required );
	}

	/**
	 * Flatten a template config into a field-key => translated-label map.
	 *
	 * Used anywhere a stored answer needs a human-readable, translatable
	 * label instead of guessing one from the raw internal field key (e.g.
	 * the submission meta box and the notification email).
	 *
	 * @param array $config A template config as returned by get_template().
	 * @return array<string,string>
	 */
	public static function get_field_labels_from_config( $config ) {
		$labels = array();

		if ( empty( $config['steps'] ) || ! is_array( $config['steps'] ) ) {
			return $labels;
		}

		foreach ( $config['steps'] as $step ) {
			if ( empty( $step['fields'] ) ) {
				continue;
			}
			foreach ( $step['fields'] as $field ) {
				if ( isset( $field['key'], $field['label'] ) ) {
					$labels[ $field['key'] ] = $field['label'];
				}
			}
		}

		return $labels;
	}

	/**
	 * Convenience wrapper: field-key => translated-label map for a template key.
	 *
	 * @param string $template_key Template key (e.g. 'web').
	 * @return array<string,string>
	 */
	public static function get_field_labels( $template_key ) {
		return self::get_field_labels_from_config( self::get_template( $template_key ) );
	}

	/**
	 * Small static icon set used by "type_grid" fields (safe, hardcoded SVGs — not user input).
	 *
	 * @param string $name Icon name.
	 * @return string
	 */
	public static function icon( $name ) {
		$icons = array(
			'globe'   => '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15 15 0 0 1 0 20M12 2a15 15 0 0 0 0 20"/></svg>',
			'refresh' => '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></svg>',
			'cart'    => '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="9" cy="21" r="1"/><circle cx="20" cy="21" r="1"/><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"/></svg>',
			'search'  => '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>',
			'wrench'  => '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/></svg>',
			'help'    => '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>',
			'palette' => '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="13.5" cy="6.5" r=".5"/><circle cx="17.5" cy="10.5" r=".5"/><circle cx="8.5" cy="7.5" r=".5"/><circle cx="6.5" cy="12.5" r=".5"/><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.9 0 1.5-.7 1.5-1.5 0-.4-.2-.8-.4-1.1-.2-.3-.4-.6-.4-1 0-.8.7-1.5 1.5-1.5H16c3.3 0 6-2.7 6-6 0-4.4-4.5-8-10-8z"/></svg>',
			'layers'  => '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/></svg>',
			'file'    => '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>',
			'user'    => '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>',
			'users'   => '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>',
			'star'    => '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>',
		);

		return isset( $icons[ $name ] ) ? $icons[ $name ] : $icons['help'];
	}

	/**
	 * Render a full [nr_brief] form instance and return the HTML.
	 *
	 * @param array $atts Shortcode attributes (already parsed by the shortcode class).
	 * @return string
	 */
	public function render_form( $atts ) {
		$template_key = sanitize_key( $atts['template'] );
		$config       = self::get_template( $template_key );
		$step_labels  = self::get_step_labels();
		$instance_id  = 'briefify-' . substr( md5( wp_rand() . microtime() ), 0, 8 );

		// Defensive: see the docblock on register_assets() for why this is
		// necessary here too, not just on the wp_enqueue_scripts hook.
		$this->register_assets();

		wp_enqueue_style( 'briefify-front' );
		wp_enqueue_script( 'briefify-front' );

		if ( ! self::$localized ) {
			wp_localize_script(
				'briefify-front',
				'briefifyData',
				array(
					'ajaxUrl' => admin_url( 'admin-ajax.php' ),
					'nonce'   => wp_create_nonce( 'briefify_form_nonce' ),
					'i18n'    => array(
						'selectRequired' => __( 'Please select an option to continue.', 'nr-brief-builder' ),
						'fieldRequired'  => __( 'This field is required.', 'nr-brief-builder' ),
						'emailInvalid'   => __( 'Please enter a valid email address.', 'nr-brief-builder' ),
						'sending'        => __( 'Sending…', 'nr-brief-builder' ),
						'error'          => __( 'Something went wrong. Please try again.', 'nr-brief-builder' ),
						'empty'          => '—',
					),
				)
			);
			self::$localized = true;
		}

		$steps = $config['steps'];
		$slugs = array_keys( $steps );
		$total = count( $slugs );

		ob_start();
		?>
		<div class="briefify-wrap" id="<?php echo esc_attr( $instance_id ); ?>" data-briefify data-template="<?php echo esc_attr( $template_key ); ?>" data-step="1" data-total-steps="<?php echo esc_attr( $total ); ?>">

			<?php
			// Pro (includes/pro/class-briefify-pro-branding.php) hooks this to
			// show a custom logo above the form. No-op in the free version.
			do_action( 'briefify_form_before_content', $instance_id );
			?>

			<div class="briefify-success" data-briefify-success hidden>
				<div class="briefify-success-icon">
					<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="20 6 9 17 4 12"/></svg>
				</div>
				<h3><?php esc_html_e( 'Brief sent!', 'nr-brief-builder' ); ?></h3>
				<p data-briefify-success-message></p>
			</div>

			<form class="briefify-form" id="<?php echo esc_attr( $instance_id ); ?>-form" data-briefify-form novalidate>
				<?php
				// Deliberately NOT named "briefify_*": the generic field collector in
				// handle_submit() sweeps every briefify_-prefixed POST key into the
				// stored brief data, and this decorative field (actual verification
				// uses the separate "nonce" value the JS appends from briefifyData)
				// would otherwise leak in as a spurious "nonce" entry.
				wp_nonce_field( 'briefify_form_nonce' );
				?>
				<input type="hidden" name="template" value="<?php echo esc_attr( $template_key ); ?>">

				<div class="briefify-progress-bar"><div class="briefify-progress-fill" data-briefify-progress></div></div>
				<div class="briefify-stepper-header" data-briefify-stepper-header>
					<?php
					$i = 1;
					foreach ( $step_labels as $slug => $label ) :
						?>
						<div class="briefify-step-item" data-briefify-step-item="<?php echo esc_attr( $i ); ?>">
							<div class="briefify-bubble<?php echo ( 1 === $i ) ? ' briefify-bubble--active' : ''; ?>" data-briefify-bubble><?php echo esc_html( $i ); ?></div>
							<span class="briefify-step-label<?php echo ( 1 !== $i ) ? ' briefify-step-label--muted' : ''; ?>" data-briefify-step-label><?php echo esc_html( $label ); ?></span>
						</div>
						<?php if ( $i < $total ) : ?>
							<div class="briefify-connector" data-briefify-connector></div>
						<?php endif; ?>
						<?php
						$i++;
					endforeach;
					?>
				</div>

				<?php
				$step_number = 1;
				foreach ( $slugs as $slug ) :
					$step_config = $steps[ $slug ];
					$step_file   = BRIEFIFY_PLUGIN_DIR . 'templates/form/step-' . $slug . '.php';
					if ( file_exists( $step_file ) ) {
						include $step_file;
					}
					$step_number++;
				endforeach;
				?>
			</form>
		</div>
		<?php

		return ob_get_clean();
	}

	/**
	 * Render one field group. Called from step templates.
	 *
	 * @param array $field Field config as built by the field_*() helpers.
	 */
	public static function render_field( $field ) {
		switch ( $field['type'] ) {
			case 'type_grid':
				self::render_type_grid( $field );
				break;
			case 'chips':
				self::render_chips( $field );
				break;
			case 'textarea':
				self::render_textarea( $field );
				break;
			default:
				self::render_text_input( $field );
				break;
		}
	}

	private static function render_type_grid( $field ) {
		?>
		<div class="briefify-type-grid" data-briefify-type-grid data-field="<?php echo esc_attr( $field['key'] ); ?>" data-recap-label="<?php echo esc_attr( $field['label'] ); ?>">
			<?php foreach ( $field['options'] as $option ) : ?>
				<label class="briefify-type-card">
					<input type="radio" name="<?php echo esc_attr( $field['key'] ); ?>" value="<?php echo esc_attr( $option['value'] ); ?>">
					<span class="briefify-type-icon"><?php echo self::icon( $option['icon'] ); // phpcs:ignore WordPress.Security.EscapeOutput -- static SVG, not user input. ?></span>
					<span class="briefify-type-label"><?php echo esc_html( $option['label'] ); ?></span>
					<span class="briefify-type-sub"><?php echo esc_html( $option['sub'] ); ?></span>
				</label>
			<?php endforeach; ?>
		</div>
		<?php
	}

	private static function render_chips( $field ) {
		$field_id = 'briefify_' . $field['key'];
		?>
		<div class="briefify-field-group" <?php echo ! empty( $field['recap'] ) ? 'data-recap="1" data-recap-label="' . esc_attr( $field['label'] ) . '"' : ''; ?>>
			<span class="briefify-label"><?php echo esc_html( $field['label'] ); ?><?php echo $field['multi'] ? ' <em class="briefify-label-hint">(' . esc_html__( 'multiple choices allowed', 'nr-brief-builder' ) . ')</em>' : ''; ?></span>
			<?php if ( ! empty( $field['hint'] ) ) : ?>
				<p class="briefify-label-hint briefify-label-hint--block"><?php echo esc_html( $field['hint'] ); ?></p>
			<?php endif; ?>
			<div class="briefify-chips<?php echo $field['multi'] ? ' briefify-chips--multi' : ''; ?>" data-briefify-chips data-field="<?php echo esc_attr( $field_id ); ?>" data-multi="<?php echo $field['multi'] ? '1' : '0'; ?>">
				<?php foreach ( $field['options'] as $option ) : ?>
					<button type="button" class="briefify-chip" data-value="<?php echo esc_attr( $option ); ?>"><?php echo esc_html( $option ); ?></button>
				<?php endforeach; ?>
			</div>
			<input type="hidden" name="<?php echo esc_attr( $field_id ); ?>" id="<?php echo esc_attr( $field_id ); ?>" value="">
		</div>
		<?php
	}

	private static function render_textarea( $field ) {
		$field_id = 'briefify_' . $field['key'];
		?>
		<div class="briefify-field-group">
			<label class="briefify-label" for="<?php echo esc_attr( $field_id ); ?>">
				<?php echo esc_html( $field['label'] ); ?>
				<?php if ( ! empty( $field['optional'] ) ) : ?>
					<em class="briefify-label-hint">(<?php esc_html_e( 'optional', 'nr-brief-builder' ); ?>)</em>
				<?php endif; ?>
			</label>
			<textarea id="<?php echo esc_attr( $field_id ); ?>" name="<?php echo esc_attr( $field_id ); ?>" class="briefify-input briefify-textarea" rows="3" placeholder="<?php echo esc_attr( $field['placeholder'] ); ?>"></textarea>
		</div>
		<?php
	}

	private static function render_text_input( $field ) {
		$field_id = 'briefify_' . $field['key'];
		$type     = in_array( $field['type'], array( 'email', 'tel', 'text' ), true ) ? $field['type'] : 'text';
		?>
		<div class="briefify-field-group">
			<label class="briefify-label" for="<?php echo esc_attr( $field_id ); ?>">
				<?php echo esc_html( $field['label'] ); ?>
				<?php if ( ! empty( $field['required'] ) ) : ?>
					<span class="briefify-required">*</span>
				<?php elseif ( ! empty( $field['optional'] ) ) : ?>
					<em class="briefify-label-hint">(<?php esc_html_e( 'optional', 'nr-brief-builder' ); ?>)</em>
				<?php endif; ?>
			</label>
			<input type="<?php echo esc_attr( $type ); ?>" id="<?php echo esc_attr( $field_id ); ?>" name="<?php echo esc_attr( $field_id ); ?>" class="briefify-input" placeholder="<?php echo esc_attr( $field['placeholder'] ); ?>" <?php echo ! empty( $field['required'] ) ? 'required' : ''; ?>>
		</div>
		<?php
	}

	/**
	 * Handle the AJAX form submission.
	 */
	public function handle_submit() {
		check_ajax_referer( 'briefify_form_nonce', 'nonce' );

		$template_key = isset( $_POST['template'] ) ? sanitize_key( wp_unslash( $_POST['template'] ) ) : 'web';
		$config       = self::get_template( $template_key );

		$name  = isset( $_POST['briefify_name'] ) ? sanitize_text_field( wp_unslash( $_POST['briefify_name'] ) ) : '';
		$email = isset( $_POST['briefify_email'] ) ? sanitize_email( wp_unslash( $_POST['briefify_email'] ) ) : '';

		if ( empty( $name ) || empty( $email ) || ! is_email( $email ) ) {
			wp_send_json_error( array( 'message' => __( 'Please provide a name and a valid email address.', 'nr-brief-builder' ) ) );
		}

		// Collect every briefify_* field generically (chips hidden inputs, texts, textareas).
		// A handful of non-data control keys are excluded even though they'd otherwise
		// match the prefix (defense in depth alongside the nonce field naming above).
		$skip_keys = array( 'briefify_nonce' );
		$data      = array();
		foreach ( $_POST as $key => $value ) {
			if ( 0 !== strpos( $key, 'briefify_' ) || in_array( $key, $skip_keys, true ) ) {
				continue;
			}
			$clean_key = sanitize_key( substr( $key, strlen( 'briefify_' ) ) );
			$raw_value = wp_unslash( $value );
			$data[ $clean_key ] = is_array( $raw_value )
				? array_map( 'sanitize_text_field', $raw_value )
				: ( 'message' === $clean_key || 'references' === $clean_key ? sanitize_textarea_field( $raw_value ) : sanitize_text_field( $raw_value ) );
		}

		$project_type = isset( $_POST['project_type'] ) ? sanitize_text_field( wp_unslash( $_POST['project_type'] ) ) : '';

		$post_id = wp_insert_post(
			array(
				'post_type'   => BRIEFIFY_CPT,
				'post_status' => 'publish',
				'post_title'  => sprintf( '%s — %s', $name, $project_type ? $project_type : __( 'Brief', 'nr-brief-builder' ) ),
			),
			true
		);

		if ( is_wp_error( $post_id ) ) {
			wp_send_json_error( array( 'message' => __( 'We couldn’t save your request. Please try again.', 'nr-brief-builder' ) ) );
		}

		$data['project_type'] = $project_type;
		$data['name']         = $name;
		$data['email']        = $email;

		update_post_meta( $post_id, '_briefify_data', $data );
		update_post_meta( $post_id, '_briefify_template', $config['label'] );
		// Raw template key (as opposed to its translated label above), kept
		// separately so admin screens can re-resolve field labels later —
		// see Briefify_Admin::render_meta_box().
		update_post_meta( $post_id, '_briefify_template_key', $template_key );
		update_post_meta( $post_id, '_briefify_status', 'new' );

		$this->email->send_notification( $post_id, $data, $config );
		$this->email->send_confirmation( $data, $config );

		wp_send_json_success(
			array(
				'message' => __( 'Thank you! Your brief has been sent. You’ll hear back shortly.', 'nr-brief-builder' ),
			)
		);
	}
}
