<?php

namespace App\Services;

use App\Models\Claim\Claim;
use App\Models\Client\Client;
use App\Models\Dsar\Dsar;
use App\Models\Document\Document;
use App\Models\WipEntry;
use Illuminate\Support\Facades\Cache;

/**
 * Books "document review" WIP for the time a handler spends on the document
 * preview screen. Called from two places — the Livewire "Finish review" action
 * and the sendBeacon tab-close endpoint — so a per-review token guards against
 * double-counting: whichever fires first wins, the other is a no-op.
 */
class DocumentReviewWipService
{
    public function __construct(private WipService $wip) {}

    public function book(
        Document $document,
        int $seconds,
        ?int $units,
        ?string $description,
        string $reviewToken,
        ?string $startedAt = null,
    ): ?WipEntry {
        $reviewToken = trim($reviewToken);

        // One booking per preview session. Cache::add is atomic, so the button
        // and the beacon cannot both create an entry for the same token.
        if ($reviewToken === '' || ! Cache::add("wip:review:{$reviewToken}", true, now()->addHour())) {
            return null;
        }

        [$clientId, $claimId] = $this->resolveOwner($document);

        return $this->wip->create([
            'client_id'     => $clientId,
            'claim_id'      => $claimId,
            'activity_type' => 'document_review',
            'seconds'       => max(0, $seconds),
            'units'         => $units,
            'description'   => $description ?: 'Reviewed document: ' . $document->display_name,
            'started_at'    => $startedAt ?: now(),
            'ended_at'      => now(),
            'is_manual'     => false,
        ], $document);
    }

    /**
     * Resolve the client/claim a document hangs off, mirroring DocumentManager@save.
     *
     * @return array{0: ?int, 1: ?int} [clientId, claimId]
     */
    private function resolveOwner(Document $document): array
    {
        $owner = $document->owner;

        return match (true) {
            $owner instanceof Client => [$owner->id, $owner->claim?->id],
            $owner instanceof Claim  => [$owner->client_id, $owner->id],
            $owner instanceof Dsar   => [$owner->claim?->client_id, $owner->claim?->id],
            default                  => [null, null],
        };
    }
}
