<?php

namespace PloverCRM\Modules\Automations\Services;

/**
 * Validates automation definitions before save and execution.
 */
class DefinitionValidator
{
    private const SUPPORTED_EVENTS = [
        'contact_created_after_enrichment',
        'contact_stage_changed',
    ];

    private const SUPPORTED_CONDITIONS = [
        'contact.source' => ['equals', 'not_equals'],
        'contact.list_ids' => ['contains_any', 'contains_none'],
        'context.stage.to' => ['equals', 'not_equals'],
        'context.stage.from' => ['equals', 'not_equals'],
    ];

    public static function validate(array $definition): array
    {
        $errors = [];
        $triggerEvent = $definition['trigger']['event'] ?? '';

        if (!in_array($triggerEvent, self::SUPPORTED_EVENTS, true)) {
            $errors[] = 'Unsupported automation trigger.';
        }

        $conditions = $definition['conditions'] ?? [];
        if (!is_array($conditions)) {
            $errors[] = 'Automation conditions must be an array.';
        } else {
            foreach ($conditions as $condition) {
                $field = $condition['field'] ?? '';
                $operator = $condition['operator'] ?? '';

                if (!isset(self::SUPPORTED_CONDITIONS[$field])) {
                    $errors[] = 'Unsupported condition field: ' . $field;
                    continue;
                }

                if (!in_array($operator, self::SUPPORTED_CONDITIONS[$field], true)) {
                    $errors[] = 'Unsupported operator for ' . $field . '.';
                }
            }

            if ($triggerEvent === 'contact_stage_changed' && !self::hasSelectedTargetStage($conditions)) {
                $errors[] = 'A target stage is required for stage-based automations.';
            }
        }

        $actions = $definition['actions'] ?? [];
        if (!is_array($actions) || empty($actions)) {
            $errors[] = 'At least one action is required.';
        } else {
            foreach ($actions as $action) {
                $type = $action['type'] ?? '';
                $config = $action['config'] ?? [];

                if ($type === 'send_internal_email') {
                    $recipients = array_filter((array) ($config['to'] ?? []), function ($email) {
                        return is_email($email);
                    });

                    if (empty($recipients)) {
                        $errors[] = 'At least one valid internal email recipient is required.';
                    }

                    if (empty(trim((string) ($config['subject'] ?? '')))) {
                        $errors[] = 'Email subject is required.';
                    }

                    if (empty(trim(wp_strip_all_tags((string) ($config['body'] ?? ''))))) {
                        $errors[] = 'Email body is required.';
                    }

                    continue;
                }

                if ($type === 'send_google_ads_conversion') {
                    if (empty(absint($config['connection_id'] ?? 0))) {
                        $errors[] = 'A Google Ads connection is required.';
                    }

                    continue;
                }

                if ($type === 'send_meta_capi_event') {
                    if (empty(absint($config['connection_id'] ?? 0))) {
                        $errors[] = 'A Meta CAPI connection is required.';
                    }

                    if (empty(trim((string) ($config['event_name'] ?? '')))) {
                        $errors[] = 'A Meta event name is required.';
                    }

                    if (($config['event_name'] ?? '') === 'Custom' && empty(trim((string) ($config['custom_event_name'] ?? '')))) {
                        $errors[] = 'A custom Meta event name is required when using the Custom event type.';
                    }

                    continue;
                }

                $errors[] = 'Unsupported action type: ' . $type;
            }
        }

        return [
            'valid' => empty($errors),
            'errors' => $errors,
        ];
    }

    private static function hasSelectedTargetStage(array $conditions): bool
    {
        foreach ($conditions as $condition) {
            if (
                ($condition['field'] ?? '') === 'context.stage.to' &&
                ($condition['operator'] ?? '') === 'equals' &&
                trim((string) ($condition['value'] ?? '')) !== ''
            ) {
                return true;
            }
        }

        return false;
    }
}
