<?php

use Illuminate\Support\Facades\Route;
use Modules\PortalApi\Http\Controllers\VerifyController;
use Modules\PortalApi\Http\Controllers\Api\PortalController;
use Modules\PortalApi\Http\Controllers\Api\AuthController;
use Modules\PortalApi\Http\Controllers\Api\PushController;
use Modules\PortalApi\Http\Controllers\Api\DoctorController;
use Modules\PortalApi\Http\Controllers\Api\PortalDeviceController;
use Modules\PortalApi\Http\Controllers\Api\DevAuthController;
use Modules\PortalApi\Http\Controllers\GuestBookingController;

/*
|------------------------------------------------------------------------
| Public vaccination card verification
|------------------------------------------------------------------------
*/
Route::middleware(['web'])->group(function () {
    Route::get('/verify/{petId}', [VerifyController::class, 'show'])
        ->where('petId', '[0-9]+')
        ->name('portal-api.verify');

    // Magic-link click → resolves token, issues a bearer, redirects to
    // the PWA with ?magic=<bearer>. PWA picks it up on boot.
    Route::get('/portal-auth/magic/{token}', [AuthController::class, 'magicClick'])
        ->where('token', '[A-Za-z0-9]+')
        ->name('portal-api.magic.click');
});

/*
|------------------------------------------------------------------------
| Public online booking (opt-in per brand: portal_brands.public_booking)
|------------------------------------------------------------------------
| No login. The brand resolves the business; the controller 404s unless the
| brand exists AND has public booking enabled. Writes (the booking submit) are
| throttled hard and only ever create a PENDING appointment for staff to confirm.
*/
Route::middleware(['web'])->group(function () {
    Route::get('/book/{slug?}', [GuestBookingController::class, 'page'])
        ->where('slug', '[A-Za-z0-9\-]+')->name('portal-api.book');
    Route::middleware('throttle:40,1')->get('/book-api/availability', [GuestBookingController::class, 'availability'])
        ->name('portal-api.book.availability');
    Route::middleware('throttle:6,1')->post('/book-api/otp', [GuestBookingController::class, 'requestOtp'])
        ->name('portal-api.book.otp');
    Route::middleware('throttle:6,1')->post('/book-api/submit', [GuestBookingController::class, 'submit'])
        ->name('portal-api.book.submit');
});

/*
|------------------------------------------------------------------------
| Pet-owner PWA shell (production)
|------------------------------------------------------------------------
| Serves the Vite-built PWA from public/app/index.html for any /app/* URL
| so vue-router's history mode works on reload. Static assets in public/app/
| (JS, CSS, manifest, icons) are served by the web server directly and
| never hit this route.
|
| If the build hasn't been produced yet, falls back to a friendly notice
| that tells you to run `npm run build` in pwa-owner/.
*/
Route::middleware(['web'])->prefix('app')->group(function () {
    Route::get('/{any?}', function () {
        $shell = public_path('app/index.html');
        if (! file_exists($shell)) {
            return response()->view('portalApi::pwa_build_notice', [], 200);
        }
        // Never cache the SPA shell — its <script src=…hash.js> references
        // change on every build. The hashed asset files themselves stay
        // immutable so the browser still caches what matters.
        return response()->file($shell, [
            'Content-Type'   => 'text/html; charset=utf-8',
            'Cache-Control'  => 'no-store, must-revalidate',
            'Pragma'         => 'no-cache',
            'Expires'        => '0',
        ]);
    })->where('any', '.*');
});

/*
|------------------------------------------------------------------------
| PWA JSON API  (/api/v1/portal/*)
|------------------------------------------------------------------------
*/
Route::prefix('api/v1/portal')->group(function () {
    // PUBLIC — used to render the brand on the login screen pre-auth.
    // No-slug variant resolves from the request host (custom domain or
    // first active brand fallback).
    Route::get('/brand',        [PortalController::class, 'brandResolve']);
    Route::get('/brand/{slug}', [PortalController::class, 'brand']);

    // PUBLIC — PWA fetches the VAPID public key before pushManager.subscribe()
    Route::get('/push/key', [PushController::class, 'vapidKey']);

    // DEV-ONLY — test-sign-in helpers. Controller short-circuits with 404
    // when the flag is off; this is belt-and-braces.
    if (DevAuthController::enabled()) {
        Route::get('/dev/credentials', [DevAuthController::class, 'credentials']);
        Route::post('/dev/password',   [DevAuthController::class, 'password']);
    }

    // PUBLIC auth flows. Throttle aggressively to stop OTP/email bombing
    // and brute-force attempts. throttle:N,M = N requests per M minutes
    // per IP address (Laravel's default key).
    Route::middleware(['throttle:5,1'])->group(function () {
        Route::post('/auth/password',      [AuthController::class, 'password']);
        Route::post('/auth/otp/request',   [AuthController::class, 'otpRequest']);
        Route::post('/auth/magic/request', [AuthController::class, 'magicRequest']);
    });
    // OTP verify is the "second factor" — limit more loosely so a slow
    // typist isn't locked out, but still prevent code brute-forcing.
    Route::middleware(['throttle:15,1'])->group(function () {
        Route::post('/auth/otp/verify',    [AuthController::class, 'otpVerify']);
    });

    // AUTHED  (Bearer <portal token>)
    Route::middleware(['portal-api.auth'])->group(function () {
        Route::post('/auth/logout',               [AuthController::class, 'logout']);

        Route::get('/me',                         [PortalController::class, 'me']);
        Route::get('/locations',                  [PortalController::class, 'locations']);
        Route::get('/home',                       [PortalController::class, 'home']);
        Route::get('/pets',                       [PortalController::class, 'pets']);
        Route::get('/pets/{id}',                  [PortalController::class, 'pet'])->where('id', '[0-9]+');
        Route::get('/pets/{id}/vax-card',         [PortalController::class, 'vaxCard'])->where('id', '[0-9]+');
        Route::get('/reasons',                    [PortalController::class, 'reasons']);
        Route::get('/slots',                      [PortalController::class, 'slots']);
        Route::get('/appointments',               [PortalController::class, 'appointments']);
        Route::post('/appointments',              [PortalController::class, 'book']);
        Route::post('/appointments/{id}/cancel',  [PortalController::class, 'cancelAppointment'])
            ->where('id', '[0-9]+');

        // Boarding / observation / hospitalization — active + recent stays.
        Route::get('/admissions',                 [PortalController::class, 'admissions']);

        // Push notification subscription management
        Route::post('/push/subscribe',     [PushController::class, 'subscribe']);
        Route::patch('/push/preferences',  [PushController::class, 'preferences']);
        Route::delete('/push/unsubscribe', [PushController::class, 'unsubscribe']);

        // Doctor catalogue + preferred-doctor change
        Route::get('/doctors',                          [DoctorController::class, 'index']);
        Route::patch('/pets/{id}/preferred-doctor',     [DoctorController::class, 'setPreferredDoctor'])
            ->where('id', '[0-9]+');

        // PWA pings this on every boot — tracks install/last-seen state.
        Route::post('/device/ping',                    [PortalDeviceController::class, 'ping']);

        /* ── Wave-2 features ─────────────────────────────────── */

        // Owner profile + account
        Route::patch ('/me',                           [PortalController::class, 'updateMe']);
        Route::delete('/me',                           [PortalController::class, 'deleteAccount']);
        Route::get   ('/me/export',                    [PortalController::class, 'exportData']);

        // Pet extras
        Route::post  ('/pets/{id}/photo',              [PortalController::class, 'uploadPetPhoto'])->where('id', '[0-9]+');
        Route::get   ('/pets/{id}/weights',            [PortalController::class, 'weights'])->where('id', '[0-9]+');
        Route::post  ('/pets/{id}/weights',            [PortalController::class, 'addWeight'])->where('id', '[0-9]+');
        Route::get   ('/pets/{id}/symptoms',           [PortalController::class, 'symptoms'])->where('id', '[0-9]+');
        Route::post  ('/pets/{id}/symptoms',           [PortalController::class, 'addSymptom'])->where('id', '[0-9]+');

        // Clinical content
        Route::get   ('/medical-reports',              [PortalController::class, 'medicalReports']);
        Route::get   ('/medical-reports/{id}',         [PortalController::class, 'medicalReport'])->where('id', '[0-9]+');
        Route::get   ('/medical-reports/{id}/print',   [PortalController::class, 'medicalReportPrint'])->where('id', '[0-9]+');
        Route::get   ('/appointments/{id}/soap',       [PortalController::class, 'appointmentSoap'])->where('id', '[0-9]+');
        Route::get   ('/appointments/{id}/ics',        [PortalController::class, 'appointmentIcs'])->where('id', '[0-9]+');
        Route::post  ('/appointments/{id}/review',     [PortalController::class, 'submitReview'])->where('id', '[0-9]+');
        Route::get   ('/appointments/{id}/review',     [PortalController::class, 'reviewFor'])->where('id', '[0-9]+');

        Route::get   ('/prescriptions',                [PortalController::class, 'prescriptions']);
        Route::post  ('/prescriptions/{id}/refill',    [PortalController::class, 'requestRefill'])->where('id', '[0-9]+');

        Route::get   ('/lab-sessions',                 [PortalController::class, 'labSessions']);
        Route::get   ('/lab-sessions/{id}',            [PortalController::class, 'labSession'])->where('id', '[0-9]+');

        Route::get   ('/invoices',                     [PortalController::class, 'invoices']);

        // Inbox / telehealth / notifications / search
        Route::get   ('/messages',                     [PortalController::class, 'messages']);
        Route::post  ('/messages',                     [PortalController::class, 'sendMessage']);
        Route::post  ('/messages/read',                [PortalController::class, 'markMessagesRead']);

        Route::get   ('/telehealth',                   [PortalController::class, 'telehealth']);
        Route::post  ('/telehealth',                   [PortalController::class, 'submitTelehealth']);

        Route::get   ('/notifications',                [PortalController::class, 'notifications']);
        Route::post  ('/notifications/read',           [PortalController::class, 'markNotificationsRead']);

        Route::get   ('/search',                       [PortalController::class, 'search']);

        // Vax card printable
        Route::get   ('/pets/{id}/vax-card/print',     [PortalController::class, 'vaxCardPrint'])->where('id', '[0-9]+');
    });
});
