<?php

namespace PloverCRM\Modules\Automations\Services;

use PloverCRM\Core\Container;

/**
 * Builds normalized automation payloads from CRM events.
 */
class AutomationPayloadBuilder
{
    public static function buildContactCreatedAfterEnrichment(
        Container $container,
        int $contactId,
        $userIp,
        $userAgent,
        $currentUrl,
        $trackingContext,
        string $providerId = ''
    ): ?array {
        $crm = self::resolveCrm($container, $providerId);

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

        $contact = $crm->getContact($contactId);
        if (!$contact) {
            return null;
        }

        $contact = self::enrichContactForAutomation($crm, $contact);

        return [
            'event_name' => 'contact_created_after_enrichment',
            'occurred_at' => current_time('mysql'),
            'contact' => $contact,
            'context' => [
                'user_ip' => $userIp,
                'user_agent' => $userAgent,
                'current_url' => $currentUrl,
                'tracking' => is_array($trackingContext) ? $trackingContext : [],
            ],
        ];
    }

    public static function buildContactStageChanged(
        Container $container,
        int $contactId,
        array $contact,
        ?string $previousStage,
        ?string $currentStage,
        array $context = []
    ): ?array {
        $crm = self::resolveCrm($container);

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

        if (empty($contact)) {
            $contact = $crm->getContact($contactId);
        }

        if (!$contact) {
            return null;
        }

        $contact = self::enrichContactForAutomation($crm, $contact);

        if (!empty($currentStage)) {
            $contact['stage'] = $currentStage;
        }

        return [
            'event_name' => 'contact_stage_changed',
            'occurred_at' => current_time('mysql'),
            'contact' => $contact,
            'previous' => [
                'stage' => $previousStage,
            ],
            'changes' => [
                'stage' => [
                    'from' => $previousStage,
                    'to' => $currentStage,
                ],
            ],
            'context' => array_merge([
                'stage' => [
                    'from' => $previousStage,
                    'to' => $currentStage,
                ],
            ], $context),
        ];
    }

    private static function enrichContactForAutomation($crm, array $contact): array
    {
        $lists = $crm->getContactLists($contact);
        $tags = $crm->getContactTags($contact);
        $customFields = self::formatCustomFields($crm, $contact);
        $customFieldsMap = self::normalizeCustomFieldsMap($customFields);

        if (empty($contact['full_name'])) {
            $contact['full_name'] = trim(($contact['first_name'] ?? '') . ' ' . ($contact['last_name'] ?? ''));
        }

        $contact['lists'] = $lists;
        $contact['tags'] = $tags;
        $contact['list_ids'] = array_map('intval', array_column($lists, 'id'));
        $contact['tag_ids'] = array_map('intval', array_column($tags, 'id'));
        $contact['custom_fields'] = $customFields;
        $contact['custom_fields_map'] = $customFieldsMap;
        $contact['stage'] = $customFieldsMap['stage-plover-crm'] ?? ($contact['stage'] ?? '');

        return $contact;
    }

    private static function formatCustomFields($crm, array $contact): array
    {
        $customFields = $crm->getContactCustomFields($contact);

        if (self::isFormattedCustomFieldList($customFields)) {
            return array_values(array_filter(array_map(static function ($field) {
                $key = (string) ($field['key'] ?? '');
                if ($key === '') {
                    return null;
                }

                return [
                    'label' => (string) ($field['label'] ?? $key),
                    'key' => $key,
                    'value' => $field['value'] ?? '',
                ];
            }, $customFields)));
        }

        $definitions = $crm->getAllCustomFields();
        $definitionsBySlug = array_column($definitions, null, 'slug');
        $formatted = [];

        foreach ($customFields as $slug => $value) {
            if (!isset($definitionsBySlug[$slug])) {
                continue;
            }

            $formatted[] = [
                'label' => $definitionsBySlug[$slug]['label'],
                'key' => $slug,
                'value' => $value,
            ];
        }

        return $formatted;
    }

    private static function isFormattedCustomFieldList($customFields): bool
    {
        if (!is_array($customFields) || $customFields === []) {
            return false;
        }

        $first = reset($customFields);

        return is_array($first)
            && array_key_exists('key', $first)
            && array_key_exists('value', $first);
    }

    private static function resolveCrm(Container $container, string $providerId = '')
    {
        $crmManager = $container->get('crm');
        $crm = $crmManager;

        if ($providerId !== '' && method_exists($crmManager, 'getProviderById')) {
            $provider = $crmManager->getProviderById($providerId);
            if ($provider) {
                $crm = $provider;
            }
        }

        return $crm;
    }

    private static function normalizeCustomFieldsMap(array $customFields): array
    {
        $normalized = [];

        foreach ($customFields as $key => $field) {
            if (is_array($field) && !empty($field['key'])) {
                $normalized[$field['key']] = $field['value'] ?? '';
                continue;
            }

            if (is_string($key)) {
                $normalized[$key] = $field;
            }
        }

        return $normalized;
    }
}
