<?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
{
    /**
     * 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
    {
        $placeholders = [];

        // 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',
            ];
        }

        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): string
    {
        if (empty($template)) {
            return '';
        }

        // 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);
    }

    /**
     * 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' => [],
        ];

        return self::parse($template, $sampleContact);
    }
}
