<?php

namespace PloverCRM\Core\Services;

use PloverCRM\Core\Plugin;

/**
 * Placeholder Service
 * 
 * Centralized service for handling template placeholders across the plugin.
 * Supports standard CRM fields, custom fields, and system fields.
 */
class PlaceholderService
{
    private const CONTACT_SUMMARY_PLACEHOLDER = [
        'key' => '{contact_summary}',
        'label' => 'Contact Summary',
        'group' => 'Email Blocks',
        'bodyOnly' => true,
        'description' => 'Inserts a formatted block of all filled contact details for email bodies.',
    ];

    // Standard/contact row keys listed here are hidden from the summary.
    private const CONTACT_SUMMARY_EXCLUDED_ROW_KEYS = [
        'id',
        'status',
        'source',
        'updated_at',
    ];

    // Add slugs here to hide them completely from the contact summary block.
    private const CONTACT_SUMMARY_EXCLUDED_KEYS = [
        'plover_crm_landing_page_first_visit',
        'plover_crm_landing_datetime_first_visit',
        'plover_crm_submission_url',
        'plover_crm_last_referral_domain',
        'plover_crm_last_page_url',
    ];

    // Structured fields listed here are shown as pretty JSON blocks at the bottom.
    private const CONTACT_SUMMARY_JSON_BLOCK_KEYS = [
        'plover_crm_ip_info',
    ];

    private const CONTACT_SUMMARY_PRIMARY_VISITOR_KEYS = [
        'plover_crm_browser_name' => 'Browser',
        'plover_crm_user_os' => 'Operating System',
        'plover_crm_referral_domain' => 'Referral Domain',
        'plover_crm_last_seen_at' => 'Last Seen',
    ];

    /**
     * System placeholders (not contact-specific)
     */
    const SYSTEM_PLACEHOLDERS = [
        'workspace' => 'Workspace Domain',
        'site_url' => 'Site URL',
        'site_name' => 'Site Name',
        'date' => 'Current Date',
        'time' => 'Current Time',
        'datetime' => 'Current Date & Time',
    ];

    /**
     * Get all available placeholders for the active CRM
     * 
     * @return array Array of placeholders with key and label
     */
    public static function getAvailablePlaceholders(array $options = []): array
    {
        $placeholders = [];
        $includeRichBlocks = !empty($options['include_rich_blocks']);

        // Add standard CRM fields
        $standardFields = self::getStandardFieldPlaceholders();
        foreach ($standardFields as $key => $label) {
            $placeholders[] = [
                'key' => '{' . $key . '}',
                'label' => $label,
                'group' => 'Contact Fields',
            ];
        }

        // Add custom fields from active CRM
        $placeholders = array_merge($placeholders, self::getCustomFieldPlaceholders());

        // Add system placeholders
        foreach (self::SYSTEM_PLACEHOLDERS as $key => $label) {
            $placeholders[] = [
                'key' => '{' . $key . '}',
                'label' => $label,
                'group' => 'Workspace & Time',
            ];
        }

        if ($includeRichBlocks) {
            $placeholders[] = self::CONTACT_SUMMARY_PLACEHOLDER;
        }

        return $placeholders;
    }

    /**
     * Get standard field placeholders based on active CRM
     * 
     * @return array
     */
    private static function getStandardFieldPlaceholders(): array
    {
        $crm = Plugin::getInstance()->getContainer()->get('crm');

        if (!$crm || !$crm->isAvailable()) {
            return [];
        }

        // Get standard fields from CRM provider
        $standardFields = $crm->getStandardFields();

        // Add computed fields
        $standardFields['full_name'] = 'Full Name';
        $standardFields['id'] = 'Contact ID';
        $standardFields['status'] = 'Status';
        $standardFields['source'] = 'Source';
        $standardFields['lists'] = 'Lists';
        $standardFields['tags'] = 'Tags';
        $standardFields['created_at'] = 'Created At';
        $standardFields['updated_at'] = 'Updated At';

        return $standardFields;
    }

    /**
     * Get custom field placeholders from active CRM
     * 
     * @return array
     */
    private static function getCustomFieldPlaceholders(): array
    {
        $crm = Plugin::getInstance()->getContainer()->get('crm');

        if (!$crm || !$crm->isAvailable()) {
            return [];
        }

        $customFields = $crm->getAllCustomFields();
        $placeholders = [];

        foreach ($customFields as $field) {
            $slug = $field['slug'] ?? '';
            $label = $field['label'] ?? $slug;

            if (!empty($slug)) {
                $placeholders[] = [
                    'key' => '{' . $slug . '}',
                    'label' => $label,
                    'group' => self::resolveCustomFieldPlaceholderGroup((array) $field),
                ];
            }
        }

        return $placeholders;
    }

    private static function resolveCustomFieldPlaceholderGroup(array $field): string
    {
        $slug = (string) ($field['slug'] ?? '');
        if ($slug === '' || !SystemFieldRegistry::isSystemSlug($slug)) {
            return 'Custom Fields';
        }

        return match ((string) ($field['group'] ?? '')) {
            'CRM' => 'CRM Fields',
            'UTM Tracking' => 'UTM Tracking',
            'Visitor Metadata' => 'Visitor Metadata',
            'Ads' => 'Ads Metadata',
            default => 'System Fields',
        };
    }

    /**
     * Parse a template string and replace placeholders with contact data
     * 
     * @param string $template Template string with placeholders
     * @param array $contact Contact data array
     * @return string Parsed string with placeholders replaced
     */
    public static function parse(string $template, array $contact, array $options = []): string
    {
        if (empty($template)) {
            return '';
        }

        $template = self::replaceRichPlaceholders($template, $contact, $options);

        // Replace standard contact fields
        $standardFields = [
            'id',
            'email',
            'first_name',
            'last_name',
            'full_name',
            'phone',
            'city',
            'state',
            'country',
            'postal_code',
            'status',
            'source',
            'lists',
            'tags',
            'created_at',
            'updated_at'
        ];

        foreach ($standardFields as $field) {
            $value = self::stringifyPlaceholderValue($contact[$field] ?? '');
            $template = str_replace('{' . $field . '}', $value, $template);
        }

        $stageValue = self::stringifyPlaceholderValue(
            $contact['stage']
                ?? ($contact['custom_fields_map'][SystemFieldRegistry::FIELD_STAGE] ?? '')
        );
        $template = str_replace('{stage}', $stageValue, $template);
        $template = str_replace('{' . SystemFieldRegistry::FIELD_STAGE . '}', $stageValue, $template);

        // Replace custom fields (using slug directly, e.g., {utm_source})
        if (!empty($contact['custom_fields']) && is_array($contact['custom_fields'])) {
            foreach ($contact['custom_fields'] as $cf) {
                $key = $cf['key'] ?? '';
                $value = $cf['value'] ?? '';

                if (!empty($key)) {
                    $template = str_replace('{' . $key . '}', self::stringifyPlaceholderValue($value), $template);
                }
            }
        }

        // Replace system placeholders
        $template = self::replaceSystemPlaceholders($template);

        // Clean up any remaining unmatched placeholders
        $template = preg_replace('/\{[a-zA-Z0-9_]+\}/', '', $template);

        return trim($template);
    }

    private static function replaceRichPlaceholders(string $template, array $contact, array $options = []): string
    {
        if (strpos($template, self::CONTACT_SUMMARY_PLACEHOLDER['key']) === false) {
            return $template;
        }

        $replacement = !empty($options['allow_rich_blocks'])
            ? self::renderContactSummaryHtml($contact)
            : '';

        return str_replace(self::CONTACT_SUMMARY_PLACEHOLDER['key'], $replacement, $template);
    }

    private static function renderContactSummaryHtml(array $contact): string
    {
        $sections = self::buildContactSummarySections($contact);

        if (empty($sections)) {
            return '<div style="margin:16px 0;padding:18px 20px;border:1px solid #e2e8f0;border-radius:16px;background:#ffffff;color:#334155;font-family:Arial,sans-serif;font-size:14px;line-height:1.6;">No filled contact details are available for this record yet.</div>';
        }

        $html = '<div style="margin:16px 0;padding:20px;border:1px solid #e2e8f0;border-radius:16px;background:#ffffff;font-family:Arial,sans-serif;color:#0f172a;">';
        $html .= '<div style="margin:0 0 18px;font-size:12px;font-weight:700;letter-spacing:0.08em;text-transform:uppercase;color:#64748b;">Contact Summary</div>';

        foreach ($sections as $section) {
            $rows = $section['rows'] ?? [];
            $blocks = $section['blocks'] ?? [];
            if (empty($rows) && empty($blocks)) {
                continue;
            }

            $html .= '<div style="margin:0 0 18px;">';
            $html .= '<div style="margin:0 0 8px;font-size:12px;font-weight:700;letter-spacing:0.08em;text-transform:uppercase;color:#64748b;">' . esc_html((string) ($section['title'] ?? '')) . '</div>';

            if (!empty($rows)) {
                if (!empty($section['compact'])) {
                    foreach ($rows as $row) {
                        $valueHtml = (string) ($row['valueHtml'] ?? '');
                        if ($valueHtml === '') {
                            continue;
                        }

                        $html .= '<div style="margin:0 0 4px;font-size:12px;line-height:1.6;color:#475569;">';
                        $html .= '<strong style="font-weight:600;color:#64748b;">' . esc_html((string) ($row['label'] ?? '')) . ':</strong> ' . $valueHtml;
                        $html .= '</div>';
                    }
                } else {
                    $html .= '<table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="width:100%;border-collapse:collapse;">';

                    foreach ($rows as $row) {
                        $valueHtml = (string) ($row['valueHtml'] ?? '');
                        if ($valueHtml === '') {
                            continue;
                        }

                        $html .= '<tr>';
                        $html .= '<td valign="top" style="width:170px;padding:5px 12px 5px 0;font-size:13px;font-weight:600;line-height:1.6;color:#64748b;">' . esc_html((string) ($row['label'] ?? '')) . '</td>';
                        $html .= '<td valign="top" style="padding:5px 0;font-size:14px;line-height:1.7;color:#0f172a;">' . $valueHtml . '</td>';
                        $html .= '</tr>';
                    }

                    $html .= '</table>';
                }
            }

            if (!empty($blocks)) {
                foreach ($blocks as $block) {
                    $json = (string) ($block['json'] ?? '');
                    if ($json === '') {
                        continue;
                    }

                    $label = (string) ($block['label'] ?? 'Data');
                    $html .= '<div style="margin:10px 0 0;">';
                    $html .= '<div style="margin:0 0 6px;font-size:10px;font-weight:700;letter-spacing:0.05em;text-transform:uppercase;color:#94a3b8;">' . esc_html($label) . '</div>';
                    $html .= '<pre style="margin:0;padding:10px 12px;border:1px solid #e2e8f0;border-radius:12px;background:#f8fafc;color:#475569;font-size:11px;line-height:1.6;font-family:SFMono-Regular,Menlo,Monaco,Consolas,monospace;white-space:pre-wrap;word-break:break-word;">' . esc_html($json) . '</pre>';
                    $html .= '</div>';
                }
            }

            $html .= '</div>';
        }

        $html .= '</div>';

        return $html;
    }

    private static function buildContactSummarySections(array $contact): array
    {
        $sections = [];
        $customFields = self::getNormalizedCustomFields($contact);
        $usedCustomKeys = [];
        $standardFieldLabels = self::getStandardFieldPlaceholders();
        $technicalBlocks = [];

        $contactRows = self::buildSummaryRows(
            $contact,
            [
                'full_name' => $standardFieldLabels['full_name'] ?? 'Full Name',
                'email' => $standardFieldLabels['email'] ?? 'Email',
                'first_name' => $standardFieldLabels['first_name'] ?? 'First Name',
                'last_name' => $standardFieldLabels['last_name'] ?? 'Last Name',
                'phone' => $standardFieldLabels['phone'] ?? 'Phone',
                'company' => $standardFieldLabels['company'] ?? 'Company',
                'job_title' => $standardFieldLabels['job_title'] ?? 'Job Title',
                'timezone' => $standardFieldLabels['timezone'] ?? 'Timezone',
                'address_line_1' => $standardFieldLabels['address_line_1'] ?? 'Address Line 1',
                'address_line_2' => $standardFieldLabels['address_line_2'] ?? 'Address Line 2',
                'city' => $standardFieldLabels['city'] ?? 'City',
                'state' => $standardFieldLabels['state'] ?? 'State',
                'country' => $standardFieldLabels['country'] ?? 'Country',
                'postal_code' => $standardFieldLabels['postal_code'] ?? 'Postal Code',
                'date_of_birth' => $standardFieldLabels['date_of_birth'] ?? 'Date of Birth',
            ],
            [
                'skip_name_parts_when_full_name_present' => true,
            ]
        );

        if (!empty($contactRows)) {
            $sections[] = [
                'title' => 'Contact',
                'rows' => $contactRows,
            ];
        }

        $crmStage = $contact['stage'] ?? ($contact['custom_fields_map'][SystemFieldRegistry::FIELD_STAGE] ?? '');
        if (self::hasMeaningfulValue($crmStage)) {
            $usedCustomKeys[SystemFieldRegistry::FIELD_STAGE] = true;
        }

        $crmRows = self::buildSummaryRows([
            'id' => $contact['id'] ?? '',
            'stage' => $crmStage,
            'status' => $contact['status'] ?? '',
            'source' => $contact['source'] ?? '',
            'lists' => $contact['lists'] ?? [],
            'tags' => $contact['tags'] ?? [],
            'created_at' => $contact['created_at'] ?? '',
            'updated_at' => $contact['updated_at'] ?? '',
        ], [
            'id' => 'Contact ID',
            'stage' => 'Stage',
            'status' => 'Status',
            'source' => 'Source',
            'lists' => 'Lists',
            'tags' => 'Tags',
            'created_at' => 'Created At',
            'updated_at' => 'Updated At',
        ]);

        $crmExtraRows = [];
        $visitorRows = self::buildPrimaryVisitorRows($customFields, $usedCustomKeys);
        $groupedCustomSections = [
            'Tracking' => [],
            'Ads' => [],
            'Custom Fields' => [],
        ];

        foreach ($customFields as $slug => $field) {
            if (isset($usedCustomKeys[$slug]) || self::shouldExcludeFromContactSummary($slug)) {
                continue;
            }

            $value = $field['value'] ?? null;
            if (!self::hasMeaningfulValue($value)) {
                continue;
            }

            if (self::shouldRenderAsJsonBlock($slug, $value)) {
                $json = self::formatJsonCodeBlock($value);
                if ($json !== '') {
                    $technicalBlocks[] = [
                        'label' => (string) ($field['label'] ?? self::humanizeFieldKey($slug)),
                        'json' => $json,
                    ];
                    $usedCustomKeys[$slug] = true;
                }
                continue;
            }

            $sectionTitle = match ((string) ($field['group'] ?? 'Custom Fields')) {
                'UTM Tracking' => 'Tracking',
                'Visitor Metadata' => 'Visitor Info',
                'Ads Metadata' => 'Ads',
                'CRM Fields' => 'CRM',
                default => 'Custom Fields',
            };

            if ($sectionTitle === 'CRM') {
                $crmExtraRows[] = [
                    'label' => (string) ($field['label'] ?? self::humanizeFieldKey($slug)),
                    'valueHtml' => self::formatSummaryValueHtml($value, $slug, $field),
                ];
                $usedCustomKeys[$slug] = true;
                continue;
            }

            if ($sectionTitle === 'Visitor Info') {
                $visitorRows[] = [
                    'label' => (string) ($field['label'] ?? self::humanizeFieldKey($slug)),
                    'valueHtml' => self::formatSummaryValueHtml($value, $slug, $field),
                ];
                $usedCustomKeys[$slug] = true;
                continue;
            }

            $groupedCustomSections[$sectionTitle][] = [
                'label' => (string) ($field['label'] ?? self::humanizeFieldKey($slug)),
                'valueHtml' => self::formatSummaryValueHtml($value, $slug, $field),
            ];
            $usedCustomKeys[$slug] = true;
        }

        $crmRows = array_values(array_filter(array_merge($crmRows, $crmExtraRows), static function ($row) {
            return ($row['valueHtml'] ?? '') !== '';
        }));

        if (!empty($crmRows)) {
            $sections[] = [
                'title' => 'CRM',
                'rows' => $crmRows,
            ];
        }

        if (!empty($visitorRows)) {
            $sections[] = [
                'title' => 'Visitor Info',
                'rows' => $visitorRows,
                'compact' => true,
            ];
        }

        foreach (['Tracking', 'Ads', 'Custom Fields'] as $title) {
            if (empty($groupedCustomSections[$title])) {
                continue;
            }

            $sections[] = [
                'title' => $title,
                'rows' => $groupedCustomSections[$title],
                'compact' => $title === 'Tracking',
            ];
        }

        if (!empty($technicalBlocks)) {
            $sections[] = [
                'title' => 'Technical Details',
                'blocks' => $technicalBlocks,
            ];
        }

        return array_values(array_filter($sections, static function ($section) {
            return !empty($section['rows']) || !empty($section['blocks']);
        }));
    }

    private static function buildSummaryRows(array $source, array $fieldLabels, array $options = []): array
    {
        $rows = [];
        $skipNameParts = !empty($options['skip_name_parts_when_full_name_present'])
            && self::hasMeaningfulValue($source['full_name'] ?? '');

        foreach ($fieldLabels as $key => $label) {
            if ($skipNameParts && in_array($key, ['first_name', 'last_name'], true)) {
                continue;
            }

            if (self::shouldExcludeSummaryRowKey((string) $key)) {
                continue;
            }

            $value = $source[$key] ?? null;
            if (!self::hasMeaningfulValue($value)) {
                continue;
            }

            $rows[] = [
                'label' => $label,
                'valueHtml' => self::formatSummaryValueHtml($value, (string) $key),
            ];
        }

        return array_values(array_filter($rows, static function ($row) {
            return ($row['valueHtml'] ?? '') !== '';
        }));
    }

    private static function buildPrimaryVisitorRows(array $customFields, array &$usedCustomKeys): array
    {
        $rows = [];

        $deviceParts = [];
        $deviceBrand = $customFields['plover_crm_device_brand']['value'] ?? null;
        $deviceType = $customFields['plover_crm_device_type']['value'] ?? null;

        if (self::hasMeaningfulValue($deviceBrand)) {
            $deviceParts[] = trim((string) $deviceBrand);
            $usedCustomKeys['plover_crm_device_brand'] = true;
        }

        if (self::hasMeaningfulValue($deviceType)) {
            $deviceParts[] = self::formatDeviceTypeValue((string) $deviceType);
            $usedCustomKeys['plover_crm_device_type'] = true;
        }

        if (!empty($deviceParts)) {
            $rows[] = [
                'label' => 'Device',
                'valueHtml' => esc_html(implode(' ', $deviceParts)),
            ];
        }

        foreach (self::CONTACT_SUMMARY_PRIMARY_VISITOR_KEYS as $slug => $label) {
            $field = $customFields[$slug] ?? null;
            if (!$field) {
                continue;
            }

            $value = $field['value'] ?? null;
            if (!self::hasMeaningfulValue($value)) {
                continue;
            }

            $rows[] = [
                'label' => $label,
                'valueHtml' => self::formatSummaryValueHtml($value, $slug, (array) $field),
            ];
            $usedCustomKeys[$slug] = true;
        }

        return array_values(array_filter($rows, static function ($row) {
            return ($row['valueHtml'] ?? '') !== '';
        }));
    }

    private static function shouldExcludeFromContactSummary(string $slug): bool
    {
        return in_array($slug, self::CONTACT_SUMMARY_EXCLUDED_KEYS, true);
    }

    private static function shouldExcludeSummaryRowKey(string $key): bool
    {
        return in_array($key, self::CONTACT_SUMMARY_EXCLUDED_ROW_KEYS, true);
    }

    private static function shouldRenderAsJsonBlock(string $slug, $value): bool
    {
        if (in_array($slug, self::CONTACT_SUMMARY_JSON_BLOCK_KEYS, true)) {
            return true;
        }

        if (!SystemFieldRegistry::isSystemSlug($slug) || !is_string($value)) {
            return false;
        }

        return is_array(self::decodeJsonValue($value));
    }

    private static function formatJsonCodeBlock($value): string
    {
        if (!self::hasMeaningfulValue($value)) {
            return '';
        }

        $normalized = $value;
        if (is_string($value)) {
            $decoded = self::decodeJsonValue($value);
            $normalized = is_array($decoded) ? $decoded : $value;
        }

        if (is_array($normalized)) {
            $json = wp_json_encode($normalized, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
            return is_string($json) ? trim($json) : '';
        }

        if (is_object($normalized)) {
            $json = wp_json_encode($normalized, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
            return is_string($json) ? trim($json) : '';
        }

        return trim((string) $normalized);
    }

    private static function formatDeviceTypeValue(string $value): string
    {
        $value = trim($value);
        if ($value === '') {
            return '';
        }

        return ucwords(str_replace(['_', '-'], ' ', strtolower($value)));
    }

    private static function getNormalizedCustomFields(array $contact): array
    {
        $definitions = self::getCustomFieldDefinitionsBySlug();
        $normalized = [];

        foreach ((array) ($contact['custom_fields'] ?? []) as $field) {
            $key = (string) ($field['key'] ?? '');
            if ($key === '') {
                continue;
            }

            $definition = (array) ($definitions[$key] ?? []);
            $normalized[$key] = [
                'key' => $key,
                'label' => (string) ($field['label'] ?? ($definition['label'] ?? self::humanizeFieldKey($key))),
                'value' => $field['value'] ?? '',
                'group' => self::resolveCustomFieldPlaceholderGroup($definition),
                'type' => (string) ($definition['type'] ?? ''),
            ];
        }

        foreach ((array) ($contact['custom_fields_map'] ?? []) as $key => $value) {
            $key = (string) $key;
            if ($key === '' || isset($normalized[$key])) {
                continue;
            }

            $definition = (array) ($definitions[$key] ?? []);
            $normalized[$key] = [
                'key' => $key,
                'label' => (string) ($definition['label'] ?? self::humanizeFieldKey($key)),
                'value' => $value,
                'group' => self::resolveCustomFieldPlaceholderGroup($definition),
                'type' => (string) ($definition['type'] ?? ''),
            ];
        }

        return $normalized;
    }

    private static function getCustomFieldDefinitionsBySlug(): array
    {
        $crm = Plugin::getInstance()->getContainer()->get('crm');

        if (!$crm || !$crm->isAvailable()) {
            return [];
        }

        $definitions = $crm->getAllCustomFields();
        if (!is_array($definitions)) {
            return [];
        }

        return array_column($definitions, null, 'slug');
    }

    private static function formatSummaryValueHtml($value, string $key = '', array $field = []): string
    {
        if (!self::hasMeaningfulValue($value)) {
            return '';
        }

        if (is_bool($value)) {
            return esc_html($value ? 'Yes' : 'No');
        }

        if (is_array($value)) {
            $values = array_values(array_filter(array_map([self::class, 'stringifyArrayItem'], $value), static function ($item) {
                return $item !== '';
            }));

            return esc_html(implode(', ', $values));
        }

        if (is_object($value)) {
            return esc_html(self::stringifyArrayItem($value));
        }

        $stringValue = trim((string) $value);
        if ($stringValue === '') {
            return '';
        }

        if (filter_var($stringValue, FILTER_VALIDATE_EMAIL)) {
            return '<a href="mailto:' . esc_attr($stringValue) . '" style="color:#2563eb;text-decoration:none;">' . esc_html($stringValue) . '</a>';
        }

        if (in_array($key, ['created_at', 'updated_at'], true)) {
            return esc_html(self::formatDateValue($stringValue, true));
        }

        if (in_array($key, ['plover_crm_last_seen_at', 'plover_crm_landing_datetime_first_visit'], true)) {
            return esc_html(self::formatDateValue($stringValue, true));
        }

        if (($field['type'] ?? '') === 'date') {
            return esc_html(self::formatDateValue($stringValue, false));
        }

        if (in_array(($field['type'] ?? ''), ['date_time', 'datetime'], true)) {
            return esc_html(self::formatDateValue($stringValue, true));
        }

        if (filter_var($stringValue, FILTER_VALIDATE_URL)) {
            return '<a href="' . esc_url($stringValue) . '" style="color:#2563eb;text-decoration:none;">' . esc_html($stringValue) . '</a>';
        }

        $decoded = self::decodeJsonValue($stringValue);
        if (is_array($decoded)) {
            return self::formatStructuredArrayHtml($decoded);
        }

        return nl2br(esc_html($stringValue));
    }

    private static function formatStructuredArrayHtml(array $value): string
    {
        if (self::isListArray($value)) {
            $values = array_values(array_filter(array_map([self::class, 'stringifyArrayItem'], $value), static function ($item) {
                return $item !== '';
            }));

            return esc_html(implode(', ', $values));
        }

        $entries = self::flattenStructuredEntries($value);
        if (empty($entries)) {
            return '';
        }

        $lines = [];
        foreach ($entries as $entry) {
            $nestedValue = (string) ($entry['valueHtml'] ?? '');
            if ($nestedValue === '') {
                continue;
            }

            $lines[] = '<div><strong>' . esc_html((string) ($entry['label'] ?? '')) . ':</strong> ' . $nestedValue . '</div>';
        }

        return implode('', $lines);
    }

    private static function flattenStructuredEntries(array $value, string $prefix = ''): array
    {
        $entries = [];

        foreach ($value as $key => $item) {
            if (!self::hasMeaningfulValue($item)) {
                continue;
            }

            $labelPart = self::humanizeFieldKey((string) $key);
            $label = trim($prefix === '' ? $labelPart : $prefix . ' ' . $labelPart);

            if (is_array($item) && !self::isListArray($item)) {
                $entries = array_merge($entries, self::flattenStructuredEntries($item, $label));
                continue;
            }

            $valueHtml = self::formatSummaryValueHtml($item);
            if ($valueHtml === '') {
                continue;
            }

            $entries[] = [
                'label' => $label,
                'valueHtml' => $valueHtml,
            ];
        }

        return $entries;
    }

    private static function decodeJsonValue(string $value): ?array
    {
        $decoded = json_decode($value, true);
        return json_last_error() === JSON_ERROR_NONE && is_array($decoded)
            ? $decoded
            : null;
    }

    private static function formatDateValue(string $value, bool $includeTime): string
    {
        $timestamp = strtotime($value);
        if ($timestamp === false) {
            return $value;
        }

        return wp_date($includeTime ? 'j M Y g:i A' : 'j M Y', $timestamp);
    }

    private static function hasMeaningfulValue($value): bool
    {
        if ($value === null) {
            return false;
        }

        if (is_bool($value)) {
            return true;
        }

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

        if (is_numeric($value)) {
            return true;
        }

        if (is_array($value)) {
            foreach ($value as $item) {
                if (self::hasMeaningfulValue($item)) {
                    return true;
                }
            }

            return false;
        }

        if (is_object($value)) {
            return true;
        }

        return false;
    }

    private static function isListArray(array $value): bool
    {
        if ($value === []) {
            return true;
        }

        return array_keys($value) === range(0, count($value) - 1);
    }

    private static function humanizeFieldKey(string $key): string
    {
        $normalized = str_replace(['plover_crm_', '_', '-'], ['', ' ', ' '], $key);
        return ucwords(trim($normalized));
    }

    /**
     * Normalize placeholder values for string replacement.
     *
     * @param mixed $value
     * @return string
     */
    private static function stringifyPlaceholderValue($value): string
    {
        if ($value === null) {
            return '';
        }

        if (is_bool($value)) {
            return $value ? 'Yes' : 'No';
        }

        if (is_array($value)) {
            $values = array_map([self::class, 'stringifyArrayItem'], $value);
            $values = array_filter($values, static function ($item) {
                return $item !== '';
            });

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

        if (is_object($value)) {
            return self::stringifyArrayItem($value);
        }

        return (string) $value;
    }

    /**
     * Normalize array and object items into readable placeholder strings.
     *
     * @param mixed $item
     * @return string
     */
    private static function stringifyArrayItem($item): string
    {
        if ($item === null) {
            return '';
        }

        if (is_bool($item)) {
            return $item ? 'Yes' : 'No';
        }

        if (is_array($item)) {
            foreach (['title', 'label', 'name', 'value', 'slug'] as $key) {
                if (isset($item[$key]) && !is_array($item[$key]) && !is_object($item[$key])) {
                    return (string) $item[$key];
                }
            }

            return '';
        }

        if (is_object($item)) {
            foreach (['title', 'label', 'name', 'value', 'slug'] as $key) {
                if (isset($item->{$key}) && !is_array($item->{$key}) && !is_object($item->{$key})) {
                    return (string) $item->{$key};
                }
            }

            return '';
        }

        return (string) $item;
    }

    /**
     * Replace system placeholders
     * 
     * @param string $template
     * @return string
     */
    private static function replaceSystemPlaceholders(string $template): string
    {
        $site_url = get_site_url();
        $domain = preg_replace('#^https?://#', '', rtrim($site_url, '/'));

        $replacements = [
            '{workspace}' => $domain,
            '{site_url}' => $site_url,
            '{site_name}' => get_bloginfo('name'),
            '{date}' => wp_date('j M Y'),
            '{time}' => wp_date('g:i A'),
            '{datetime}' => wp_date('j M Y g:i A'),
        ];

        return str_replace(array_keys($replacements), array_values($replacements), $template);
    }

    /**
     * Get placeholder preview with sample data
     * 
     * @param string $template
     * @return string
     */
    public static function preview(string $template): string
    {
        $sampleContact = [
            'id' => 123,
            'email' => 'john.doe@example.com',
            'first_name' => 'John',
            'last_name' => 'Doe',
            'full_name' => 'John Doe',
            'phone' => '+1 234 567 8900',
            'city' => 'New York',
            'state' => 'NY',
            'country' => 'United States',
            'postal_code' => '10001',
            'status' => 'subscribed',
            'source' => 'Webhook',
            'lists' => [
                ['id' => 1, 'title' => 'Sales Leads'],
            ],
            'tags' => [
                ['id' => 2, 'title' => 'Hot Lead'],
            ],
            'created_at' => wp_date('Y-m-d H:i:s'),
            'updated_at' => wp_date('Y-m-d H:i:s'),
            'custom_fields' => [
                [
                    'label' => 'Stage',
                    'key' => SystemFieldRegistry::FIELD_STAGE,
                    'value' => 'Qualified',
                ],
                [
                    'label' => 'UTM Source',
                    'key' => 'plover_crm_utm_source',
                    'value' => 'Facebook',
                ],
                [
                    'label' => 'Device Type',
                    'key' => 'plover_crm_device_type',
                    'value' => 'Mobile',
                ],
                [
                    'label' => 'Browser Name',
                    'key' => 'plover_crm_browser_name',
                    'value' => 'Safari',
                ],
                [
                    'label' => 'IP info',
                    'key' => 'plover_crm_ip_info',
                    'value' => wp_json_encode([
                        'ip' => '203.0.113.7',
                        'city' => 'New York',
                        'region' => 'New York',
                        'country' => 'United States',
                        'timezone' => ['id' => 'America/New_York'],
                        'connection' => ['isp' => 'Example ISP'],
                    ]),
                ],
                [
                    'label' => 'Plan',
                    'key' => 'plan_name',
                    'value' => 'Growth',
                ],
            ],
            'custom_fields_map' => [
                SystemFieldRegistry::FIELD_STAGE => 'Qualified',
                'plover_crm_utm_source' => 'Facebook',
                'plover_crm_device_type' => 'Mobile',
                'plover_crm_browser_name' => 'Safari',
                'plover_crm_ip_info' => wp_json_encode([
                    'ip' => '203.0.113.7',
                    'city' => 'New York',
                    'region' => 'New York',
                    'country' => 'United States',
                    'timezone' => ['id' => 'America/New_York'],
                    'connection' => ['isp' => 'Example ISP'],
                ]),
                'plan_name' => 'Growth',
            ],
        ];

        return self::parse($template, $sampleContact, [
            'allow_rich_blocks' => true,
        ]);
    }
}
