<?php

declare(strict_types=1);

namespace ImovelZapAi\Documents\Application\Actions;

use ImovelZapAi\Documents\Application\Services\DocumentHistoryWriter;
use ImovelZapAi\Documents\Application\Services\DocumentShareTokenService;
use ImovelZapAi\Documents\Domain\Enums\DocumentHistoryEvent;
use ImovelZapAi\Documents\Domain\Events\DocumentViewed;
use ImovelZapAi\Documents\Infrastructure\Persistence\Eloquent\BusinessDocumentModel;
use ImovelZapAi\Documents\Infrastructure\Persistence\Eloquent\DocumentHistoryModel;
use ImovelZapAi\Documents\Infrastructure\Persistence\Eloquent\DocumentViewModel;

final class RecordDocumentViewAction
{
    public function __construct(
        private readonly DocumentShareTokenService $tokens,
        private readonly DocumentHistoryWriter $history,
    ) {}

    /** @return array{document: BusinessDocumentModel, view: DocumentViewModel} */
    public function execute(string $plainToken, ?string $ip = null, ?string $userAgent = null): array
    {
        $resolved = $this->tokens->resolve($plainToken);
        $document = $resolved['document'];
        $share = $resolved['share'];

        $device = 'desktop';
        $ua = strtolower((string) $userAgent);
        if (str_contains($ua, 'mobile') || str_contains($ua, 'android') || str_contains($ua, 'iphone')) {
            $device = 'mobile';
        } elseif (str_contains($ua, 'tablet') || str_contains($ua, 'ipad')) {
            $device = 'tablet';
        }

        $view = DocumentViewModel::query()->create([
            'tenant_id' => $document->tenant_id,
            'business_document_id' => $document->id,
            'document_share_id' => $share->id,
            'document_version_id' => $share->document_version_id,
            'ip' => $ip,
            'user_agent' => $userAgent ? substr($userAgent, 0, 512) : null,
            'device' => $device,
            'started_at' => now(),
        ]);

        $document->forceFill([
            'last_viewed_at' => now(),
            'view_count' => $document->view_count + 1,
        ])->save();

        $recent = DocumentHistoryModel::query()
            ->where('business_document_id', $document->id)
            ->where('event', DocumentHistoryEvent::Viewed)
            ->where('created_at', '>=', now()->subHour())
            ->exists();

        if (! $recent) {
            $this->history->write(
                $document->tenant_id,
                $document->id,
                DocumentHistoryEvent::Viewed,
                actorType: 'client',
                payload: ['device' => $device, 'ip' => $ip],
                message: 'Cliente abriu o documento.',
            );
            DocumentViewed::dispatch($document->tenant_id, $document->id);
        }

        return ['document' => $document->fresh(['currentVersion', 'comments']), 'view' => $view];
    }
}
