<?php

declare(strict_types=1);

namespace ImovelZapAi\Signatures\Application\Actions;

use ImovelZapAi\Signatures\Application\Services\SignatureAuditWriter;
use ImovelZapAi\Signatures\Application\Services\SignatureStatusSynchronizer;
use ImovelZapAi\Signatures\Domain\Enums\SignatureAuditEvent;
use ImovelZapAi\Signatures\Domain\Enums\SignatureRequestStatus;
use ImovelZapAi\Signatures\Domain\Enums\SignerStatus;
use ImovelZapAi\Signatures\Domain\Events\SignatureExpired;
use ImovelZapAi\Signatures\Domain\Exceptions\SignatureException;
use ImovelZapAi\Signatures\Infrastructure\Persistence\Eloquent\SignatureRequestModel;

final class ExpireSignatureRequestAction
{
    public function __construct(
        private readonly SignatureAuditWriter $audit,
        private readonly SignatureStatusSynchronizer $sync,
    ) {}

    public function execute(SignatureRequestModel $request): SignatureRequestModel
    {
        if (! $request->isOpen()) {
            throw SignatureException::invalidState('solicitação já encerrada.');
        }

        $request->forceFill(['status' => SignatureRequestStatus::Expired])->save();

        $request->signers()
            ->whereNotIn('status', [SignerStatus::Signed->value, SignerStatus::Rejected->value])
            ->update(['status' => SignerStatus::Expired->value]);

        $this->audit->write(
            $request->tenant_id,
            $request->id,
            SignatureAuditEvent::Expired,
            actorType: 'system',
            message: 'Solicitação de assinatura expirada.',
        );

        SignatureExpired::dispatch($request->tenant_id, $request->id);

        $this->sync->sync($request);

        return $request->fresh(['signers', 'document']);
    }
}
