<?php

declare(strict_types=1);

namespace ImovelZapAi\Proposals\Application\Actions;

use ImovelZapAi\Proposals\Application\Services\ProposalHistoryWriter;
use ImovelZapAi\Proposals\Application\Services\ProposalShareTokenService;
use ImovelZapAi\Proposals\Domain\Enums\ProposalHistoryEvent;
use ImovelZapAi\Proposals\Domain\Events\ProposalViewed;
use ImovelZapAi\Proposals\Infrastructure\Persistence\Eloquent\ProposalViewModel;

final class RecordProposalViewAction
{
    public function __construct(
        private readonly ProposalShareTokenService $tokens,
        private readonly ProposalHistoryWriter $history,
    ) {}

    /** @return array{proposal: \ImovelZapAi\Proposals\Infrastructure\Persistence\Eloquent\ProposalModel, view: ProposalViewModel} */
    public function execute(string $plainToken, ?string $ip = null, ?string $userAgent = null): array
    {
        $resolved = $this->tokens->resolve($plainToken);
        $proposal = $resolved['proposal'];
        $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 = ProposalViewModel::query()->create([
            'tenant_id' => $proposal->tenant_id,
            'proposal_id' => $proposal->id,
            'proposal_share_id' => $share->id,
            'proposal_version_id' => $share->proposal_version_id,
            'ip' => $ip,
            'user_agent' => $userAgent ? substr($userAgent, 0, 512) : null,
            'device' => $device,
            'started_at' => now(),
        ]);

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

        $recent = \ImovelZapAi\Proposals\Infrastructure\Persistence\Eloquent\ProposalHistoryModel::query()
            ->where('proposal_id', $proposal->id)
            ->where('event', ProposalHistoryEvent::Viewed)
            ->where('created_at', '>=', now()->subHour())
            ->exists();

        if (! $recent) {
            $this->history->write(
                $proposal->tenant_id,
                $proposal->id,
                ProposalHistoryEvent::Viewed,
                actorType: 'client',
                payload: ['device' => $device, 'ip' => $ip],
                message: 'Cliente abriu a proposta.',
            );
            ProposalViewed::dispatch($proposal->tenant_id, $proposal->id);
        }

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