<?php

namespace GriffinForms\Admin\App\Html\Modals\FormThemes;

use GriffinForms\Items\FormTheme as FormThemeItem;

trait Renders
{
    /**
     * Determines the active category from the available list.
     *
     * @param array  $categories Available category objects.
     * @param string $requested  Requested category slug.
     *
     * @return string
     */
    protected function resolveActiveCategory($categories, $requested)
    {
        if (!is_array($categories) || empty($categories)) {
            return '';
        }

        $requested = strtolower((string) $requested);

        foreach ($categories as $category) {
            $value = is_object($category) ? $category->category : (is_array($category) ? ($category['category'] ?? '') : '');
            if ($value === '') {
                continue;
            }

            if ($requested !== '' && strtolower($value) === $requested) {
                return $value;
            }
        }

        $first = reset($categories);
        if (is_object($first) && !empty($first->category)) {
            return $first->category;
        }
        if (is_array($first) && !empty($first['category'])) {
            return $first['category'];
        }

        return '';
    }

    /**
     * Builds HTML markup for the category button list.
     *
     * @param array  $categories     Category rows with `category` and `count` keys.
     * @param string $active_category The active category.
     *
     * @return string
     */
    protected function renderThemeCategoriesHtml($categories, $active_category)
    {
        if (!is_array($categories) || empty($categories)) {
            return '';
        }

        $html = '<div class="griffinforms-theme-categories">';

        foreach ($categories as $category) {
            $slug = is_object($category) ? (string) ($category->category ?? '') : (string) ($category['category'] ?? '');
            $count = is_object($category) ? (int) ($category->count ?? 0) : (int) ($category['count'] ?? 0);

            if ($slug === '') {
                continue;
            }

            $is_active = ($slug === $active_category) ? ' active' : '';
            $label = ($slug === 'all') ? esc_html__('All', 'griffinforms-form-builder') : esc_html($slug);
            $html .= sprintf(
                '<button type="button" class="griffinforms-theme-category-btn%s" data-category="%s">' .
                '<span class="griffinforms-theme-category-label">%s</span>' .
                '<span class="griffinforms-theme-category-count">%d</span>' .
                '</button>',
                esc_attr($is_active),
                esc_attr($slug),
                $label,
                $count
            );
        }

        $html .= '</div>';

        return $html;
    }

    /**
     * Builds HTML markup for the theme grid in a given category.
     *
     * @param array $themes          Theme rows returned from SQL layer.
     * @param int   $active_theme_id Theme currently applied to the active form.
     *
     * @return string
     */
    protected function renderThemeCardsHtml($themes, $active_theme_id, $include_default = false)
    {
        $has_themes = is_array($themes) && !empty($themes);

        if (!$has_themes && !$include_default) {
            return '';
        }

        $html = '<div class="griffinforms-theme-grid">';

        if ($include_default) {
            $html .= $this->renderNoThemeCard($active_theme_id);
        }

        if ($has_themes) {
            foreach ($themes as $theme) {
                $theme_item = new FormThemeItem();
                $theme_item->hydrateFromSource($theme);
                $html .= $this->renderThemeCard($theme_item, $theme, $active_theme_id);
            }
        }

        $html .= '</div>';

        return $html;
    }

    /**
     * Builds HTML markup for individual theme cards only (without grid wrapper).
     * Used for appending additional themes via AJAX to existing grid.
     *
     * @param array $themes          Theme rows returned from SQL layer.
     * @param int   $active_theme_id Theme currently applied to the active form.
     *
     * @return string
     */
    protected function renderThemeCardsItemsHtml($themes, $active_theme_id)
    {
        $has_themes = is_array($themes) && !empty($themes);

        if (!$has_themes) {
            return '';
        }

        $html = '';

        foreach ($themes as $theme) {
            $theme_item = new FormThemeItem();
            $theme_item->hydrateFromSource($theme);
            $html .= $this->renderThemeCard($theme_item, $theme, $active_theme_id);
        }

        return $html;
    }

    /**
     * Builds the “No Theme” option card for the All category.
     *
     * @param int $active_theme_id Theme currently applied to the active form.
     *
     * @return string
     */
    protected function renderNoThemeCard($active_theme_id)
    {
        $is_applied = ($active_theme_id === 0);
        $tile_classes = 'griffinforms-theme-tile h-100 d-flex flex-column griffinforms-theme-default';
        if ($is_applied) {
            $tile_classes .= ' selected';
        }

        $apply_label_default = esc_html__('Use Default Styling', 'griffinforms-form-builder');
        $apply_label_applied = esc_html__('Default Applied', 'griffinforms-form-builder');
        $apply_label = $is_applied ? $apply_label_applied : $apply_label_default;
        $button_status = $is_applied ? 'applied' : '';

        $html  = '<div class="' . esc_attr($tile_classes) . '" data-theme-id="0">';
        $html .= '<div class="griffinforms-theme-tile-swatch mb-3">';
        $html .= '<div class="griffinforms-swatch-preview">';
        $html .= '<div class="griffinforms-theme-swatch-container griffinforms-theme-swatch-default border rounded bg-white">';
        $html .= '<div class="griffinforms-theme-swatch-inner d-flex flex-column justify-content-center gap-2 text-start">';
        $html .= '<div class="griffinforms-theme-swatch-heading h4">' . esc_html__('No Theme', 'griffinforms-form-builder') . '</div>';
        $html .= '<div class="griffinforms-theme-swatch-description text-muted small">' . esc_html__('Falls back to the stock Bootstrap styling bundled with the builder.', 'griffinforms-form-builder') . '</div>';

        $html .= '<div class="griffinforms-theme-swatch-field">';
        $html .= '<div class="griffinforms-theme-swatch-label form-label">' . esc_html__('Field Label', 'griffinforms-form-builder') . '</div>';
        $html .= '<div class="griffinforms-theme-swatch-input border border-dashed rounded-1 p-2">' . esc_html__('Text input', 'griffinforms-form-builder') . '</div>';
        $html .= '<div class="griffinforms-theme-swatch-field-description small text-muted">' . esc_html__('This is a sample field description.', 'griffinforms-form-builder') . '</div>';
        $html .= '</div>';

        $html .= '<div class="griffinforms-theme-swatch-button-wrap">';
        $html .= '<div class="griffinforms-theme-swatch-button bg-primary text-white rounded-2 d-inline-flex px-4 py-2">' . esc_html__('Submit', 'griffinforms-form-builder') . '</div>';
        $html .= '</div>';
        $html .= '</div></div></div>';
        $html .= '</div>';

        $html .= '<div class="griffinforms-theme-origin-label fw-medium text-uppercase gf-text-primary" style="font-size: 9px;">' . esc_html__('In-Built', 'griffinforms-form-builder') . '</div>';
        $html .= '<div class="griffinforms-theme-name fw-semibold border-bottom pb-2 mb-3 text-truncate">' . esc_html__('Use Default Styling', 'griffinforms-form-builder') . '</div>';
        $html .= '<p class="griffinforms-theme-description text-muted small flex-grow-1 mb-3">' . esc_html__('Revert to the built-in Bootstrap palette without any custom FormTheme overrides.', 'griffinforms-form-builder') . '</p>';
        $html .= '<div class="griffinforms-theme-actions d-flex gap-2 justify-content-between align-items-center mt-auto pt-2">';
        $html .= '<button type="button" class="gf-btn gf-btn-primary flex-fill text-center griffinforms-apply-theme-btn" data-theme-id="0" data-original-label="' . esc_attr($apply_label_default) . '" data-status="' . esc_attr($button_status) . '">';
        $html .= '<span class="gf-btn-label">' . esc_html($apply_label) . '</span>';
        $html .= '</button>';
        $html .= '</div>';
        $html .= '</div>';

        return $html;
    }

    /**
     * Renders a single theme tile including swatch preview and actions.
     *
     * @param FormThemeItem $theme_item     Hydrated theme item.
     * @param object        $theme_row      Raw theme row data.
     * @param int           $active_theme_id Currently applied theme ID.
     *
     * @return string
     */
    protected function renderThemeCard(FormThemeItem $theme_item, $theme_row, $active_theme_id)
    {
        $theme_id = absint($theme_row->id ?? 0);
        if ($theme_id < 1) {
            return '';
        }

        $theme_name = $theme_item->getProp('name') ?: ($theme_row->name ?? '');
        $theme_description = $theme_row->description ?? '';
        $origin = $theme_row->origin ?? '';

        $is_applied = ($theme_id === absint($active_theme_id));
        $tile_classes = 'griffinforms-theme-tile h-100 d-flex flex-column';
        if ($is_applied) {
            $tile_classes .= ' selected';
        }

        $apply_label_default = esc_html__('Apply Theme', 'griffinforms-form-builder');
        $apply_label_applied = esc_html__('Applied', 'griffinforms-form-builder');
        $apply_label = $is_applied ? $apply_label_applied : $apply_label_default;
        $button_status = $is_applied ? 'applied' : '';
        $button_class = $is_applied ? 'gf-btn-dark' : 'gf-btn-primary';

        $swatch_html = $this->renderThemeSwatch($theme_item);
        $edit_url = esc_url(admin_url('admin.php?page=griffinforms-formtheme&id=' . $theme_id));

        $html  = '<div class="' . esc_attr($tile_classes) . '" data-theme-id="' . esc_attr($theme_id) . '">';
        $html .= '<div class="griffinforms-theme-tile-swatch mb-3">' . $swatch_html . '</div>';

        // Add origin label above theme name
        if ($origin === 'user') {
            $html .= '<div class="griffinforms-theme-origin-label fw-medium text-uppercase gf-text-primary" style="font-size: 9px;">' . esc_html__('Uploaded', 'griffinforms-form-builder') . '</div>';
        } else {
            $html .= '<div class="griffinforms-theme-origin-label fw-medium text-uppercase gf-text-primary" style="font-size: 9px;">' . esc_html__('In-Built', 'griffinforms-form-builder') . '</div>';
        }

        $html .= '<div class="griffinforms-theme-name fw-semibold border-bottom pb-2 mb-3 text-truncate">' . esc_html($theme_name) . '</div>';

        if (!empty($theme_description)) {
            $html .= '<p class="griffinforms-theme-description text-muted small flex-grow-1 mb-3">' . esc_html($theme_description) . '</p>';
        } else {
            $html .= '<p class="griffinforms-theme-description text-muted small flex-grow-1 mb-3">' . esc_html__('No description available.', 'griffinforms-form-builder') . '</p>';
        }

        $html .= '<div class="griffinforms-theme-actions d-flex gap-2 justify-content-between align-items-center mt-auto pt-2">';
        $html .= '<button type="button" class="gf-btn ' . esc_attr($button_class) . ' flex-fill text-center griffinforms-apply-theme-btn d-flex align-items-center justify-content-center gap-2" data-theme-id="' . esc_attr($theme_id) . '" data-original-label="' . esc_attr($apply_label_default) . '" data-status="' . esc_attr($button_status) . '">';
        if ($is_applied) {
            $html .= '<svg class="gf-icon" style="width: 1.2rem; height: 1.2rem; flex-shrink: 0; fill: currentColor;" viewBox="0 0 24 24">';
            $html .= '<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" />';
            $html .= '</svg>';
        }
        $html .= '<span class="gf-btn-label">' . esc_html($apply_label) . '</span>';
        $html .= '</button>';
        $html .= '<a href="' . $edit_url . '" target="_blank" rel="noopener noreferrer" class="gf-btn gf-btn-light flex-fill text-center griffinforms-edit-theme-btn">';
        $html .= '<span class="gf-btn-label">' . esc_html__('Edit Theme', 'griffinforms-form-builder') . '</span>';
        $html .= '</a>';
        $html .= '</div>';
        $html .= '</div>';

        return $html;
    }

    /**
     * Builds the swatch preview HTML using FormTheme getters for CSS.
     *
     * @param FormThemeItem $theme_item Hydrated theme item.
     *
     * @return string
     */
    protected function renderThemeSwatch(FormThemeItem $theme_item)
    {
        $form_style = $theme_item->getFormStyleCss();
        $page_style = $theme_item->getPageStyleCss();
        $title_style = $theme_item->getPageHeadingCss();
        $description_style = $theme_item->getPageDescriptionCss();
        $row_style = $theme_item->getRowStyleCss();
        $field_label_style = $theme_item->getFieldLabelCss();
        $field_description_style = $theme_item->getFieldDescriptionCss();
        $field_input_style = $theme_item->getFieldStyleCss('text_input');
        $button_style = $theme_item->getSubmitButtonCss();

        $heading_text = __('Heading', 'griffinforms-form-builder');
        $description_content = __('Page description', 'griffinforms-form-builder');
        $sample_field_description = __('Field description', 'griffinforms-form-builder');

        $html  = '<div class="griffinforms-swatch-preview">';
        $html .= '<div class="griffinforms-theme-swatch-container p-2" style="' . esc_attr($form_style) . '">';
        $html .= '<div class="griffinforms-theme-swatch-inner d-flex flex-column justify-content-center gap-2 p-3" style="' . esc_attr($page_style) . '">';
        $html .= '<div class="griffinforms-theme-swatch-heading" style="' . esc_attr($title_style) . '">' . esc_html($heading_text) . '</div>';
        $html .= '<div class="griffinforms-theme-swatch-description" style="' . esc_attr($description_style) . '">' . esc_html($description_content) . '</div>';
        $html .= '<div class="griffinforms-theme-swatch-row" style="' . esc_attr($row_style) . '">';
        $html .= '<div class="griffinforms-theme-swatch-field">';
        $html .= '<div class="griffinforms-theme-swatch-label" style="' . esc_attr($field_label_style) . '">' . esc_html__('Field Label', 'griffinforms-form-builder') . '</div>';
        $html .= '<div class="griffinforms-theme-swatch-input" style="' . esc_attr($field_input_style) . '">' . esc_html__('Text input', 'griffinforms-form-builder') . '</div>';
        $html .= '<div class="griffinforms-theme-swatch-field-description" style="' . esc_attr($field_description_style) . '">' . esc_html($sample_field_description) . '</div>';
        $html .= '</div>';
        $html .= '</div>';
        $html .= '<div class="griffinforms-theme-swatch-button-wrap">';
        $html .= '<div class="griffinforms-theme-swatch-button" style="' . esc_attr($button_style) . '">' . esc_html__('Submit', 'griffinforms-form-builder') . '</div>';
        $html .= '</div>';
        $html .= '</div>';
        $html .= '</div>';
        $html .= '</div>';

        return $html;
    }

    /**
     * Attempts to extract display text from a typography configuration block.
     *
     * @param mixed $block Typography configuration values.
     *
     * @return string
     */
    protected function extractTypographyContent($block)
    {
        if (is_string($block)) {
            $trimmed = trim($block);
            return $trimmed;
        }

        if (!is_array($block)) {
            return '';
        }

        $candidate_keys = array(
            'text',
            'content',
            'value',
            'sample',
            'sample_text',
            'example',
            'example_text',
            'placeholder',
            'heading',
            'description'
        );

        foreach ($candidate_keys as $key) {
            if (!isset($block[$key])) {
                continue;
            }

            $value = $block[$key];

            if (is_string($value) && trim($value) !== '') {
                return trim($value);
            }

            if (is_array($value)) {
                $nested = $this->extractTypographyContent($value);
                if ($nested !== '') {
                    return $nested;
                }
            }
        }

        if (isset($block['default'])) {
            $default = $block['default'];
            if (is_string($default) && trim($default) !== '') {
                return trim($default);
            }
            if (is_array($default)) {
                return $this->extractTypographyContent($default);
            }
        }

        return '';
    }
}
