<?php

namespace App\Actions\Communications;

use App\Enum\Contact\TemplateTriggerType;
use App\Models\Contact\ContactTemplateTrigger;
use App\ValueObjects\Communications\DispatchRequest;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;

class EvaluateContactTriggersAction
{
    public function __construct(
        protected DispatchContactMessageAction $dispatch,
    ) {}

    public function __invoke(Model $subject, TemplateTriggerType $type, array $context = []): void
    {
        $modelType = get_class($subject);

        $triggers = ContactTemplateTrigger::query()
            ->with(['template' => fn ($q) => $q->where('is_active', true)])
            ->where('trigger_type', $type->value)
            ->where('is_active', true)
            ->where(function ($q) use ($modelType) {
                $q->whereNull('model_type')->orWhere('model_type', $modelType);
            })
            ->get();

        foreach ($triggers as $trigger) {
            if (!$trigger->template) {
                continue;
            }
            if (!$trigger->matchesConditions($context)) {
                continue;
            }
            if (!$trigger->template->allow_automatic_send) {
                continue;
            }

            try {
                ($this->dispatch)(new DispatchRequest(
                    template: $trigger->template,
                    messageable: $subject,
                    origin: $type->toOrigin(),
                    originDetail: array_merge(
                        $context,
                        [
                            'trigger_id' => $trigger->id,
                            'dedupe_window_minutes' => $trigger->dedupe_window_minutes,
                        ],
                    ),
                ));
            } catch (\Throwable $e) {
                Log::error('Contact trigger dispatch failed', [
                    'trigger_id' => $trigger->id,
                    'template_id' => $trigger->contact_template_id,
                    'error' => $e->getMessage(),
                ]);
            }
        }
    }
}
