<?php
/**
 * Gutenberg Block Registration
 *
 * @package Vareon_Calculator_Suite_Lite
 */

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

if ( ! function_exists( 'vareoncalc_get_calculator_library' ) ) {
	/**
	 * Calculator library used by the block editor and other consumers.
	 *
	 * @return array Calculator library.
	 */
	function vareoncalc_get_calculator_library() {
		if ( function_exists( 'vareoncalc_settings_get_calculator_library' ) ) {
			return vareoncalc_settings_get_calculator_library();
		}

		return array(
			'loan'               => array(
				'title'       => 'Loan Calculator',
				'icon'        => '💰',
				'category'    => 'finance',
				'version'     => 'lite',
				'description' => 'Estimate monthly loan payments and total interest for any principal, rate, and term.',
				'shortcode'   => '[vareon type="loan"]',
				'perfect_for' => array(
					'Lending and banking landing pages',
					'Finance education blogs',
					'Debt repayment resources',
				),
				'details'     => 'Collects principal, APR, and term to calculate payment amount, total interest paid, and payoff summary. Supports both short and long-term loans.',
				'example'     => '[vareon type="loan" theme="dark" width="620px"]',
			),
			'mortgage'           => array(
				'title'       => 'Mortgage Calculator',
				'icon'        => '🏠',
				'category'    => 'finance',
				'version'     => 'lite',
				'description' => 'Break down mortgage payments with taxes, insurance, and HOA options.',
				'shortcode'   => '[vareon type="mortgage"]',
				'perfect_for' => array(
					'Real estate listings and blogs',
					'Mortgage broker websites',
					'Home buyer education hubs',
				),
				'details'     => 'Calculates monthly mortgage payment, total cost, and payoff summaries with optional property tax, insurance, and HOA fee inputs.',
				'example'     => '[vareon type="mortgage" theme="light"]',
			),
			'savings'            => array(
				'title'       => 'Savings & Compound Growth',
				'icon'        => '📈',
				'category'    => 'finance',
				'version'     => 'lite',
				'description' => 'Project compound growth with one-time and recurring contributions.',
				'shortcode'   => '[vareon type="savings"]',
				'perfect_for' => array(
					'Personal finance blogs',
					'Retirement planning pages',
					'Financial coaching services',
				),
				'details'     => 'Shows future balance, total contributions, and interest earned using monthly, yearly, or lump-sum contributions with adjustable rates.',
				'example'     => '[vareon type="savings" branding="0"]',
			),
			'credit-card-payoff' => array(
				'title'       => 'Credit Card Payoff Planner',
				'icon'        => '💳',
				'category'    => 'finance',
				'version'     => 'lite',
				'description' => 'Compare payoff timelines and interest savings for credit card balances.',
				'shortcode'   => '[vareon type="credit-card-payoff"]',
				'perfect_for' => array(
					'Debt relief and budgeting sites',
					'Financial coaching resources',
					'Consumer finance blogs',
				),
				'details'     => 'Calculates payoff date, total interest, and savings when paying more than the minimum. Highlights comparison versus minimum-only payments.',
				'example'     => '[vareon type="credit-card-payoff" width="580px"]',
			),
			'roi'                => array(
				'title'       => 'ROI Calculator',
				'icon'        => '💵',
				'category'    => 'finance',
				'version'     => 'lite',
				'description' => 'Measure return on investment with gain/loss and percentage output.',
				'shortcode'   => '[vareon type="roi"]',
				'perfect_for' => array(
					'Marketing campaign reporting',
					'Investment and startup blogs',
					'Product pricing pages',
				),
				'details'     => 'Computes profit or loss, ROI percentage, and break-even information from cost and gain inputs.',
				'example'     => '[vareon type="roi" theme="dark"]',
			),
			'discount'           => array(
				'title'       => 'Discount Calculator',
				'icon'        => '🏷️',
				'category'    => 'commerce',
				'version'     => 'lite',
				'description' => 'Show shoppers sale price, savings percentage, and final totals instantly.',
				'shortcode'   => '[vareon type="discount"]',
				'perfect_for' => array(
					'Ecommerce product pages',
					'Affiliate marketing content',
					'Retail promotions and sales',
				),
				'details'     => 'Outputs discounted price, amount saved, and original price comparison from cost and discount inputs.',
				'example'     => '[vareon type="discount" branding="0"]',
			),
			'tip'                => array(
				'title'       => 'Tip Calculator',
				'icon'        => '🧾',
				'category'    => 'lifestyle',
				'version'     => 'lite',
				'description' => 'Split bills and calculate tip totals with per-person breakdown.',
				'shortcode'   => '[vareon type="tip"]',
				'perfect_for' => array(
					'Restaurant and hospitality blogs',
					'Travel and dining guides',
					'Lifestyle and budgeting content',
				),
				'details'     => 'Generates tip amount, grand total, and per-person share based on bill size, tip percentage, and party size.',
				'example'     => '[vareon type="tip" theme="dark"]',
			),
			'percentage'         => array(
				'title'       => 'Percentage Calculator',
				'icon'        => '💯',
				'category'    => 'math',
				'version'     => 'lite',
				'description' => 'Solve percentage change, ratio, and "percentage of" problems fast.',
				'shortcode'   => '[vareon type="percentage"]',
				'perfect_for' => array(
					'Math and education blogs',
					'Business metrics and planning',
					'General productivity hubs',
				),
				'details'     => 'Handles percentage of, change, difference, and reverse calculations with clear outputs.',
				'example'     => '[vareon type="percentage" width="520px"]',
			),
			'fuel-cost'          => array(
				'title'       => 'Fuel Cost Calculator',
				'icon'        => '⛽',
				'category'    => 'travel',
				'version'     => 'lite',
				'description' => 'Estimate trip fuel costs using mileage, MPG, and gas price inputs.',
				'shortcode'   => '[vareon type="fuel-cost"]',
				'perfect_for' => array(
					'Travel budgeting guides',
					'Fleet and logistics blogs',
					'Road trip planning pages',
				),
				'details'     => 'Calculates total trip cost, cost per mile, and gallons required based on distance, efficiency, and price per gallon.',
				'example'     => '[vareon type="fuel-cost" branding="0"]',
			),
			'gpa'                => array(
				'title'       => 'GPA Calculator',
				'icon'        => '🎓',
				'category'    => 'education',
				'version'     => 'lite',
				'description' => 'Compute weighted GPA with customizable grade scales and credit hours.',
				'shortcode'   => '[vareon type="gpa"]',
				'perfect_for' => array(
					'Student resource centers',
					'University advising pages',
					'Education blogs and portals',
				),
				'details'     => 'Supports multiple courses, credit weighting, and both letter or numeric grade inputs with GPA summary output.',
				'example'     => '[vareon type="gpa" theme="light"]',
			),
			'grade-calc'         => array(
				'title'       => 'Grade Calculator',
				'icon'        => '📚',
				'category'    => 'education',
				'version'     => 'lite',
				'description' => 'Work out required scores to hit your target grades and track progress.',
				'shortcode'   => '[vareon type="grade-calc"]',
				'perfect_for' => array(
					'Teacher and classroom sites',
					'Student productivity blogs',
					'Course landing pages',
				),
				'details'     => 'Determines needed exam or assignment scores based on weightings and current performance to reach target grades.',
				'example'     => '[vareon type="grade-calc" width="580px"]',
			),
			'bmi'                => array(
				'title'       => 'BMI Calculator',
				'icon'        => '📏',
				'category'    => 'health',
				'version'     => 'lite',
				'description' => 'Calculate Body Mass Index with automatic category and guidance.',
				'shortcode'   => '[vareon type="bmi"]',
				'perfect_for' => array(
					'Health and wellness blogs',
					'Fitness coaches and trainers',
					'Medical resource hubs',
				),
				'details'     => 'Converts height and weight into BMI, displays health category, and shows friendly tips based on results.',
				'example'     => '[vareon type="bmi" branding="0"]',
			),
			'age'                => array(
				'title'       => 'Age Calculator',
				'icon'        => '🎂',
				'category'    => 'general',
				'version'     => 'lite',
				'description' => 'Find exact age in years, months, and days with next birthday countdown.',
				'shortcode'   => '[vareon type="age"]',
				'perfect_for' => array(
					'Birthday and milestone pages',
					'Family blogs and parenting sites',
					'Event planning resources',
				),
				'details'     => 'Outputs precise age and next birthday timeline from a single birthdate input.',
				'example'     => '[vareon type="age" theme="dark"]',
			),
			'unit-converter'     => array(
				'title'       => 'Unit Converter',
				'icon'        => '🔄',
				'category'    => 'general',
				'version'     => 'lite',
				'description' => 'Convert key units across length, weight, volume, speed, and temperature.',
				'shortcode'   => '[vareon type="unit-converter"]',
				'perfect_for' => array(
					'DIY and maker blogs',
					'Cooking and recipe sites',
					'STEM and classroom resources',
				),
				'details'     => 'Handles quick conversions across everyday measurement categories with instant results.',
				'example'     => '[vareon type="unit-converter" width="500px"]',
			),
		);
	}
}

/**
 * Register a custom block category.
 *
 * @param array $categories Existing block categories.
 * @param mixed $context    Block context (unused, required by filter signature).
 * @return array Modified categories.
 */
function vareoncalc_register_block_category( $categories, $context = null ) {
	unset( $context ); // Unused but required by filter signature.
	$slug = 'vareoncalc';
	foreach ( $categories as $cat ) {
		if ( ! empty( $cat['slug'] ) && $cat['slug'] === $slug ) {
			return $categories;
		}
	}

	$categories[] = array(
		'slug'  => $slug,
		'title' => esc_html__( 'Vareon Calculator Suite', 'vareon-calculator-suite-lite' ),
		'icon'  => 'calculator',
	);

	return $categories;
}
add_filter( 'block_categories_all', 'vareoncalc_register_block_category', 10, 2 );

add_action(
	'init',
	function () {
		$block_dir = trailingslashit( VAREONCALC_DIR ) . 'blocks/vareoncalc';

		$result = register_block_type(
			$block_dir,
			array(
				'render_callback' => 'vareoncalc_block_render',
			)
		);
		unset( $result );

		wp_set_script_translations(
			'vareoncalc-block-editor-script',
			'vareon-calculator-suite-lite',
			VAREONCALC_DIR . 'languages'
		);
	}
);

add_action(
	'enqueue_block_editor_assets',
	function () {
		$loader_ver       = function_exists( 'vareoncalc_get_asset_version' ) ? vareoncalc_get_asset_version() : VAREONCALC_VER;
		$editor_modal_css = function_exists( 'vareoncalc_get_resolved_asset' )
			? vareoncalc_get_resolved_asset( 'assets/editor-modal.css' )
			: array(
				'url'     => VAREONCALC_URL . 'assets/editor-modal.css',
				'version' => $loader_ver,
			);

		wp_enqueue_style(
			'vareoncalc-editor-modal',
			$editor_modal_css['url'],
			array(),
			$editor_modal_css['version']
		);
		wp_enqueue_style( 'vareoncalc-style' );

		$preview_shadow_asset = function_exists( 'vareoncalc_get_resolved_asset' )
			? vareoncalc_get_resolved_asset( 'assets/js/preview-shadow.js' )
			: array(
				'url'     => VAREONCALC_URL . 'assets/js/preview-shadow.js',
				'version' => $loader_ver,
			);
		wp_enqueue_script(
			'vareoncalc-preview-shadow',
			$preview_shadow_asset['url'],
			array(),
			$preview_shadow_asset['version'],
			true
		);

		$preview_bridge_asset = function_exists( 'vareoncalc_get_resolved_asset' )
			? vareoncalc_get_resolved_asset( 'assets/js/preview-bridge.js' )
			: array(
				'url'     => VAREONCALC_URL . 'assets/js/preview-bridge.js',
				'version' => $loader_ver,
			);
		wp_enqueue_script(
			'vareoncalc-preview-bridge',
			$preview_bridge_asset['url'],
			array(),
			$preview_bridge_asset['version'],
			true
		);

		$preview_config_factory_asset = function_exists( 'vareoncalc_get_resolved_asset' )
			? vareoncalc_get_resolved_asset( 'assets/js/preview-config-factory.js' )
			: array(
				'url'     => VAREONCALC_URL . 'assets/js/preview-config-factory.js',
				'version' => $loader_ver,
			);
		wp_enqueue_script(
			'vareoncalc-preview-config-factory',
			$preview_config_factory_asset['url'],
			array( 'vareoncalc-preview-shadow', 'vareoncalc-preview-bridge' ),
			$preview_config_factory_asset['version'],
			true
		);

		$registered_block_script = wp_scripts()->registered['vareoncalc-block-editor-script'] ?? null;
		if ( $registered_block_script ) {
			$registered_block_script->ver  = $loader_ver;
			$registered_block_script->deps = array_values(
				array_unique(
					array_merge(
						(array) $registered_block_script->deps,
						array( 'vareoncalc-preview-shadow', 'vareoncalc-preview-bridge', 'vareoncalc-preview-config-factory' )
					)
				)
			);
		}

		$registered_block_style = wp_styles()->registered['vareoncalc-block-editor-style'] ?? null;
		if ( $registered_block_style ) {
			$editor_calc_styles          = function_exists( 'vareoncalc_get_resolved_asset' )
				? vareoncalc_get_resolved_asset( 'assets/calculators.css' )
				: array(
					'url'     => VAREONCALC_URL . 'assets/calculators.css',
					'version' => $loader_ver,
				);
			$registered_block_style->src = $editor_calc_styles['url'];
			$registered_block_style->ver = $editor_calc_styles['version'];
		}

		$library = vareoncalc_get_calculator_library();
		$options = get_option( 'vareoncalc_lite_options', array() );

		$calculators = array();
		foreach ( $library as $type => $data ) {
			if ( 'white-label-branding' === $type ) {
				continue;
			}
			if ( isset( $data['category'] ) && 'pro' === $data['category'] ) {
				continue;
			}

			$calculators[ $type ] = array(
				'title'       => $data['title'] ?? ucwords( str_replace( '-', ' ', $type ) ),
				'icon'        => $data['icon'] ?? '🧮',
				'category'    => $data['category'] ?? 'general',
				'version'     => 'lite',
				'description' => $data['description'] ?? '',
			);
		}

		$themes = array(
			'light'  => __( 'Light', 'vareon-calculator-suite-lite' ),
			'dark'   => __( 'Dark', 'vareon-calculator-suite-lite' ),
			'modern' => __( 'Modern', 'vareon-calculator-suite-lite' ),
		);

		$default_theme = isset( $options['theme_preset'] ) ? sanitize_key( (string) $options['theme_preset'] ) : 'light';
		if ( ! in_array( $default_theme, array( 'light', 'dark', 'modern' ), true ) ) {
			$default_theme = 'light';
		}

		$theme_configs = array(
			'light'  => array( 'palette' => 'light' ),
			'dark'   => array( 'palette' => 'dark' ),
			'modern' => array( 'palette' => 'modern' ),
		);
		$active_theme  = $theme_configs[ $default_theme ];

		$preview_frame_data   = array(
			'url'            => add_query_arg( 'action', 'vareoncalc_lite_preview_frame', admin_url( 'admin-ajax.php', 'relative' ) ),
			'nonce'          => wp_create_nonce( 'vareoncalc_preview_frame' ),
			'context'        => 'editor',
			'expectedOrigin' => '',
			'protocol'       => '1.0',
			'debug'          => (bool) ( defined( 'VAREON_DEBUG' ) && VAREON_DEBUG ),
		);
		$preview_loader_asset = function_exists( 'vareoncalc_get_resolved_asset' )
			? vareoncalc_get_resolved_asset( 'js/vareoncalc-loader.js' )
			: array(
				'url'     => VAREONCALC_URL . 'js/vareoncalc-loader.js',
				'version' => $loader_ver,
			);

		$editor_data = array(
			'version'             => 'lite',
			'assetVersion'        => $loader_ver,
			'useMinifiedAssets'   => function_exists( 'vareoncalc_should_use_minified_assets' ) ? vareoncalc_should_use_minified_assets() : ! ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ),
			'calculators'         => $calculators,
			'themes'              => $themes,
			'defaultTheme'        => $default_theme,
			'branding'            => ! empty( $options['branding'] ),
			'pluginUrl'           => VAREONCALC_URL,
			'settingsUrl'         => admin_url( 'options-general.php?page=vareoncalc' ),
			'activeTheme'         => $active_theme,
			'themeConfigs'        => $theme_configs,
			'gutenbergModalTheme' => 'auto',
			'previewLoader'       => array(
				'url' => $preview_loader_asset['url'],
			),
			'previewFrame'        => $preview_frame_data,
		);

		wp_localize_script(
			'vareoncalc-preview-bridge',
			'VAREONCALC_PREVIEW_FRAME',
			$preview_frame_data
		);

		$editor_script_handle = 'vareoncalc-block-editor-script';
		if ( ! wp_script_is( $editor_script_handle, 'registered' ) && ! wp_script_is( $editor_script_handle, 'enqueued' ) ) {
			$editor_script_handle = 'wp-blocks';
		}

		wp_add_inline_script(
			$editor_script_handle,
			'window.VAREONCALC_EDITOR = Object.assign({}, window.VAREONCALC_EDITOR || {}, ' . wp_json_encode( $editor_data ) . ');',
			'before'
		);
	}
);

/**
 * Mark editor and loader scripts as ES modules.
 */
add_filter(
	'script_loader_tag',
	function ( $tag, $handle, $src ) {
		$module_handles = array( 'vareoncalc-loader', 'vareoncalc-loader-preview', 'vareoncalc-block-editor-script', 'vareoncalc-lite-preview-frame-loader' );

		if ( in_array( $handle, $module_handles, true ) ||
		( strpos( $handle, 'vareoncalc' ) !== false &&
		( strpos( $src, '/blocks/vareoncalc/edit.js' ) !== false || strpos( $src, '/js/vareoncalc-loader.js' ) !== false ) ) ) {
			if ( strpos( $tag, 'type=' ) === false ) {
				return str_replace( '<script ', '<script type="module" ', $tag );
			}
		}
		return $tag;
	},
	10,
	3
);

/**
 * Render block callback
 *
 * @param array    $attrs   Block attributes.
 * @param string   $content Block content (unused, required by callback signature).
 * @param WP_Block $block   Block instance (unused, required by callback signature).
 * @return string Rendered output.
 */
function vareoncalc_block_render( $attrs, $content, $block ) {
	unset( $content, $block ); // Unused but required by render callback signature.

	$raw_type = isset( $attrs['type'] ) ? strtolower( (string) $attrs['type'] ) : 'bmi';
	$type     = preg_replace( '/[^a-z\-]/', '', $raw_type );
	if ( empty( $type ) || ( function_exists( 'vareoncalc_is_calculator_available' ) && ! vareoncalc_is_calculator_available( $type ) ) ) {
		$type = 'bmi';
	}

	vareoncalc_enqueue_frontend_assets( $type );

	$raw_width = $attrs['width'] ?? '100%';
	if ( function_exists( 'vareoncalc_sanitize_css_width' ) ) {
		$width = vareoncalc_sanitize_css_width( $raw_width );
	} else {
		$width = sanitize_text_field( (string) $raw_width );
	}

	$theme = null;
	if ( isset( $attrs['theme'] ) && is_string( $attrs['theme'] ) ) {
		$theme_candidate = strtolower( sanitize_text_field( $attrs['theme'] ) );
		$allowed_themes  = function_exists( 'vareoncalc_get_available_themes' ) ? vareoncalc_get_available_themes() : array( 'light', 'dark', 'modern' );
		if ( in_array( $theme_candidate, $allowed_themes, true ) ) {
			$theme = $theme_candidate;
		}
	}

	$show_branding          = isset( $attrs['showBranding'] ) ? (bool) $attrs['showBranding'] : null;
	$align                  = isset( $attrs['align'] ) ? sanitize_key( $attrs['align'] ) : '';
	$min_width_px           = 300;
	$max_unaligned_width_px = 645;
	$max_wide_width_px      = 1340;
	$max_aligned_width_px   = 700;
	$allowed_align          = array( 'wide', 'full', 'left', 'right', 'center' );
	$format_css_number      = static function ( $value ) {
		$rounded = round( (float) $value, 2 );
		if ( (float) (int) $rounded === (float) $rounded ) {
			return (string) (int) $rounded;
		}

		return rtrim( rtrim( sprintf( '%.2f', $rounded ), '0' ), '.' );
	};
	$apply_width_cap        = static function ( $candidate_width, $max_width_px ) use ( $min_width_px, $format_css_number ) {
		$normalized_width = trim( (string) $candidate_width );

		if ( preg_match( '/^(\d+(?:\.\d+)?)%$/i', $normalized_width, $matches ) ) {
			$percent = (float) $matches[1];
			$percent = max( 0, min( 100, $percent ) );
			$scaled  = round( ( $max_width_px * $percent ) / 100, 2 );
			$scaled  = max( $min_width_px, min( $max_width_px, $scaled ) );
			$value   = $format_css_number( $scaled );
			return ( '' === $value ? '0' : $value ) . 'px';
		}

		if ( preg_match( '/^(\d+(?:\.\d+)?)px$/i', $normalized_width, $matches ) ) {
			$px_value = (float) $matches[1];
			$px_value = max( $min_width_px, min( $max_width_px, $px_value ) );
			$value    = $format_css_number( $px_value );
			return ( '' === $value ? '0' : $value ) . 'px';
		}

		return $candidate_width;
	};
	if ( ! in_array( $align, $allowed_align, true ) ) {
		$align = '';
	}
	if ( in_array( $align, array( 'wide', 'full' ), true ) ) {
		$width = $apply_width_cap( $width, $max_wide_width_px );
	} elseif ( in_array( $align, array( 'left', 'center', 'right' ), true ) ) {
		$width = $apply_width_cap( $width, $max_aligned_width_px );
	} else {
		$width = $apply_width_cap( $width, $max_unaligned_width_px );
	}

	$shortcode_atts = sprintf( 'type="%s"', esc_attr( $type ) );
	if ( ! empty( $width ) ) {
		$shortcode_atts .= sprintf( ' width="%s"', esc_attr( $width ) );
	}
	if ( $theme ) {
		$shortcode_atts .= sprintf( ' theme="%s"', esc_attr( $theme ) );
	}
	if ( null !== $show_branding ) {
		$shortcode_atts .= sprintf( ' branding="%d"', $show_branding ? 1 : 0 );
	}

	$output = do_shortcode( "[vareon {$shortcode_atts}]" );

	if ( ! empty( $align ) ) {
		$wrap_style  = function_exists( 'vareoncalc_build_responsive_shell_style' )
			? vareoncalc_build_responsive_shell_style( $width )
			: 'width:100%;';
		$wrap_style .= 'min-width:0;';
		$output      = sprintf(
			'<div class="vareoncalc-align-wrap align%1$s" style="%2$s">%3$s</div>',
			esc_attr( $align ),
			esc_attr( $wrap_style ),
			$output
		);
	}

	return $output;
}
