<?php
/**
 * Enhanced Template Helper Functions
 *
 * Provides extensible template loading for both shortcode and block templates
 * with support for theme overrides and third-party extensions.
 *
 * @since 4.2.0
 */

/**
 * Enhanced template locator with extensibility support
 *
 * @param string $template_file Template file path (e.g., 'blocks/user-directory/layouts/layout-1.php')
 * @param string $context Context for template (shortcode|block)
 * @param array $args Additional arguments
 * @return string|false Full path to template file or false if not found
 * @since 4.2.0
 */
function wpuf_locate_block_template($template_file, $context = 'block', $args = []) {
    $template_paths = [];

    // 1. Check theme overrides first (highest priority)
    $theme_paths = [
        'wpuf-user-directory/' . $template_file,
        'wpuf/' . $template_file,
        $template_file,
    ];

    foreach ($theme_paths as $theme_path) {
        $theme_template = locate_template([$theme_path]);
        if ($theme_template) {
            return $theme_template;
        }
    }

    // 2. Check third-party plugin overrides
    $plugin_template = apply_filters('wpuf_block_template_path', false, $template_file, $context, $args);
    if ($plugin_template && file_exists($plugin_template)) {
        return $plugin_template;
    }

    // 3. Check default plugin templates
    $default_template = WPUF_UD_TEMPLATES . '/' . $template_file;
    if (file_exists($default_template)) {
        return $default_template;
    }

    // 4. Check fallback to shortcode templates
    if ($context === 'block') {
        $shortcode_template = str_replace('blocks/', '', $template_file);
        $shortcode_template = str_replace('/layouts/', '/', $shortcode_template);
        $shortcode_template = str_replace('/blocks/', '/', $shortcode_template);

        $fallback_template = WPUF_UD_TEMPLATES . '/' . $shortcode_template;
        if (file_exists($fallback_template)) {
            return $fallback_template;
        }
    }

    return false;
}

/**
 * Load block template with context
 *
 * @param string $template_file Template file path
 * @param array $template_data Template data
 * @param string $context Context for template
 * @param array $args Additional arguments
 * @return string Rendered template HTML
 * @since 4.2.0
 */
function wpuf_load_block_template($template_file, $template_data = [], $context = 'block', $args = []) {
    $template_path = wpuf_locate_block_template($template_file, $context, $args);

    if (!$template_path) {
        return sprintf(
            '<div class="wpuf-template-error">Template not found: %s</div>',
            esc_html($template_file)
        );
    }

    // Extract template data for use in template
    if (!empty($template_data)) {
        extract($template_data);
    }

    // Start output buffering
    ob_start();

    // Include the template
    include $template_path;

    return ob_get_clean();
}

/**
 * Get block template path for specific block and layout
 *
 * @param string $block_type Block type (user-directory|user-profile)
 * @param string $layout Layout name (layout-1|layout-2|etc.)
 * @param string $template_type Template type (layouts|blocks|components)
 * @param string $template_name Template name (optional)
 * @return string Template file path
 * @since 4.2.0
 */
function wpuf_get_block_template_path($block_type, $layout, $template_type = 'layouts', $template_name = '') {
    $template_file = "blocks/{$block_type}/{$template_type}/";

    if ($template_name) {
        $template_file .= $template_name . '.php';
    } else {
        $template_file .= $layout . '.php';
    }

    return $template_file;
}

/**
 * Check if block template exists
 *
 * @param string $template_file Template file path
 * @param string $context Context for template
 * @return bool True if template exists
 * @since 4.2.0
 */
function wpuf_block_template_exists($template_file, $context = 'block') {
    return wpuf_locate_block_template($template_file, $context) !== false;
}

/**
 * Get available block templates for a specific block type
 *
 * @param string $block_type Block type
 * @param string $template_type Template type (layouts|blocks|components)
 * @return array Array of available templates
 * @since 4.2.0
 */
function wpuf_get_available_block_templates($block_type, $template_type = 'layouts') {
    $templates = [];
    $template_dir = WPUF_UD_TEMPLATES . "/blocks/{$block_type}/{$template_type}/";

    if (is_dir($template_dir)) {
        $files = glob($template_dir . '*.php');
        foreach ($files as $file) {
            $template_name = basename($file, '.php');
            $templates[$template_name] = $file;
        }
    }

    return apply_filters("wpuf_available_{$block_type}_templates", $templates, $template_type);
}

/**
 * Render block template with fallback support
 *
 * @param string $block_type Block type
 * @param string $layout Layout name
 * @param array $template_data Template data
 * @param array $args Additional arguments
 * @return string Rendered HTML
 * @since 4.2.0
 */
function wpuf_render_block_template($block_type, $layout, $template_data = [], $args = []) {
    // Try block template first
    $template_file = wpuf_get_block_template_path($block_type, $layout, 'layouts');
    $html = wpuf_load_block_template($template_file, $template_data, 'block', $args);


    return $html;
}

/**
 * Get block styling helper
 *
 * @param array $attributes Block attributes
 * @param string $block_type Block type
 * @return array Styling data
 * @since 4.2.0
 */
function wpuf_get_block_styling($attributes, $block_type) {
    // Load styling helper if exists
    $styling_helper = wpuf_locate_block_template('blocks/shared/helpers/styling.php');
    if ($styling_helper) {
        include_once $styling_helper;
    }

    // Default styling
    $styling = [
        'classes' => "wpuf-{$block_type}",
        'styles' => [],
    ];

    // Apply block editor styles - this is the key part that processes WordPress styling
    if (!empty($attributes['style'])) {
        $styling['styles'] = array_merge($styling['styles'], $attributes['style']);
    }

    // Handle direct color attributes from supports (palette slugs)
    if (!empty($attributes['backgroundColor'])) {
        $bg_slug = sanitize_key($attributes['backgroundColor']);
        $styling['styles']['background-color'] = get_theme_color_or_css_var($bg_slug);
        $styling['classes'] .= ' has-background has-' . $bg_slug . '-background-color';
    }
    if (!empty($attributes['textColor'])) {
        $text_slug = sanitize_key($attributes['textColor']);
        $styling['styles']['color'] = get_theme_color_or_css_var($text_slug);
        $styling['classes'] .= ' has-text-color has-' . $text_slug . '-color';
    }
    if (!empty($attributes['borderColor'])) {
        $border_color_slug = sanitize_key($attributes['borderColor']);
        // Ensure border array exists in styles
        if (!isset($styling['styles']['border']) || !is_array($styling['styles']['border'])) {
            $styling['styles']['border'] = [];
        }
        $styling['styles']['border']['color'] = get_theme_color_or_css_var($border_color_slug);
        $styling['classes'] .= ' has-border-color has-' . $border_color_slug . '-border-color';
    }
    if (!empty($attributes['gradient'])) {
        // Gradients typically come as var:preset|gradient|slug
        $styling['styles']['background'] = wpuf_process_color_value($attributes['gradient']);
        $styling['classes'] .= ' has-background';
    }

    // Handle style.color structure
    if (!empty($attributes['style']['color'])) {
        $color_style = $attributes['style']['color'];
        if (!empty($color_style['background'])) {
            $bg = $color_style['background'];
            $styling['styles']['background-color'] = wpuf_process_color_value($bg);
            $styling['classes'] .= ' has-background';
        }
        if (!empty($color_style['text'])) {
            $txt = $color_style['text'];
            $styling['styles']['color'] = wpuf_process_color_value($txt);
            $styling['classes'] .= ' has-text-color';
        }
        if (!empty($color_style['gradient'])) {
            $grad = $color_style['gradient'];
            $styling['styles']['background'] = wpuf_process_color_value($grad);
            $styling['classes'] .= ' has-background';
        }
    }

    // Handle style.typography structure
    if (!empty($attributes['style']['typography'])) {
        $typography_style = $attributes['style']['typography'];
        if (!empty($typography_style['fontSize'])) {
            $fs = $typography_style['fontSize'];
            $styling['styles']['font-size'] = wpuf_process_typography_value($fs);
        }
        if (!empty($typography_style['fontFamily'])) {
            $ff = $typography_style['fontFamily'];
            $styling['styles']['font-family'] = wpuf_process_typography_value($ff);
        }
        if (!empty($typography_style['fontWeight'])) {
            $fw = $typography_style['fontWeight'];
            $styling['styles']['font-weight'] = wpuf_process_typography_value($fw);
        }
        if (!empty($typography_style['lineHeight'])) {
            $lh = $typography_style['lineHeight'];
            $styling['styles']['line-height'] = wpuf_process_typography_value($lh);
        }
        if (!empty($typography_style['textAlign'])) {
            $ta = $typography_style['textAlign'];
            $styling['styles']['text-align'] = wpuf_process_typography_value($ta);
        }
        if (!empty($typography_style['fontStyle'])) {
            $fs = $typography_style['fontStyle'];
            $styling['styles']['font-style'] = wpuf_process_typography_value($fs);
        }
        if (!empty($typography_style['letterSpacing'])) {
            $ls = $typography_style['letterSpacing'];
            $styling['styles']['letter-spacing'] = wpuf_process_typography_value($ls);
        }
        if (!empty($typography_style['textTransform'])) {
            $tt = $typography_style['textTransform'];
            $styling['styles']['text-transform'] = wpuf_process_typography_value($tt);
        }
        if (!empty($typography_style['textDecoration'])) {
            $td = $typography_style['textDecoration'];
            $styling['styles']['text-decoration'] = wpuf_process_typography_value($td);
        }
    }

    // Handle style.elements structure (for link colors, etc.)
    if (!empty($attributes['style']['elements'])) {
        $elements_style = $attributes['style']['elements'];
        if (!empty($elements_style['link']['color']['text'])) {
            $link_color = $elements_style['link']['color']['text'];
            $styling['styles']['--wpuf-link-color'] = wpuf_process_color_value($link_color);
        }
    }


    // Handle typography preset helpers
    if (!empty($attributes['fontSize']) && is_string($attributes['fontSize'])) {
        $fs = sanitize_key($attributes['fontSize']);
        // If it's a preset slug, add class; if it's a raw value, style array will cover it
        $styling['classes'] .= ' has-' . $fs . '-font-size';
    }
    if (!empty($attributes['fontFamily']) && is_string($attributes['fontFamily'])) {
        $ff = sanitize_key($attributes['fontFamily']);
        // Add class used by WP for font family presets
        $styling['classes'] .= ' has-' . $ff . '-font-family';
        // Also set CSS var fallback
        $styling['styles']['font-family'] = 'var(--wp--preset--font-family--' . $ff . ')';
    }

    // Apply custom styling
    $styling = apply_filters("wpuf_{$block_type}_styling", $styling, $attributes);

    return $styling;
}

/**
 * Build inline styles from array
 *
 * @param array $styles Array of CSS properties
 * @return string Inline styles string
 * @since 4.2.0
 */
function wpuf_build_inline_styles($styles) {
    if (empty($styles) || !is_array($styles)) {
        return '';
    }

    $css_properties = [];

    foreach ($styles as $property => $value) {
        // Skip empty values
        if (empty($value) && $value !== '0') {
            continue;
        }

        // Handle array values (WordPress block editor styling)
        if (is_array($value)) {
            $processed = wpuf_process_style_array($property, $value);
            $css_properties = array_merge($css_properties, $processed);
            continue;
        }

        // Ensure property and value are strings
        $property = (string) $property;
        $value = (string) $value;

        $css_properties[] = esc_attr($property) . ': ' . esc_attr($value);
    }

    return implode('; ', $css_properties);
}

/**
 * Process WordPress block editor style arrays
 *
 * @param string $property The CSS property name
 * @param array $value The style value array
 * @return array Array of CSS property strings
 * @since 4.2.0
 */
function wpuf_process_style_array($property, $value) {
    $css_properties = [];

    switch ($property) {
        case 'color':
            // Handle color properties
            if (isset($value['background'])) {
                $css_properties[] = 'background-color: ' . wpuf_process_color_value($value['background']);
            }
            if (isset($value['backgroundColor'])) {
                $css_properties[] = 'background-color: ' . wpuf_process_color_value($value['backgroundColor']);
            }
            if (isset($value['text'])) {
                $css_properties[] = 'color: ' . wpuf_process_color_value($value['text']);
            }
            if (isset($value['textColor'])) {
                $css_properties[] = 'color: ' . wpuf_process_color_value($value['textColor']);
            }
            if (isset($value['gradient'])) {
                $css_properties[] = 'background: ' . wpuf_process_color_value($value['gradient']);
            }
            break;

        case 'spacing':
            // Handle spacing properties
            if (isset($value['padding'])) {
                $padding = wpuf_process_spacing_values($value['padding']);
                if (!empty($padding)) {
                    $css_properties[] = 'padding: ' . $padding;
                }
            }
            if (isset($value['margin'])) {
                $margin = wpuf_process_spacing_values($value['margin']);
                if (!empty($margin)) {
                    $css_properties[] = 'margin: ' . $margin;
                }
            }
            break;

        case 'typography':
            // Handle typography properties
            if (isset($value['fontSize'])) {
                $css_properties[] = 'font-size: ' . esc_attr($value['fontSize']);
            }
            if (isset($value['fontFamily'])) {
                $css_properties[] = 'font-family: ' . esc_attr($value['fontFamily']);
            }
            if (isset($value['fontWeight'])) {
                $css_properties[] = 'font-weight: ' . esc_attr($value['fontWeight']);
            }
            if (isset($value['lineHeight'])) {
                $css_properties[] = 'line-height: ' . esc_attr($value['lineHeight']);
            }
            if (isset($value['textAlign'])) {
                $css_properties[] = 'text-align: ' . esc_attr($value['textAlign']);
            }
            if (isset($value['fontStyle'])) {
                $css_properties[] = 'font-style: ' . esc_attr($value['fontStyle']);
            }
            if (isset($value['letterSpacing'])) {
                $css_properties[] = 'letter-spacing: ' . esc_attr($value['letterSpacing']);
            }
            if (isset($value['textTransform'])) {
                $css_properties[] = 'text-transform: ' . esc_attr($value['textTransform']);
            }
            if (isset($value['textDecoration'])) {
                $css_properties[] = 'text-decoration: ' . esc_attr($value['textDecoration']);
            }
            break;

        case 'border':
            // Handle border properties
            if (isset($value['width'])) {
                $css_properties[] = 'border-width: ' . esc_attr($value['width']);
            }
            if (isset($value['color'])) {
                $css_properties[] = 'border-color: ' . wpuf_process_color_value($value['color']);
            }
            if (isset($value['style'])) {
                $css_properties[] = 'border-style: ' . esc_attr($value['style']);
            }
            if (isset($value['radius'])) {
                $css_properties[] = 'border-radius: ' . esc_attr($value['radius']);
            }
            break;

        default:
            // For unknown array properties, try to convert to string
            if (is_string($value) || is_numeric($value)) {
                $css_properties[] = esc_attr($property) . ': ' . esc_attr($value);
            }
            break;
    }

    return $css_properties;
}

/**
 * Process typography values (including CSS custom properties)
 *
 * @param string $value Typography value from WordPress
 * @return string Processed typography value
 * @since 4.2.0
 */
function wpuf_process_typography_value($value) {
    if (empty($value)) {
        return '';
    }

    // Handle CSS custom properties (WordPress presets)
    if (is_string($value) && strpos($value, 'var:preset|') === 0) {
        // Convert WordPress preset to CSS custom property
        // var:preset|fontSize|medium -> var(--wp--preset--fontSize--medium)
        $value = 'var(--wp--preset--' . str_replace('var:preset|', '', $value) . ')';
        $value = str_replace('|', '--', $value);
    } elseif (is_string($value) && preg_match('/^[a-z0-9\-]+$/', $value) && !preg_match('/[0-9]+px$/', $value)) {
        // If it's a preset slug (e.g., medium, large) convert to CSS var
        // But don't convert actual pixel values like "14px"
        // Only convert fontSize presets, not fontWeight or other numeric values
        if (strpos($value, 'px') === false && strpos($value, 'em') === false && strpos($value, 'rem') === false && !is_numeric($value)) {
            $value = 'var(--wp--preset--fontSize--' . $value . ')';
        }
    }

    return esc_attr($value);
}

/**
 * Process color values (including CSS custom properties)
 *
 * @param string $color Color value from WordPress
 * @return string Processed color value
 * @since 4.2.0
 */
function wpuf_process_color_value($color) {
    if (empty($color)) {
        return '';
    }

    // Handle CSS custom properties (WordPress presets)
    if (is_string($color) && strpos($color, 'var:preset|') === 0) {
        // Convert WordPress preset to CSS custom property
        // var:preset|color|accent-4 -> var(--wp--preset--color--accent-4)
        $color = 'var(--wp--preset--' . str_replace('var:preset|', '', $color) . ')';
        $color = str_replace('|', '--', $color);
    } elseif (is_string($color) && preg_match('/^[a-z0-9\-]+$/', $color)) {
        // If it's a palette slug (e.g., accent-3) convert to CSS var or HEX
        $color = get_theme_color_or_css_var($color);
    }

    return esc_attr($color);
}

/**
 * Get theme color CSS variable for a given slug.
 * Always returns CSS variable to ensure compatibility with WordPress styling system.
 *
 * @param string $slug Color slug, e.g. 'contrast', 'base', 'accent', 'contrast-2'.
 * @return string CSS variable string for the color.
 */
function get_theme_color_or_css_var( $slug ) {
    // Normalize the slug for contrast/2 style slugs: replace '/' with '-'
    $normalized_slug = str_replace( '/', '-', $slug );

    // Always return CSS variable - WordPress handles the actual color resolution
    // This ensures compatibility with theme.json and user customizations
    return sprintf( 'var(--wp--preset--color--%s)', $normalized_slug );
}


/**
 * Process spacing values (padding/margin)
 *
 * @param array $spacing Spacing values array
 * @return string CSS spacing value
 * @since 4.2.0
 */
function wpuf_process_spacing_values($spacing) {
    if (!is_array($spacing)) {
        return '';
    }

    $values = [];
    $sides = ['top', 'right', 'bottom', 'left'];

    foreach ($sides as $side) {
        if (isset($spacing[$side])) {
            $value = $spacing[$side];

            // Handle CSS custom properties (var:preset|spacing|20)
            if (is_string($value) && strpos($value, 'var:preset|') === 0) {
                // Convert WordPress preset to CSS custom property
                // var:preset|spacing|20 -> var(--wp--preset--spacing--20)
                $value = 'var(--wp--preset--' . str_replace('var:preset|', '', $value) . ')';
                $value = str_replace('|', '--', $value);
            }

            $values[] = esc_attr($value);
        } else {
            $values[] = '0';
        }
    }

    return implode(' ', $values);
}

/**
 * Get block wrapper attributes with styling
 *
 * @param array $attributes Block attributes
 * @param string $block_type Block type
 * @param array $additional_attrs Additional attributes
 * @return string Block wrapper attributes
 * @since 4.2.0
 */
function wpuf_get_block_wrapper_attributes($attributes, $block_type, $additional_attrs = []) {
    $styling = wpuf_get_block_styling($attributes, $block_type);

    // Merge classes properly instead of overriding
    $merged_classes = trim($styling['classes'] . ' ' . ($additional_attrs['class'] ?? ''));

    $wrapper_attrs = [
        'class' => $merged_classes,
        'style' => wpuf_build_inline_styles($styling['styles']),
    ];

    // Merge additional attributes, but preserve our generated class
    foreach ($additional_attrs as $key => $value) {
        if ($key !== 'class') {
            $wrapper_attrs[$key] = $value;
        }
    }

    // Build attributes string
    $attr_parts = [];
    foreach ($wrapper_attrs as $key => $value) {
        if (!empty($value)) {
            $attr_parts[] = esc_attr($key) . '="' . esc_attr($value) . '"';
        }
    }

    return implode(' ', $attr_parts);
}
