<?php

namespace App\Http\Controllers\Api\V1\Documents;

use App\Domain\Applicants\Models\Applicant;
use App\Domain\Applicants\Policies\ApplicantPolicy;
use App\Domain\Documents\Enums\DocumentStatus;
use App\Domain\Documents\Models\Document;
use App\Domain\Identity\Services\ScopeGuard;
use App\Http\Controllers\Controller;
use App\Http\Resources\DocumentResource;
use App\Support\ApiResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

/**
 * The verification queue (§17B.11) — everything waiting on a reviewer, plus
 * the expiry watchlist (§17B.17).
 */
class DocumentQueueController extends Controller
{
    public function __construct(private readonly ScopeGuard $scopes) {}

    public function index(Request $request): JsonResponse
    {
        abort_unless($request->user()->can('document.view'), 403);

        $query = Document::query()
            ->current()
            ->with(['documentType', 'owner', 'uploadedBy:id,name'])
            ->where('company_id', $request->user()->company_id);

        // A document is only visible if its owning applicant is. Scope is
        // applied to the applicant query, not to `documents`, which carries no
        // branch or team dimension of its own.
        $applicantMorph = (new Applicant)->getMorphClass();
        $scopedApplicants = $this->scopes->apply(
            Applicant::query()->select('id'),
            $request->user(),
            'document.view',
            ApplicantPolicy::OWNER_COLUMNS,
        );

        $query->where(function ($outer) use ($applicantMorph, $scopedApplicants) {
            $outer->where(fn ($q) => $q
                ->where('owner_type', $applicantMorph)
                ->whereIn('owner_id', $scopedApplicants))
                // Employer and agent documents are company-level records.
                ->orWhere('owner_type', '!=', $applicantMorph);
        });

        $documents = $query
            ->when($request->filled('status'),
                fn ($b) => $b->where('verification_status', $request->string('status')),
                fn ($b) => $b->awaitingReview())
            ->when($request->filled('document_type_id'), fn ($b) => $b->whereHas(
                'documentType', fn ($q) => $q->where('uuid', $request->string('document_type_id'))
            ))
            ->when($request->boolean('expiring_soon'), fn ($b) => $b
                ->whereNotNull('expiry_date')
                ->whereBetween('expiry_date', [now()->toDateString(), now()->addDays(90)->toDateString()]))
            ->when($request->boolean('expired'), fn ($b) => $b
                ->whereNotNull('expiry_date')
                ->whereDate('expiry_date', '<', now()->toDateString()))
            ->orderBy('created_at')
            ->paginate($request->integer('per_page', 25));

        return ApiResponse::success(
            DocumentResource::collection($documents),
            meta: [
                'statuses' => array_map(
                    fn (DocumentStatus $status) => ['value' => $status->value, 'label' => $status->label()],
                    DocumentStatus::cases(),
                ),
            ],
        );
    }
}
