<?php

declare(strict_types=1);

namespace ImovelZapAi\Analytics\Application\Actions;

use Illuminate\Support\Facades\Event;
use ImovelZapAi\Analytics\Domain\Enums\AlertSeverity;
use ImovelZapAi\Analytics\Domain\Enums\AlertStatus;
use ImovelZapAi\Analytics\Domain\Enums\AnalyticsEventKey;
use ImovelZapAi\Analytics\Domain\Events\AnalyticsAlertTriggered;
use ImovelZapAi\Analytics\Infrastructure\Persistence\Eloquent\AnalyticsAlertModel;
use ImovelZapAi\Analytics\Infrastructure\Persistence\Eloquent\AnalyticsFactModel;

final class EvaluateAnalyticsAlertsAction
{
    public function execute(string $tenantId): int
    {
        $created = 0;
        $created += $this->evaluateSignaturePending($tenantId);
        $created += $this->evaluateOpportunityInactive($tenantId);

        return $created;
    }

    private function evaluateSignaturePending(string $tenantId): int
    {
        $thresholdDays = (int) config('analytics.signature_pending_days', 3);
        $cutoff = now()->subDays($thresholdDays);
        $created = 0;

        $requested = AnalyticsFactModel::query()
            ->where('tenant_id', $tenantId)
            ->where('event_key', AnalyticsEventKey::SignatureRequested->value)
            ->where('occurred_at', '<=', $cutoff)
            ->where('entity_type', 'signature_request')
            ->get();

        foreach ($requested as $fact) {
            $completed = AnalyticsFactModel::query()
                ->where('tenant_id', $tenantId)
                ->where('event_key', AnalyticsEventKey::SignatureCompleted->value)
                ->where('entity_type', 'signature_request')
                ->where('entity_id', $fact->entity_id)
                ->exists();

            if ($completed) {
                continue;
            }

            if ($this->alertExists($tenantId, 'signature.pending', 'signature_request', (string) $fact->entity_id)) {
                continue;
            }

            $alert = AnalyticsAlertModel::query()->create([
                'tenant_id' => $tenantId,
                'alert_key' => 'signature.pending',
                'title' => 'Assinatura pendente',
                'body' => 'Assinatura solicitada há mais de '.$thresholdDays.' dias sem conclusão.',
                'severity' => AlertSeverity::Warning->value,
                'status' => AlertStatus::Open->value,
                'entity_type' => 'signature_request',
                'entity_id' => $fact->entity_id,
                'meta' => ['requested_at' => $fact->occurred_at?->toIso8601String()],
                'triggered_at' => now(),
            ]);

            Event::dispatch(AnalyticsAlertTriggered::fromModel($alert));
            $created++;
        }

        return $created;
    }

    private function evaluateOpportunityInactive(string $tenantId): int
    {
        $thresholdHours = (int) config('analytics.opportunity_inactive_hours', 24);
        $cutoff = now()->subHours($thresholdHours);
        $created = 0;

        $deals = AnalyticsFactModel::query()
            ->where('tenant_id', $tenantId)
            ->where('event_key', AnalyticsEventKey::DealCreated->value)
            ->where('occurred_at', '<=', $cutoff)
            ->where('entity_type', 'deal')
            ->get();

        foreach ($deals as $fact) {
            $hasActivity = AnalyticsFactModel::query()
                ->where('tenant_id', $tenantId)
                ->where('entity_type', 'deal')
                ->where('entity_id', $fact->entity_id)
                ->where('occurred_at', '>', $fact->occurred_at)
                ->exists();

            if ($hasActivity) {
                continue;
            }

            if ($this->alertExists($tenantId, 'opportunity.inactive', 'deal', (string) $fact->entity_id)) {
                continue;
            }

            $alert = AnalyticsAlertModel::query()->create([
                'tenant_id' => $tenantId,
                'alert_key' => 'opportunity.inactive',
                'title' => 'Oportunidade sem atividade',
                'body' => 'Oportunidade sem movimentação há mais de '.$thresholdHours.' horas.',
                'severity' => AlertSeverity::Info->value,
                'status' => AlertStatus::Open->value,
                'entity_type' => 'deal',
                'entity_id' => $fact->entity_id,
                'meta' => ['created_at' => $fact->occurred_at?->toIso8601String()],
                'triggered_at' => now(),
            ]);

            Event::dispatch(AnalyticsAlertTriggered::fromModel($alert));
            $created++;
        }

        return $created;
    }

    private function alertExists(string $tenantId, string $alertKey, string $entityType, string $entityId): bool
    {
        return AnalyticsAlertModel::query()
            ->where('tenant_id', $tenantId)
            ->where('alert_key', $alertKey)
            ->where('entity_type', $entityType)
            ->where('entity_id', $entityId)
            ->whereIn('status', [AlertStatus::Open->value, AlertStatus::Acked->value])
            ->exists();
    }
}
