<?php

declare(strict_types=1);

namespace ImovelZapAi\Visits\Application\Actions;

use App\Models\User;
use Illuminate\Support\Facades\DB;
use ImovelZapAi\Visits\Application\Services\VisitLogWriter;
use ImovelZapAi\Visits\Application\Services\VisitSnapshotter;
use ImovelZapAi\Visits\Domain\Enums\VisitLogEvent;
use ImovelZapAi\Visits\Domain\Enums\VisitStatus;
use ImovelZapAi\Visits\Domain\Exceptions\VisitException;
use ImovelZapAi\Visits\Infrastructure\Persistence\Eloquent\VisitModel;

final class CheckOutVisitAction
{
    public function __construct(
        private readonly VisitLogWriter $logWriter,
        private readonly VisitSnapshotter $snapshotter,
    ) {}

    public function execute(VisitModel $visit, User $actor, ?string $notes = null): VisitModel
    {
        if ($visit->status !== VisitStatus::InProgress) {
            throw VisitException::invalidState(
                $visit->status instanceof VisitStatus ? $visit->status->value : (string) $visit->status,
                'check_out',
            );
        }

        return DB::transaction(function () use ($visit, $actor, $notes): VisitModel {
            $before = $this->snapshotter->snapshot($visit);

            $visit->forceFill([
                'check_out_at' => now(),
                'check_in_notes' => $notes !== null
                    ? trim(($visit->check_in_notes ? $visit->check_in_notes."\n" : '').$notes)
                    : $visit->check_in_notes,
            ])->save();

            $this->logWriter->write(
                $visit->tenant_id,
                $visit->id,
                VisitLogEvent::CheckedOut,
                actorUserId: (int) $actor->id,
                before: $before,
                after: $this->snapshotter->snapshot($visit->fresh()),
                message: 'Check-out registrado.',
            );

            return $visit->fresh();
        });
    }
}
