<?php

use App\Http\Controllers\Api\AdminAiController;
use App\Http\Controllers\Api\AiController;
use App\Http\Controllers\Api\ApprovalController;
use App\Http\Controllers\Api\AuthController;
use App\Http\Controllers\Api\BookingCatalogController;
use App\Http\Controllers\Api\BookingController;
use App\Http\Controllers\Api\CallController;
use App\Http\Controllers\Api\CatalogController;
use App\Http\Controllers\Api\ChatController;
use App\Http\Controllers\Api\ConsultationController;
use App\Http\Controllers\Api\ContentController;
use App\Http\Controllers\Api\ExpertController;
use App\Http\Controllers\Api\PanchangController;
use App\Http\Controllers\Api\PanchangShareController;
use App\Http\Controllers\Api\GroupController;
use App\Http\Controllers\Api\KycController;
use App\Http\Controllers\Api\MasterController;
use App\Http\Controllers\Api\NotificationController;
use App\Http\Controllers\Api\NumerologyController;
use App\Http\Controllers\Api\PaymentController;
use App\Http\Controllers\Api\AstroController;
use App\Http\Controllers\Api\ChantImportController;
use App\Http\Controllers\Api\MediaController;
use App\Http\Controllers\Api\PanditController;
use App\Http\Controllers\Api\PdfController;
use App\Http\Controllers\Api\PublicController;
use App\Http\Controllers\Api\SettingsController;
use App\Http\Controllers\Api\TrustController;
use App\Http\Controllers\Api\UsersController;
use App\Http\Controllers\Api\WorkflowController;
use App\Http\Controllers\Api\ReportController;
use App\Http\Controllers\Api\SevaController;
use App\Http\Controllers\Api\ShopController;
use App\Http\Controllers\Api\DaySpecialController;
use App\Http\Controllers\Api\AnnouncementController;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| VPandit API routes  (prefix: /api)
|--------------------------------------------------------------------------
| Parallel-run migration. Each module is added here as it is ported, and its
| PHP counterpart is retired only after the React route is validated live.
*/

Route::get('/ping', fn () => response()->json(['ok' => true, 'data' => ['service' => 'vpandit-api', 'stack' => 'laravel']]));

// ---- Auth (public + protected) --------------------------------------------
Route::prefix('auth')->group(function () {
    Route::post('login', [AuthController::class, 'login'])->middleware('throttle:auth');
    Route::post('register', [AuthController::class, 'register'])->middleware('throttle:auth');
    Route::post('otp/request', [AuthController::class, 'otpRequest'])->middleware('throttle:auth');
    Route::post('otp/verify', [AuthController::class, 'otpVerify'])->middleware('throttle:auth');

    Route::middleware('auth:sanctum')->group(function () {
        Route::get('me', [AuthController::class, 'me']);
        Route::post('logout', [AuthController::class, 'logout']);
        Route::post('change-password', [AuthController::class, 'changePassword']);
    });
});

// ---- Delegated menu access (each tier designs the menu for the tier below) --
Route::middleware(['auth:sanctum', 'throttle:api'])->group(function () {
    Route::get('me/menu-access', [\App\Http\Controllers\Api\MenuAccessController::class, 'mine']);
    // Unified structured profile — every user type edits the same profile here.
    Route::get('user-profile', [\App\Http\Controllers\Api\UserProfileController::class, 'mine']);
    Route::post('user-profile', [\App\Http\Controllers\Api\UserProfileController::class, 'save']);
    Route::get('menu-access/users', [\App\Http\Controllers\Api\MenuAccessController::class, 'users']);
    Route::get('menu-access/users/{id}', [\App\Http\Controllers\Api\MenuAccessController::class, 'show'])->whereNumber('id');
    Route::post('menu-access/users/{id}', [\App\Http\Controllers\Api\MenuAccessController::class, 'save'])->whereNumber('id');
});

// ---- Trust portal — port of PHP trust/dashboard ----------------------------
Route::prefix('trust')->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api'])->group(function () {
    Route::get('dashboard', [TrustController::class, 'dashboard']);
});

// ---- Pandit self-service portal — port of PHP pandit/* ----------------------
Route::prefix('pandit')->middleware(['auth:sanctum', 'role:pandit', 'throttle:api'])->group(function () {
    Route::get('dashboard', [PanditController::class, 'dashboard']);
    Route::get('profile', [PanditController::class, 'profile']);
    Route::post('profile', [PanditController::class, 'saveProfile']);
    Route::get('services', [PanditController::class, 'services']);
    Route::post('services', [PanditController::class, 'saveService']);
    Route::delete('services/{id}', [PanditController::class, 'deleteService'])->whereNumber('id');
    Route::get('schedule', [PanditController::class, 'schedule']);
    Route::post('schedule', [PanditController::class, 'saveSchedule']);
    Route::get('subscription', [PanditController::class, 'subscription']);
});

// ---- Public marketing site (no auth) — port of PHP home/inquiry -------------
Route::middleware('throttle:api')->group(function () {
    Route::get('public/home', [PublicController::class, 'home']);
    Route::get('public/panchang', [PublicController::class, 'panchangDetail']);
    // Shared Panchang (public) — resolve a share token + branded PDF.
    Route::get('public/panchang/share/{token}', [PanchangShareController::class, 'show']);
    Route::get('public/panchang/share/{token}/pdf', [PanchangShareController::class, 'pdf']);
    Route::get('public/services', [PublicController::class, 'servicesList']);
    Route::get('public/service/{key}', [PublicController::class, 'serviceDetail']);
    Route::get('public/pooja/{key}/booklet.pdf', [PublicController::class, 'poojaBooklet']);
    Route::get('public/poojas', [PublicController::class, 'poojasAll']);
    // Bhakti Setu — scheduled e-poojas open for public booking.
    Route::get('public/bhakti-setu', [PublicController::class, 'bhaktiSetuList']);
    Route::get('public/bhakti-setu/{id}', [PublicController::class, 'bhaktiSetuDetail'])->whereNumber('id');
    Route::post('public/bhakti-setu/{id}/book', [PublicController::class, 'bhaktiSetuBook'])->whereNumber('id');
    Route::get('public/services/by-category/{cat}', [PublicController::class, 'servicesByCategory'])->where('cat', '.*');
    Route::get('public/numerology-services', [PublicController::class, 'numerologyServices']);
    // Shared numerology report (public): order status + tokenized PDF (gated by paid).
    Route::get('public/numerology/orders/{token}', [NumerologyController::class, 'orderStatus']);
    Route::get('public/numerology/report/{token}/pdf', [PdfController::class, 'numerologyStoredPdf']);
    Route::get('public/testimonials', [PublicController::class, 'testimonialsList']);
    Route::post('inquiry', [PublicController::class, 'inquiry']);
    // Territory currency (INR / USD) — resolve for this visitor + manual switch.
    Route::get('public/currency', [\App\Http\Controllers\Api\PricingController::class, 'currency']);
    Route::post('public/currency/switch', [\App\Http\Controllers\Api\PricingController::class, 'switchCurrency']);
    Route::post('public/kundali', [AstroController::class, 'kundali']);
    Route::post('public/vargas', [AstroController::class, 'vargas']);
    Route::post('public/horoscope', [AstroController::class, 'horoscope']);
    Route::post('public/matchmaking', [AstroController::class, 'matchmaking']);
    Route::get('public/astrology-services', [PublicController::class, 'astrologyServices']);
    Route::get('public/astrology/orders/{token}', [AstroController::class, 'orderStatus']);
    Route::get('public/astrology/report/{token}/pdf', [PdfController::class, 'astrologyStoredPdf']);
    Route::get('public/palmistry-services', [PublicController::class, 'palmistryServices']);
    Route::get('public/palmistry/orders/{token}', [\App\Http\Controllers\Api\PalmistryController::class, 'orderStatus']);
    Route::get('public/palmistry/report/{token}/pdf', [PdfController::class, 'palmistryStoredPdf']);
    Route::get('public/vastu-services', [PublicController::class, 'vastuServices']);
    Route::get('public/vastu/orders/{token}', [\App\Http\Controllers\Api\VastuController::class, 'orderStatus']);
    Route::get('public/vastu/report/{token}/pdf', [PdfController::class, 'vastuStoredPdf']);
});

// ---- Admin dashboard — port of PHP admin/dashboard --------------------------
Route::get('admin/dashboard', [\App\Http\Controllers\Api\AdminController::class, 'dashboard'])
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api']);

// ---- Dynamic dashboard widgets ("pins") — per authenticated user ------------
Route::prefix('dashboard/pins')
    ->middleware(['auth:sanctum', 'throttle:api'])
    ->group(function () {
        Route::get('/', [\App\Http\Controllers\Api\DashboardPinController::class, 'index']);
        Route::post('toggle', [\App\Http\Controllers\Api\DashboardPinController::class, 'toggle']);
        Route::post('reorder', [\App\Http\Controllers\Api\DashboardPinController::class, 'reorder']);
    });

// ---- Module 1: Numerology --------------------------------------------------
// ---- Site Settings (admin) — port of PHP admin/site-settings ----------------
Route::prefix('admin/settings')
    ->middleware(['auth:sanctum', 'role:super_admin', 'throttle:api'])
    ->group(function () {
        Route::get('/', [SettingsController::class, 'index']);
        Route::post('/', [SettingsController::class, 'update']);
        Route::get('{key}', [SettingsController::class, 'show']);
    });

// ---- Users administration — port of PHP admin/users ------------------------
Route::prefix('admin/users')
    ->middleware(['auth:sanctum', 'role:super_admin', 'throttle:api'])
    ->group(function () {
        Route::get('/', [UsersController::class, 'index']);
        Route::post('/', [UsersController::class, 'save']);
        Route::post('{id}/toggle', [UsersController::class, 'toggle'])->whereNumber('id');
    });

// ---- User Management summary (headline counts per user category) ------------
Route::get('admin/user-summary', [\App\Http\Controllers\Api\UserSummaryController::class, 'summary'])
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api']);
// Exact pending-queue depth per approval tab (for the User Master tab badges).
Route::get('admin/approval-counts', [\App\Http\Controllers\Api\UserSummaryController::class, 'approvalCounts'])
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api']);

// ---- Platform Analytics — super-admin all-activity dashboard (counts/amounts/hours) ----
Route::get('admin/platform-analytics', [\App\Http\Controllers\Api\PlatformAnalyticsController::class, 'index'])
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api']);

// ---- Admin: assign/change franchise territories (incl. legacy franchises) ---
Route::middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api'])->group(function () {
    Route::get('admin/franchise-territories', [\App\Http\Controllers\Api\FranchiseTerritoryController::class, 'adminList']);
    Route::post('admin/franchise-territories/assign', [\App\Http\Controllers\Api\FranchiseTerritoryController::class, 'adminAssign']);
});

// ---- Platform Charges ledger (admin finance) -------------------------------
Route::get('admin/platform-charges', [\App\Http\Controllers\Api\PlatformChargeController::class, 'index'])
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api']);

// ---- Self-service: the current user's own categories + package status ------
Route::middleware(['auth:sanctum', 'throttle:api'])->group(function () {
    Route::get('my/packages', [\App\Http\Controllers\Api\UserPackageController::class, 'mine']);
    Route::post('my/packages/{mapId}/pay', [\App\Http\Controllers\Api\UserPackageController::class, 'payInit'])->whereNumber('mapId');
    Route::get('my/stats', [\App\Http\Controllers\Api\MyStatsController::class, 'stats']);
    Route::get('my/franchise', [\App\Http\Controllers\Api\MyStatsController::class, 'franchiseDashboard']);
    Route::get('my/pandit', [\App\Http\Controllers\Api\MyStatsController::class, 'panditDashboard']);
    Route::get('my/franchise/territory', [\App\Http\Controllers\Api\FranchiseTerritoryController::class, 'show']);
    Route::get('my/franchise/territory/options', [\App\Http\Controllers\Api\FranchiseTerritoryController::class, 'options']);
    Route::post('my/franchise/territory', [\App\Http\Controllers\Api\FranchiseTerritoryController::class, 'assign']);
    Route::post('my/franchise/invite', [\App\Http\Controllers\Api\FranchiseTerritoryController::class, 'invite']);
});

// ---- Pandit AI Engagement (allocate package AI hours into AI-pandit plans) --
Route::prefix('pandit-ai')->middleware(['auth:sanctum', 'throttle:api'])->group(function () {
    $c = \App\Http\Controllers\Api\PanditAiController::class;
    Route::get('state', [$c, 'state']);
    Route::get('live', [$c, 'live']);
    Route::post('engagements', [$c, 'save']);
    Route::post('engagements/{id}/status', [$c, 'setStatus'])->whereNumber('id');
    Route::post('engagements/{id}/delete', [$c, 'destroy'])->whereNumber('id');
    Route::get('engagements/{id}/knowledge', [$c, 'knowledge'])->whereNumber('id');
    Route::post('engagements/{id}/knowledge', [$c, 'addKnowledge'])->whereNumber('id');
    Route::post('knowledge/{kid}/delete', [$c, 'deleteKnowledge'])->whereNumber('kid');
});

// ---- Pandit Console (presence, hour meters, comm sessions, recharge) -------
Route::prefix('pandit-console')->middleware(['auth:sanctum', 'throttle:api'])->group(function () {
    $c = \App\Http\Controllers\Api\PanditConsoleController::class;
    Route::get('meters', [$c, 'meters']);
    Route::post('presence', [$c, 'setPresence']);
    Route::post('comm-session', [$c, 'logCommSession']);
    Route::post('buy-hours', [$c, 'buyHours']);
});

// ---- User ↔ Category ↔ Package mapping -------------------------------------
Route::prefix('admin/user-packages')
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api'])
    ->group(function () {
        Route::get('/', [\App\Http\Controllers\Api\UserPackageController::class, 'queue']);
        Route::get('{userId}', [\App\Http\Controllers\Api\UserPackageController::class, 'show'])->whereNumber('userId');
        Route::post('{userId}', [\App\Http\Controllers\Api\UserPackageController::class, 'assign'])->whereNumber('userId');
        Route::post('{userId}/pay/{mapId}', [\App\Http\Controllers\Api\UserPackageController::class, 'confirmPayment'])->whereNumber('userId')->whereNumber('mapId');
        Route::post('{userId}/approve/{mapId}', [\App\Http\Controllers\Api\UserPackageController::class, 'approve'])->whereNumber('userId')->whereNumber('mapId');
        Route::post('{userId}/reject/{mapId}', [\App\Http\Controllers\Api\UserPackageController::class, 'reject'])->whereNumber('userId')->whereNumber('mapId');
        Route::post('{userId}/cancel/{mapId}', [\App\Http\Controllers\Api\UserPackageController::class, 'cancel'])->whereNumber('userId')->whereNumber('mapId');
    });

// ---- AI Pandit Avatars — pandits backed by an AI agent, in the experts list --
Route::prefix('admin/ai-pandits')
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api'])
    ->group(function () {
        Route::get('/', [\App\Http\Controllers\Api\AiPanditController::class, 'index']);
        Route::get('agents', [\App\Http\Controllers\Api\AiPanditController::class, 'agents']);
        Route::post('/', [\App\Http\Controllers\Api\AiPanditController::class, 'save']);
        Route::delete('{id}', [\App\Http\Controllers\Api\AiPanditController::class, 'destroy'])->whereNumber('id');
    });

// ---- Media Library — port of PHP admin/media (X07) -------------------------
Route::prefix('admin/media')
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api'])
    ->group(function () {
        Route::get('/', [MediaController::class, 'index']);
        Route::post('/', [MediaController::class, 'upload']);
        Route::delete('{id}', [MediaController::class, 'destroy'])->whereNumber('id');
    });

// ---- Admin workflows: service bookings + booking orders --------------------
Route::prefix('admin')->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api'])->group(function () {
    Route::get('service-bookings', [WorkflowController::class, 'serviceBookings']);
    Route::post('service-bookings/{id}/status', [WorkflowController::class, 'serviceBookingStatus'])->whereNumber('id');
    Route::get('booking-orders', [WorkflowController::class, 'bookingOrders']);
    Route::get('booking-orders/{id}', [WorkflowController::class, 'bookingOrder'])->whereNumber('id');
    Route::post('booking-orders/{id}/status', [WorkflowController::class, 'bookingOrderStatus'])->whereNumber('id');
    // Chants import (PDF/Word/CSV/OCR)
    Route::post('chants/import/preview', [ChantImportController::class, 'preview']);
    Route::post('chants/import/commit', [ChantImportController::class, 'commit']);
    // Unified profile — admin view of any user's structured profile.
    Route::get('user-profiles/{id}', [\App\Http\Controllers\Api\UserProfileController::class, 'show'])->whereNumber('id');
});

// ---- Admin: Booking Catalog rate-card manager — port of admin/booking_catalog.php ----
// Main Services CRUD + Peripheral Packages CRUD + per-service package link editor.
Route::prefix('admin/booking-catalog')
    ->middleware(['auth:sanctum', 'role:super_admin', 'throttle:api'])
    ->group(function () {
        Route::get('/', [BookingCatalogController::class, 'index']);
        // Main services
        Route::post('services', [BookingCatalogController::class, 'saveService']);
        Route::post('services/{id}/toggle', [BookingCatalogController::class, 'toggleService'])->whereNumber('id');
        Route::delete('services/{id}', [BookingCatalogController::class, 'deleteService'])->whereNumber('id');
        // Per-service package links
        Route::get('services/{id}/links', [BookingCatalogController::class, 'links'])->whereNumber('id');
        Route::post('services/{id}/links', [BookingCatalogController::class, 'saveLinks'])->whereNumber('id');
        // Peripheral packages
        Route::post('addons', [BookingCatalogController::class, 'saveAddon']);
        Route::post('addons/{id}/toggle', [BookingCatalogController::class, 'toggleAddon'])->whereNumber('id');
        Route::delete('addons/{id}', [BookingCatalogController::class, 'deleteAddon'])->whereNumber('id');
    });

// ── Pooja ↔ Material mapping ────────────────────────────────────────────────
Route::prefix('admin/pooja-material')
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api'])
    ->group(function () {
        Route::get('options', [\App\Http\Controllers\Api\PoojaMaterialController::class, 'options']);
        Route::get('materials', [\App\Http\Controllers\Api\PoojaMaterialController::class, 'materialSearch']);
        // Materials mapped to one pooja (by booking_services slug or id) — feeds the
        // Pooja Sequence step "Materials" dropdown so it shows only mapped items.
        Route::get('for-pooja', [\App\Http\Controllers\Api\PoojaMaterialController::class, 'forPooja']);
        Route::get('peripherals/{serviceId}', [\App\Http\Controllers\Api\PoojaMaterialController::class, 'peripherals'])->whereNumber('serviceId');
        Route::get('existing', [\App\Http\Controllers\Api\PoojaMaterialController::class, 'existing']);
        Route::post('save', [\App\Http\Controllers\Api\PoojaMaterialController::class, 'save']);
        Route::get('list', [\App\Http\Controllers\Api\PoojaMaterialController::class, 'list']);
        Route::delete('{serviceId}/{addonId}', [\App\Http\Controllers\Api\PoojaMaterialController::class, 'destroy'])->whereNumber('serviceId')->whereNumber('addonId');
    });

// ── Unified report orders (all modules) — one admin surface + client history ─
Route::get('my/service-orders', [\App\Http\Controllers\Api\OrdersController::class, 'myOrders'])
    ->middleware(['auth:sanctum', 'throttle:api']);
Route::prefix('admin/service-orders')
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api'])
    ->group(function () {
        Route::get('/', [\App\Http\Controllers\Api\OrdersController::class, 'adminList']);
        Route::post('{token}/verify', [\App\Http\Controllers\Api\OrdersController::class, 'verify']);
        Route::post('{token}/reject', [\App\Http\Controllers\Api\OrdersController::class, 'reject']);
    });

// ── Astrology reports + orders (public) ─────────────────────────────────────
Route::prefix('astrology')->middleware('throttle:api')->group(function () {
    Route::post('service-report', [AstroController::class, 'serviceReport']);
    Route::post('report/combined/pdf', [PdfController::class, 'astrologyCombined']);
    // Orders + pay-to-unlock (payment context: astrology_order).
    Route::post('orders', [AstroController::class, 'createOrder']);
    Route::post('orders/{token}/checkout', [AstroController::class, 'checkout']);
    Route::post('orders/{token}/capture', [AstroController::class, 'capture']);
    Route::post('orders/{token}/pay', [AstroController::class, 'payOrder']);
    Route::get('orders', [AstroController::class, 'myOrders'])->middleware('auth:sanctum');
    Route::middleware(['auth:sanctum', 'role:super_admin,trust_manager'])->group(function () {
        Route::get('admin/orders', [AstroController::class, 'adminOrders']);
        Route::post('orders/{token}/verify', [AstroController::class, 'verifyOrder']);
        Route::post('orders/{token}/reject', [AstroController::class, 'rejectOrder']);
    });
});

// ── Sacred Library — public reads + Pandit-guide assembler ──────────────────
Route::prefix('library')->middleware('throttle:api')->group(function () {
    Route::get('books', [\App\Http\Controllers\Api\LibraryController::class, 'books']);
    Route::get('chants', [\App\Http\Controllers\Api\LibraryController::class, 'chants']);
    Route::get('chants/{code}', [\App\Http\Controllers\Api\LibraryController::class, 'chant']);
    Route::get('sections', [\App\Http\Controllers\Api\LibraryController::class, 'sections']);
    Route::get('book/{book}', [\App\Http\Controllers\Api\LibraryController::class, 'book']);
    Route::get('sankalp-variables', [\App\Http\Controllers\Api\LibraryController::class, 'sankalpVariables']);
    Route::get('svara-scale', [\App\Http\Controllers\Api\LibraryController::class, 'svaraScale']);
    Route::get('pooja/{pooja}/steps', [\App\Http\Controllers\Api\LibraryController::class, 'poojaSteps']);
    Route::post('assemble', [\App\Http\Controllers\Api\LibraryController::class, 'assemble']);
});

Route::prefix('numerology')->middleware('throttle:api')->group(function () {
    // Public compute (mirrors the PHP free numerology tool).
    Route::post('compute', [NumerologyController::class, 'compute']);
    Route::post('special-analysis', [NumerologyController::class, 'specialAnalysis']);
    // Pure numerology couple compatibility (separate from astrology Ashtakoot).
    Route::post('compatibility', [NumerologyController::class, 'compatibility']);
    // Opt-in Health Insights (medical numerology; disclaimer-gated).
    Route::post('health', [NumerologyController::class, 'healthInsights']);
    // DB predictions for computed peripheral sections (by calc + number).
    Route::post('predictions', [NumerologyController::class, 'numberPredictions']);
    // Topic-based predictions (canonical `numerologies` design: topc_no + number
    // → HTML desc_title/desc_details). Drives every compute_key peripheral.
    Route::get('topic/{topic}/{number}', [NumerologyController::class, 'topicOne']);
    Route::post('topic-predictions', [NumerologyController::class, 'topicPredictions']);
    // Combination readings: pairwise numcom + 6-value personalnumcom (pyramid).
    Route::get('numcom/{v1}/{v2}', [NumerologyController::class, 'numcom']);
    Route::get('personalnumcom/{v1}/{v2}/{v3}/{v4}/{v5}/{v6}', [NumerologyController::class, 'personalnumcom']);
    // Mobile numerology (pairs + weightage + Pros/Cons/Remedies) and matchmaking.
    Route::post('mobile', [NumerologyController::class, 'mobileNumerology']);
    Route::post('matchmaking', [NumerologyController::class, 'matchmaking']);
    // Lo Shu per-number impact readings (balance panel DB text).
    Route::post('loshu-readings', [NumerologyController::class, 'loshuReadings']);
    // Lo Shu Grid Predictions master (num_loshu_predictions) by topic+digit+count.
    Route::post('loshu-grid-predictions', [NumerologyController::class, 'loshuGridPredictions']);
    // Lo Shu / Vedic plane (line-of-three) readings — complete planes only.
    Route::post('loshu-plane-readings', [NumerologyController::class, 'loshuPlaneReadings']);
    // Birth-date predictions (num_type_predictions) — send mulank + birth date.
    Route::post('birthdate-predictions', [NumerologyController::class, 'birthDatePredictions']);
    // Rebuild the numerology AI-agent knowledge base from the prediction tables.
    Route::post('kb/ingest', [NumerologyController::class, 'ingestKb']);
    // Unified prediction resolver (Tier-3): rule engine → fixed tables fallback.
    Route::post('predict', [NumerologyController::class, 'predict']);
    // Auto-translate base-language rows into target languages (en/hi) via LLM.
    Route::post('translate', [NumerologyController::class, 'translate']);
    // ── Admin-Controlled AI Numerology Engine (deterministic) ──
    Route::post('ai/analyze', [NumerologyController::class, 'aiAnalyze']);
    Route::post('rule-match', [NumerologyController::class, 'ruleMatch']);
    Route::get('kb/dashboard', [NumerologyController::class, 'kbDashboard'])
        ->middleware(['auth:sanctum', 'role:super_admin,trust_manager']);
    // Per-service report (admin template mapped by service slug) — public tool.
    Route::post('service-report', [NumerologyController::class, 'serviceReport']);
    // Devanagari-capable PDF report (public; nothing persisted).
    Route::post('report/pdf', [PdfController::class, 'numerologyReport']);
    // Combined single PDF of the free report + all selected paid services.
    Route::post('report/combined/pdf', [PdfController::class, 'numerologyCombined']);
    // Order history — create is open (links to user if logged in); list needs auth.
    Route::post('orders', [NumerologyController::class, 'createOrder']);
    Route::get('orders', [NumerologyController::class, 'myOrders'])->middleware('auth:sanctum');
    // Pay-to-unlock: automatic gateway (Razorpay/UPI) — checkout + capture.
    Route::post('orders/{token}/checkout', [NumerologyController::class, 'checkout']);
    Route::post('orders/{token}/capture', [NumerologyController::class, 'capture']);
    // Manual fallback: client submits a UPI reference; admin verifies → paid.
    Route::post('orders/{token}/pay', [NumerologyController::class, 'payOrder']);
    Route::middleware(['auth:sanctum', 'role:super_admin,trust_manager'])->group(function () {
        Route::get('admin/orders', [NumerologyController::class, 'adminOrders']);
        Route::post('orders/{token}/verify', [NumerologyController::class, 'verifyOrder']);
        Route::post('orders/{token}/reject', [NumerologyController::class, 'rejectOrder']);
    });
    // Dasha → Antardasha → Pratyantar timeline + period interpretation (public tool).
    Route::post('dasha', [\App\Http\Controllers\Api\DashaController::class, 'tree']);
    Route::post('dasha/interpret', [\App\Http\Controllers\Api\DashaController::class, 'interpret']);
    // Public read of the Number Combo master (dasha combination predictions).
    Route::get('dasha/combos', [\App\Http\Controllers\Api\DashaController::class, 'combos']);
    // Public read of the Lo Shu Grid Predictions master (grid topic 201-218 / 301-318).
    Route::get('grid-predictions', [\App\Http\Controllers\Api\DashaController::class, 'gridPredictions']);
    // Public read of the Number Master (1-9) — team-editable lucky tables for My Page.
    Route::get('number-master', [\App\Http\Controllers\Api\DashaController::class, 'numberMaster']);
    // Public read of the seeded Health-engine content bank (My Page Health & Dasha tab).
    Route::get('health-content', [\App\Http\Controllers\Api\DashaController::class, 'healthContent']);
    // ── Numerology Health & Dasha engine (server mirror of the client lib) ──
    Route::post('dasha/timeline', [\App\Http\Controllers\Api\NumHealthController::class, 'timeline']);
    Route::post('dasha/at', [\App\Http\Controllers\Api\NumHealthController::class, 'at']);
    Route::post('health/assess', [\App\Http\Controllers\Api\NumHealthController::class, 'assess']);
    Route::post('health/reading', [\App\Http\Controllers\Api\NumHealthController::class, 'reading']);
    Route::post('health/forecast', [\App\Http\Controllers\Api\NumHealthController::class, 'forecast']);
    Route::post('health/transitions', [\App\Http\Controllers\Api\NumHealthController::class, 'transitions']);
    // Devanagari/Gujarati PDF of the health reading (gated by paid order_token).
    Route::post('health/report/pdf', [\App\Http\Controllers\Api\PdfController::class, 'numerologyHealthReport']);

    // ── Numerology Forecast engine (server mirror of numerology_forecast.js) ──
    Route::get('forecast/config', [\App\Http\Controllers\Api\NumForecastController::class, 'config']);
    Route::post('forecast/numbers', [\App\Http\Controllers\Api\NumForecastController::class, 'numbers']);
    Route::post('forecast/profile', [\App\Http\Controllers\Api\NumForecastController::class, 'profile']);
    Route::post('forecast/name-numbers', [\App\Http\Controllers\Api\NumForecastController::class, 'nameNumbers']);
    Route::post('forecast/compute', [\App\Http\Controllers\Api\NumForecastController::class, 'compute']);
    Route::post('forecast/full', [\App\Http\Controllers\Api\NumForecastController::class, 'full']);
    Route::post('forecast/monthly', [\App\Http\Controllers\Api\NumForecastController::class, 'monthly']);
    Route::post('forecast/calendar', [\App\Http\Controllers\Api\NumForecastController::class, 'calendar']);
    Route::post('forecast/auspicious', [\App\Http\Controllers\Api\NumForecastController::class, 'auspicious']);
    Route::post('forecast/compatibility', [\App\Http\Controllers\Api\NumForecastController::class, 'compatibility']);
    Route::post('forecast/number-score', [\App\Http\Controllers\Api\NumForecastController::class, 'numberScore']);
    Route::get('forecast/triad/{kind}/{v1}/{v2}/{v3}', [\App\Http\Controllers\Api\NumForecastController::class, 'triad']);
    // Visual admin editor for the forecast scoring tables (relation grid + affinity heatmap).
    Route::middleware(['auth:sanctum', 'role:super_admin,trust_manager'])->group(function () {
        Route::get('forecast/admin/tables', [\App\Http\Controllers\Api\NumForecastAdminController::class, 'tables']);
        Route::post('forecast/admin/save', [\App\Http\Controllers\Api\NumForecastAdminController::class, 'save']);
        Route::post('forecast/admin/reset', [\App\Http\Controllers\Api\NumForecastAdminController::class, 'reset']);
    });

    // Saved customer vault — authenticated (admin / pandit / yajman).
    Route::middleware(['auth:sanctum'])->group(function () {
        // Registered customer's own tabbed profile (front-side) + package picker.
        Route::get('me/profile', [NumerologyController::class, 'meProfile']);
        Route::post('me/profile', [NumerologyController::class, 'saveMeProfile']);
        Route::get('packages', [NumerologyController::class, 'packages']);
        Route::get('customers', [NumerologyController::class, 'customers']);
        Route::get('customers/{customer}', [NumerologyController::class, 'customer']);
        // Customer assets (Asset Registry scoped to a customer — profile data).
        Route::get('customers/{customer}/assets', [NumerologyController::class, 'assets']);
        Route::post('customers/{customer}/assets', [NumerologyController::class, 'assetSave'])
            ->middleware('role:super_admin,pandit');
        Route::delete('customers/{customer}/assets/{asset}', [NumerologyController::class, 'assetDelete'])
            ->whereNumber('asset')->middleware('role:super_admin,pandit');
        // Create + Recalculate/Update & Save — restricted to staff (mirrors the PHP admin handlers).
        Route::post('customers', [NumerologyController::class, 'store'])
            ->middleware('role:super_admin,pandit');
        Route::post('customers/{customer}', [NumerologyController::class, 'save'])
            ->middleware('role:super_admin,pandit');
    });
});

// ---- Flexible client profile (schema-less) + service value ingestion -------
Route::prefix('profile')->middleware('throttle:api')->group(function () {
    // Public: a service records the values a client entered. Resolves a prospect
    // (lead-bank) when the visitor is not logged in, so nothing is lost.
    Route::post('ingest', [\App\Http\Controllers\Api\ProfileController::class, 'ingest']);

    // Authenticated: read + edit the client's own flexible profile.
    Route::middleware(['auth:sanctum'])->group(function () {
        Route::get('/', [\App\Http\Controllers\Api\ProfileController::class, 'show']);
        Route::put('/', [\App\Http\Controllers\Api\ProfileController::class, 'update']);
    });
});

// ---- Vastu Analyzer — property-map placement evaluation --------------------
// Config + evaluation are public (the free tool on the site); plans are saved per-user.
Route::prefix('vastu')->middleware('throttle:api')->group(function () {
    Route::get('config', [\App\Http\Controllers\Api\VastuController::class, 'config']);
    Route::get('entrances', [\App\Http\Controllers\Api\VastuController::class, 'entrances']);
    Route::get('mandala', [\App\Http\Controllers\Api\VastuController::class, 'mandala']);
    // ── Admin-Controlled AI Vastu Engine (object-based, deterministic) ──
    Route::post('ai/analyze', [\App\Http\Controllers\Api\VastuController::class, 'aiAnalyze']);
    Route::post('match', [\App\Http\Controllers\Api\VastuController::class, 'match']);
    // Per-service reports + orders + pay-to-unlock (payment context: vastu_order).
    Route::post('service-report', [\App\Http\Controllers\Api\VastuController::class, 'serviceReport']);
    Route::post('report/combined/pdf', [PdfController::class, 'vastuCombined']);
    Route::post('orders', [\App\Http\Controllers\Api\VastuController::class, 'createOrder']);
    Route::post('orders/{token}/checkout', [\App\Http\Controllers\Api\VastuController::class, 'checkout']);
    Route::post('orders/{token}/capture', [\App\Http\Controllers\Api\VastuController::class, 'capture']);
    Route::post('orders/{token}/pay', [\App\Http\Controllers\Api\VastuController::class, 'payOrder']);
    Route::get('kb/dashboard', [\App\Http\Controllers\Api\VastuController::class, 'kbDashboard'])
        ->middleware(['auth:sanctum', 'role:super_admin,trust_manager']);
    // Green→red suitable-degree map for one element (drives the image scale overlay).
    Route::get('element/{code}/degrees', [\App\Http\Controllers\Api\VastuController::class, 'elementDegrees'])->where('code', '[A-Za-z0-9_\-]+');
    Route::get('plants', [\App\Http\Controllers\Api\VastuController::class, 'plants']);
    Route::post('evaluate', [\App\Http\Controllers\Api\VastuController::class, 'evaluate']);
    Route::post('score/color', [\App\Http\Controllers\Api\VastuController::class, 'scoreColor']);
    Route::post('score/plant', [\App\Http\Controllers\Api\VastuController::class, 'scorePlant']);
    Route::post('report.pdf', [PdfController::class, 'vastuReport']);
    Route::middleware('auth:sanctum')->group(function () {
        Route::get('plans', [\App\Http\Controllers\Api\VastuController::class, 'plans']);
        Route::get('plans/{id}', [\App\Http\Controllers\Api\VastuController::class, 'plan'])->whereNumber('id');
        Route::post('plans', [\App\Http\Controllers\Api\VastuController::class, 'savePlan']);
    });
});

// ---- Palmistry Analysis — admin rule engine + client readings --------------
Route::prefix('palmistry')->middleware('throttle:api')->group(function () {
    Route::get('config', [\App\Http\Controllers\Api\PalmistryController::class, 'config']);
    Route::get('line-templates', [\App\Http\Controllers\Api\PalmistryController::class, 'lineTemplates']);
    Route::get('vision/status', [\App\Http\Controllers\Api\PalmistryController::class, 'visionStatus']);
    Route::post('classify', [\App\Http\Controllers\Api\PalmistryController::class, 'classify']);
    Route::post('measurements/interpret', [\App\Http\Controllers\Api\PalmistryController::class, 'interpretMeasurements']);
    Route::post('report.pdf', [PdfController::class, 'palmReport']);
    // Per-service reports + orders + pay-to-unlock (payment context: palmistry_order).
    Route::post('service-report', [\App\Http\Controllers\Api\PalmistryController::class, 'serviceReport']);
    Route::post('report/combined/pdf', [PdfController::class, 'palmistryCombined']);
    Route::post('orders', [\App\Http\Controllers\Api\PalmistryController::class, 'createOrder']);
    Route::post('orders/{token}/checkout', [\App\Http\Controllers\Api\PalmistryController::class, 'checkout']);
    Route::post('orders/{token}/capture', [\App\Http\Controllers\Api\PalmistryController::class, 'capture']);
    Route::post('orders/{token}/pay', [\App\Http\Controllers\Api\PalmistryController::class, 'payOrder']);
    // Optional external CV/ML scorer (proxied so the endpoint + key stay server-side).
    Route::get('cv/status', [\App\Http\Controllers\Api\PalmistryController::class, 'cvStatus']);
    Route::post('cv', [\App\Http\Controllers\Api\PalmistryController::class, 'cv']);
    Route::post('cv/validate', [\App\Http\Controllers\Api\PalmistryController::class, 'cvValidate']);
    Route::middleware('auth:sanctum')->group(function () {
        Route::post('vision', [\App\Http\Controllers\Api\PalmistryController::class, 'visionReading']);
        Route::get('readings', [\App\Http\Controllers\Api\PalmistryController::class, 'readings']);
        Route::get('readings/{id}', [\App\Http\Controllers\Api\PalmistryController::class, 'reading'])->whereNumber('id');
        Route::post('readings', [\App\Http\Controllers\Api\PalmistryController::class, 'saveReading']);
    });
    // Admin CV-service configuration + line-template designer.
    Route::middleware(['auth:sanctum', 'role:super_admin'])->group(function () {
        Route::get('cv/settings', [\App\Http\Controllers\Api\PalmistryController::class, 'cvSettings']);
        Route::post('cv/settings', [\App\Http\Controllers\Api\PalmistryController::class, 'cvSaveSettings']);
        Route::post('line-templates', [\App\Http\Controllers\Api\PalmistryController::class, 'saveLineTemplates']);
    });
});

// ---- Face Reading & Matching — astrology + psychology + compatibility -------
Route::prefix('face')->middleware('throttle:api')->group(function () {
    Route::get('rules', [\App\Http\Controllers\Api\FaceReadingController::class, 'rules']);
    Route::post('read', [\App\Http\Controllers\Api\FaceReadingController::class, 'read']);
    Route::post('match', [\App\Http\Controllers\Api\FaceReadingController::class, 'match']);
    Route::post('report/pdf', [\App\Http\Controllers\Api\FaceReadingController::class, 'reportPdf']);
    Route::middleware('auth:sanctum')->group(function () {
        Route::get('reports', [\App\Http\Controllers\Api\FaceReadingController::class, 'reports']);
        Route::get('reports/{id}', [\App\Http\Controllers\Api\FaceReadingController::class, 'report'])->whereNumber('id');
    });
});

// ---- Voice Astrology (Swar Shastra) ----------------------------------------
Route::prefix('voice-astrology')->middleware('throttle:api')->group(function () {
    Route::get('config', [\App\Http\Controllers\Api\VoiceAstrologyController::class, 'config']);
    Route::post('predict', [\App\Http\Controllers\Api\VoiceAstrologyController::class, 'predict']);
    Route::post('report.pdf', [PdfController::class, 'voiceReport']);
    Route::middleware('auth:sanctum')->group(function () {
        Route::post('readings', [\App\Http\Controllers\Api\VoiceAstrologyController::class, 'save']);
        Route::get('readings', [\App\Http\Controllers\Api\VoiceAstrologyController::class, 'readings']);
        Route::get('readings/{id}', [\App\Http\Controllers\Api\VoiceAstrologyController::class, 'reading'])->whereNumber('id');
    });
});

// ---- Module 2: Masters (config-driven CRUD + import/export) ----------------
// Admin only (super_admin | trust_manager); slug is validated against the registry.
Route::prefix('masters')
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api'])
    ->group(function () {
        Route::get('/', [MasterController::class, 'index']);
        Route::get('{slug}/meta', [MasterController::class, 'meta']);
        Route::get('{slug}/export', [MasterController::class, 'export']);
        Route::get('{slug}/template', [MasterController::class, 'template']);
        Route::post('{slug}/import/preview', [MasterController::class, 'importPreview']);
        Route::post('{slug}/import/commit', [MasterController::class, 'importCommit']);
        Route::get('{slug}', [MasterController::class, 'list']);
        Route::post('{slug}', [MasterController::class, 'store']);
        Route::get('{slug}/{id}', [MasterController::class, 'show'])->whereNumber('id');
        Route::put('{slug}/{id}', [MasterController::class, 'update'])->whereNumber('id');
        Route::delete('{slug}/{id}', [MasterController::class, 'destroy'])->whereNumber('id');
    });

// ---- Per-master default sort order (admin-configured, applied on every list) --
// Dedicated prefix, kept OUT of the masters group so the MenuGuard masters/{slug}
// mapping never mistakes "sort-config" for a slug. Same admin gating.
Route::prefix('master-sort')
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api'])
    ->group(function () {
        Route::get('/', [MasterController::class, 'sortConfig']);
        Route::post('{slug}', [MasterController::class, 'sortSave']);
    });

// ---- Pooja Sequence Builder — step manager grouped by pooja -----------------
Route::prefix('pooja-sequence')
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api'])
    ->group(function () {
        $c = \App\Http\Controllers\Api\PoojaSequenceController::class;
        Route::get('poojas', [$c, 'poojas']);
        Route::get('steps', [$c, 'steps']);
        Route::post('reorder', [$c, 'reorder']);
        Route::post('import', [$c, 'import']);
    });

// ---- Nam Sankalan — the collection of names (108/1008 …) for a deity ---------
// Child rows of the Deity master (deity_names, FK deity_id). Shown as a tab in
// the Deity edit screen. Same admin gating as the masters it belongs to.
Route::prefix('deity-names')
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api'])
    ->group(function () {
        $c = \App\Http\Controllers\Api\DeityNameController::class;
        Route::get('{deityId}', [$c, 'list'])->whereNumber('deityId');
        Route::post('{deityId}', [$c, 'store'])->whereNumber('deityId');
        Route::post('{deityId}/bulk', [$c, 'bulk'])->whereNumber('deityId');
        Route::put('{deityId}/{id}', [$c, 'update'])->whereNumber('deityId')->whereNumber('id');
        Route::delete('{deityId}/{id}', [$c, 'destroy'])->whereNumber('deityId')->whereNumber('id');
    });

// ---- Pandit Assign — multiple pandits per Scheduled e-Pooja -----------------
Route::prefix('scheduled-pooja-pandits')
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api'])
    ->group(function () {
        $c = \App\Http\Controllers\Api\ScheduledPoojaPanditController::class;
        Route::get('{poojaId}', [$c, 'list'])->whereNumber('poojaId');
        Route::post('{poojaId}', [$c, 'store'])->whereNumber('poojaId');
        Route::delete('{poojaId}/{id}', [$c, 'destroy'])->whereNumber('poojaId')->whereNumber('id');
    });

// ---- Module 7: Finance — revenue split engine + auditable ledger ----------
// Preview open to finance-capable roles; posting restricted to super_admin.
Route::prefix('finance')
    ->middleware(['auth:sanctum', 'throttle:api'])
    ->group(function () {
        Route::middleware('role:super_admin,trust_manager')->group(function () {
            Route::post('revenue/preview', [\App\Http\Controllers\Api\FinanceController::class, 'preview']);
            Route::get('revenue/summary', [\App\Http\Controllers\Api\FinanceController::class, 'summary']);
        });
        Route::middleware('role:super_admin')->group(function () {
            Route::post('revenue/post', [\App\Http\Controllers\Api\FinanceController::class, 'post']);
        });
    });

// ---- Commission & Incentive engine (multi-level, actor-attributed) --------
// Read/report open to admin roles; disbursement + hierarchy edits gated tighter.
Route::prefix('commission')
    ->middleware(['auth:sanctum', 'throttle:api'])
    ->group(function () {
        Route::middleware('role:super_admin,trust_manager')->group(function () {
            Route::get('summary', [\App\Http\Controllers\Api\CommissionController::class, 'summary']);
            Route::get('incentive-report', [\App\Http\Controllers\Api\CommissionController::class, 'incentiveReport']);
            Route::get('entries', [\App\Http\Controllers\Api\CommissionController::class, 'entries']);
            Route::get('incentives', [\App\Http\Controllers\Api\CommissionController::class, 'incentives']);
            Route::get('hierarchy', [\App\Http\Controllers\Api\CommissionController::class, 'hierarchy']);
            Route::post('release-due', [\App\Http\Controllers\Api\CommissionController::class, 'releaseDue']);
            Route::post('incentives/compute', [\App\Http\Controllers\Api\CommissionController::class, 'computeIncentives']);
        });
        Route::middleware('role:super_admin')->group(function () {
            Route::post('entries/mark-paid', [\App\Http\Controllers\Api\CommissionController::class, 'markPaid']);
            Route::post('entries/{id}/status', [\App\Http\Controllers\Api\CommissionController::class, 'setEntryStatus'])->whereNumber('id');
            Route::post('incentives/{id}/status', [\App\Http\Controllers\Api\CommissionController::class, 'setIncentiveStatus'])->whereNumber('id');
            Route::post('hierarchy', [\App\Http\Controllers\Api\CommissionController::class, 'setHierarchy']);
        });
        // A pandit / franchise can see their own earnings statement.
        Route::get('statement', [\App\Http\Controllers\Api\CommissionController::class, 'statement']);
    });

// ---- Pandit ↔ Service mapping (catalogue services + per-pandit charges) ----
Route::prefix('admin/pandit-service-map')
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api'])
    ->group(function () {
        Route::get('/', [\App\Http\Controllers\Api\PanditServiceMapController::class, 'data']);
        Route::get('{panditId}', [\App\Http\Controllers\Api\PanditServiceMapController::class, 'get'])->whereNumber('panditId');
        Route::post('{panditId}', [\App\Http\Controllers\Api\PanditServiceMapController::class, 'save'])->whereNumber('panditId');
    });

// ---- Formula Engine — run / test dynamically-bound formulas ---------------
Route::prefix('formula')
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api'])
    ->group(function () {
        Route::post('run', [\App\Http\Controllers\Api\FormulaController::class, 'run']);
        Route::post('test', [\App\Http\Controllers\Api\FormulaController::class, 'test']);
    });

// ---- Maker-checker approvals (four-eyes) — checker-gated -------------------
Route::prefix('approvals')
    ->middleware(['auth:sanctum', 'role:super_admin', 'throttle:api'])
    ->group(function () {
        Route::get('/', [ApprovalController::class, 'index']);
        Route::post('{id}/approve', [ApprovalController::class, 'approve'])->whereNumber('id');
        Route::post('{id}/reject', [ApprovalController::class, 'reject'])->whereNumber('id');
    });

// ---- Module 3: Reports (config-driven, read-side + export) -----------------
Route::prefix('reports')
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api'])
    ->group(function () {
        Route::get('/', [ReportController::class, 'index']);
        Route::get('{slug}/meta', [ReportController::class, 'meta']);
        Route::get('{slug}/export', [ReportController::class, 'export']);
        Route::get('{slug}', [ReportController::class, 'run']);
    });

// ---- Module 4: KYC / documents (user upload + admin review) ----------------
Route::prefix('kyc')->middleware(['auth:sanctum', 'throttle:api'])->group(function () {
    // Any authenticated user manages their own documents.
    Route::get('my', [KycController::class, 'my']);
    Route::get('required-docs', [KycController::class, 'requiredDocs']);
    Route::post('upload', [KycController::class, 'upload']);

    // Admin / trust: review queue + decisions.
    Route::middleware('role:super_admin,trust_manager')->group(function () {
        Route::get('queue', [KycController::class, 'queue']);
        Route::post('{id}/review', [KycController::class, 'review'])->whereNumber('id');
    });
});

// ---- Self-service account-category upgrade ---------------------------------
Route::prefix('upgrade')->middleware(['auth:sanctum', 'throttle:api'])->group(function () {
    // Applicant (any authenticated user)
    Route::get('state', [\App\Http\Controllers\Api\UpgradeController::class, 'state']);
    Route::get('my-roles', [\App\Http\Controllers\Api\UpgradeController::class, 'myRoles']);
    Route::post('apply', [\App\Http\Controllers\Api\UpgradeController::class, 'apply']);
    Route::post('withdraw', [\App\Http\Controllers\Api\UpgradeController::class, 'withdraw']);

    // Admin / trust review
    Route::middleware('role:super_admin,trust_manager')->group(function () {
        Route::get('queue', [\App\Http\Controllers\Api\UpgradeController::class, 'queue']);
        Route::post('{id}/review', [\App\Http\Controllers\Api\UpgradeController::class, 'review'])->whereNumber('id');
    });
});

// ---- Module 5: Catalog (public) + Bookings ---------------------------------
Route::prefix('catalog')->middleware('throttle:api')->group(function () {
    Route::get('poojas', [CatalogController::class, 'poojas']);
    Route::get('poojas/{id}', [CatalogController::class, 'pooja'])->whereNumber('id');
    Route::get('categories', [CatalogController::class, 'categories']);
    Route::get('services', [CatalogController::class, 'services']);
    // Service-booking rate card (public) — port of booking.php.
    Route::get('booking-services', [CatalogController::class, 'bookingServices']);
    Route::get('booking-services/{id}/addons', [CatalogController::class, 'bookingServiceAddons'])->whereNumber('id');
});

Route::prefix('bookings')->middleware(['auth:sanctum', 'throttle:api'])->group(function () {
    // Own bookings (any authenticated user acting as yajman).
    Route::get('mine', [BookingController::class, 'mine']);
    Route::get('mine/{id}', [BookingController::class, 'show'])->whereNumber('id');
    Route::post('/', [BookingController::class, 'store']);

    // Admin / trust: full list + status/quote.
    Route::middleware('role:super_admin,trust_manager')->group(function () {
        Route::get('/', [BookingController::class, 'index']);
        Route::post('{id}/status', [BookingController::class, 'status'])->whereNumber('id');
        Route::post('{id}/quote', [BookingController::class, 'quote'])->whereNumber('id');
    });
});

// ---- Module 6: Payments (self-hosted UPI + Razorpay, settlement dispatch) ---
// Webhook is PUBLIC — authenticated by HMAC signature only (API group is CSRF-exempt).
Route::post('pay/webhook', [PaymentController::class, 'webhook']);

Route::prefix('pay')->middleware(['auth:sanctum', 'throttle:api'])->group(function () {
    // Checkout (any authenticated user, scoped to their own booking).
    Route::post('booking/{id}', [PaymentController::class, 'createForBooking'])->whereNumber('id');
    Route::post('{ref}/upi', [PaymentController::class, 'submitUpi']);
    Route::post('{ref}/capture', [PaymentController::class, 'capture']);
    // Devanagari-capable PDF receipt (owner of the booking, or admin).
    Route::get('{ref}/receipt.pdf', [PdfController::class, 'receipt']);
    Route::get('{ref}', [PaymentController::class, 'show']);

    // Admin / trust: ledger + verification + refunds.
    Route::middleware('role:super_admin,trust_manager')->group(function () {
        Route::get('/', [PaymentController::class, 'ledger']);
        Route::post('{ref}/verify', [PaymentController::class, 'verify']);
        Route::post('{ref}/reject', [PaymentController::class, 'reject']);
        Route::post('{ref}/refund', [PaymentController::class, 'refund']);
    });
});

// ---- Module 7: Shop (vendor product orders) + coupons ----------------------
Route::prefix('shop')->middleware('throttle:api')->group(function () {
    // Public catalog.
    Route::get('products', [ShopController::class, 'products']);
    Route::get('product/{sku}', [ShopController::class, 'showProduct']);

    Route::middleware('auth:sanctum')->group(function () {
        Route::post('coupon/check', [ShopController::class, 'checkCoupon']);
        Route::post('orders', [ShopController::class, 'createOrder']);
        Route::get('orders/mine', [ShopController::class, 'myOrders']);
        Route::get('orders/{ref}', [ShopController::class, 'show']);

        // Admin order list + fulfilment lifecycle.
        Route::middleware('role:super_admin,trust_manager')->group(function () {
            Route::get('orders', [ShopController::class, 'index']);
            Route::get('orders-summary', [ShopController::class, 'summary']);
            Route::post('orders/{ref}/status', [ShopController::class, 'updateStatus']);
        });
    });
});

// ---- Vendor self-serve (select products, set stock & price, view payouts) --
Route::prefix('vendor')->middleware(['auth:sanctum', 'throttle:api'])->group(function () {
    Route::get('me', [\App\Http\Controllers\Api\VendorController::class, 'me']);
    Route::get('catalog', [\App\Http\Controllers\Api\VendorController::class, 'catalog']);
    Route::post('offer', [\App\Http\Controllers\Api\VendorController::class, 'saveOffer']);
    Route::delete('offer/{sku}', [\App\Http\Controllers\Api\VendorController::class, 'deleteOffer']);
    Route::get('sales', [\App\Http\Controllers\Api\VendorController::class, 'sales']);
});

// ---- Module 8: Group Pooja (Bhakti Setu) -----------------------------------
Route::prefix('group')->middleware('throttle:api')->group(function () {
    // Public offerings.
    Route::get('poojas', [GroupController::class, 'index']);
    Route::get('poojas/{id}', [GroupController::class, 'show'])->whereNumber('id');

    Route::middleware('auth:sanctum')->group(function () {
        Route::post('poojas/{id}/join', [GroupController::class, 'join'])->whereNumber('id');
        Route::get('participants/{ref}', [GroupController::class, 'participant']);

        // Admin participant list + fulfilment.
        Route::middleware('role:super_admin,trust_manager')->group(function () {
            Route::get('participants', [GroupController::class, 'participants']);
            Route::post('participants/{ref}/fulfil', [GroupController::class, 'fulfil']);
        });
    });
});

// ---- Module 10: Experts directory + Consultations --------------------------
Route::prefix('experts')->middleware('throttle:api')->group(function () {
    Route::get('/', [ExpertController::class, 'index']);
    Route::get('{id}', [ExpertController::class, 'show'])->whereNumber('id');
});

// ---- Module 11: Pooja Lead Marketplace -------------------------------------
Route::prefix('leads')->middleware('throttle:api')->group(function () {
    // Public: create a lead (open or pandit-assigned), track by ref, award an offer.
    Route::post('/', [\App\Http\Controllers\Api\LeadController::class, 'store']);
    Route::get('track/{ref}', [\App\Http\Controllers\Api\LeadController::class, 'track']);
    Route::post('{ref}/award', [\App\Http\Controllers\Api\LeadController::class, 'award']);
    Route::post('{ref}/assign', [\App\Http\Controllers\Api\LeadController::class, 'assign']);

    Route::middleware('auth:sanctum')->group(function () {
        // Client's own leads.
        Route::get('mine', [\App\Http\Controllers\Api\LeadController::class, 'mine']);
        // Pandit marketplace + offers.
        Route::get('marketplace', [\App\Http\Controllers\Api\LeadController::class, 'marketplace']);
        Route::post('{ref}/offer', [\App\Http\Controllers\Api\LeadController::class, 'offer']);
        // Admin listing.
        Route::middleware('role:super_admin,trust_manager')->group(function () {
            Route::get('/', [\App\Http\Controllers\Api\LeadController::class, 'index']);
        });
    });
});

Route::prefix('consultations')->middleware(['auth:sanctum', 'throttle:api'])->group(function () {
    // Client.
    Route::post('/', [ConsultationController::class, 'store']);
    Route::get('mine', [ConsultationController::class, 'mine']);

    // Pandit portal.
    Route::middleware('role:pandit')->group(function () {
        Route::get('pandit', [ConsultationController::class, 'forPandit']);
    });

    // Status transition — pandit (own) OR admin (authorised in the service).
    Route::post('{ref}/status', [ConsultationController::class, 'status']);

    // Admin list.
    Route::middleware('role:super_admin,trust_manager')->group(function () {
        Route::get('/', [ConsultationController::class, 'index']);
    });
});

// ---- Seva Exchange (pandit/yajman coordination marketplace) ----------------
Route::prefix('seva')->middleware(['auth:sanctum', 'throttle:api'])->group(function () {
    Route::get('/', [SevaController::class, 'index']);
    Route::post('/', [SevaController::class, 'store']);
    Route::get('mine/offers', [SevaController::class, 'myOffers']);
    Route::get('mine/responses', [SevaController::class, 'myResponses']);
    Route::get('mine/reminders', [SevaController::class, 'myReminders']);
    Route::get('services', [SevaController::class, 'services']);
    // Unified console.
    Route::get('console', [SevaController::class, 'console']);
    // Shared dropdown data (services/poojas + pandits) for booking + edit forms.
    Route::get('console/options', [SevaController::class, 'consoleOptions']);
    // ── Pandit assignment tab (authed; per-action permission enforced) ──
    Route::get('assign/open', [SevaController::class, 'assignOpen']);
    Route::get('assign/{id}', [SevaController::class, 'assignDetail'])->whereNumber('id');
    Route::post('assign/offer', [SevaController::class, 'assignOffer']);
    Route::post('assign/accept', [SevaController::class, 'assignAccept']);
    Route::post('assign/assign', [SevaController::class, 'assignPandit']);
    Route::post('assign/bulk', [SevaController::class, 'assignBulk']);
    Route::post('assign/confirm', [SevaController::class, 'assignConfirm']);
    Route::post('assign/modify', [SevaController::class, 'assignModify']);
    Route::post('assign/cancel', [SevaController::class, 'assignCancel']);
    // Feedback on completed inquiries (pandit / owner).
    Route::get('feedback/{id}', [SevaController::class, 'exchangeFeedbackList'])->whereNumber('id');
    Route::post('feedback', [SevaController::class, 'exchangeFeedbackSubmit']);
    // Quote (offer a fee) + accept — authed; per-record permission enforced in
    // the controller (pandit/expert or the posting client).
    Route::post('console/quote', [SevaController::class, 'consoleQuote']);
    Route::post('console/accept', [SevaController::class, 'consoleAccept']);
    // Status change — managers (super_admin / trust_manager).
    Route::middleware('role:super_admin,trust_manager')->group(function () {
        Route::post('console/status', [SevaController::class, 'consoleStatus']);
    });
    // Edit + delete — authed; status/role/24h rules enforced in the service.
    Route::get('console/row/{id}', [SevaController::class, 'consoleRow'])->whereNumber('id');
    Route::post('console/update', [SevaController::class, 'consoleUpdate']);
    Route::post('console/delete', [SevaController::class, 'consoleDelete']);
    // Mutual confirm + negotiation (either party) on a response.
    Route::post('responses/{responseId}/confirm', [SevaController::class, 'confirm'])->whereNumber('responseId');
    Route::post('responses/{responseId}/negotiate', [SevaController::class, 'negotiate'])->whereNumber('responseId');
    Route::get('responses/{responseId}/negotiation', [SevaController::class, 'negotiation'])->whereNumber('responseId');
    // Public provider rating summary (from confirmed-seva provider feedback).
    Route::get('pandit/{panditId}/rating', [SevaController::class, 'panditRating'])->whereNumber('panditId');
    // Admin: run due reminders now (before the production cron is wired).
    Route::post('admin/reminders/dispatch', [SevaController::class, 'dispatchReminders'])
        ->middleware('role:super_admin,trust_manager');
    Route::get('{id}', [SevaController::class, 'show'])->whereNumber('id');
    Route::post('{id}/respond', [SevaController::class, 'respond'])->whereNumber('id');
    Route::post('{id}/withdraw', [SevaController::class, 'withdraw'])->whereNumber('id');
    Route::post('{id}/cancel', [SevaController::class, 'cancel'])->whereNumber('id');
    Route::post('{id}/complete', [SevaController::class, 'complete'])->whereNumber('id');
    Route::post('{id}/feedback', [SevaController::class, 'feedback'])->whereNumber('id');
    Route::get('{id}/feedback', [SevaController::class, 'feedbackList'])->whereNumber('id');
});

// ---- Pandit Skill Mapping (pandit ↔ services, grouped by service category) --
// Any authenticated user; an admin may target any pandit, a pandit is locked to self.
Route::prefix('pandit-skills')->middleware(['auth:sanctum', 'throttle:api'])->group(function () {
    Route::get('context', [\App\Http\Controllers\Api\PanditSkillController::class, 'context']);
    Route::get('mapped', [\App\Http\Controllers\Api\PanditSkillController::class, 'mapped']);
    Route::get('services', [\App\Http\Controllers\Api\PanditSkillController::class, 'services']);
    Route::post('save', [\App\Http\Controllers\Api\PanditSkillController::class, 'save']);
});

// ---- Module 13: Content + Panchang (public read) ---------------------------
Route::prefix('panchang')->middleware('throttle:api')->group(function () {
    Route::get('today', [PanchangController::class, 'today']);
});

// Registered users share a day's Panchang (branded with pandit profile if pandit).
Route::post('panchang/share', [PanchangShareController::class, 'create'])
    ->middleware(['auth:sanctum', 'throttle:api']);

Route::prefix('content')->middleware('throttle:api')->group(function () {
    Route::get('articles', [ContentController::class, 'articles']);
    Route::get('articles/{slug}', [ContentController::class, 'article']);
    Route::get('tirths', [ContentController::class, 'tirths']);
    Route::get('tirths/{slug}', [ContentController::class, 'tirth']);
    Route::get('festivals', [ContentController::class, 'festivals']);
    Route::get('horoscopes', [ContentController::class, 'horoscopes']);
});

// ---- Module 12: AI agents + consult wallet + leads -------------------------
Route::prefix('ai')->middleware('throttle:api')->group(function () {
    // Public directory.
    Route::get('agents', [AiController::class, 'agents']);
    // TEMPORARY diagnostic — remove after the "Agent not found" issue is resolved.
    // Shows how AI agents and AI-pandit rows are keyed, so a mismatch is visible.
    Route::get('_diag', function () {
        $out = ['ai_agents' => [], 'ai_pandits' => []];
        try {
            $out['ai_agents'] = \Illuminate\Support\Facades\DB::table('ai_agents')
                ->get(['id', 'agent_key', 'name', 'is_active', 'is_template', 'owner_pandit_id']);
        } catch (\Throwable $e) {
            $out['ai_agents_err'] = $e->getMessage();
        }
        try {
            if (\Illuminate\Support\Facades\Schema::hasColumn('pandits', 'is_ai')) {
                $cols = ['id', 'full_name', 'is_active'];
                foreach (['is_ai', 'ai_agent_key'] as $c) {
                    if (\Illuminate\Support\Facades\Schema::hasColumn('pandits', $c)) {
                        $cols[] = $c;
                    }
                }
                $out['ai_pandits'] = \Illuminate\Support\Facades\DB::table('pandits')->where('is_ai', 1)->get($cols);
            }
        } catch (\Throwable $e) {
            $out['ai_pandits_err'] = $e->getMessage();
        }
        return response()->json($out);
    });
    Route::get('agents/{key}', [AiController::class, 'agent']);
    // Suggested / most-asked questions for an agent (shown as chips on chat open).
    Route::get('{key}/suggested', [AiController::class, 'suggested']);

    Route::middleware('auth:sanctum')->group(function () {
        Route::get('consults/mine', [AiController::class, 'myConsults']);
        // Persisted session transcript (owner only) — JSON + Devanagari PDF.
        Route::get('consults/{ref}/messages', [AiController::class, 'sessionMessages']);
        Route::get('consults/{ref}/transcript.pdf', [PdfController::class, 'aiSessionTranscript']);
        Route::get('leads', [AiController::class, 'leads']);
        Route::post('{key}/chat', [AiController::class, 'chat']);
        Route::post('{key}/consult', [AiController::class, 'buyConsult']);
        Route::post('{key}/request-expert', [AiController::class, 'requestExpert']);
    });
});

// ---- Admin: AI Pandit console — agents + KB training (port of admin/ai-agent*) ----
Route::prefix('admin/ai-agents')
    ->middleware(['auth:sanctum', 'role:super_admin', 'throttle:api'])
    ->group(function () {
        Route::get('/', [AdminAiController::class, 'agents']);
        Route::post('/', [AdminAiController::class, 'agentCreate']);
        Route::get('{key}', [AdminAiController::class, 'agentGet']);
        Route::post('{key}/edit', [AdminAiController::class, 'agentQuickEdit']);
        Route::post('{key}', [AdminAiController::class, 'agentSave']);
        Route::post('{key}/toggle', [AdminAiController::class, 'agentToggle']);
        Route::delete('{key}', [AdminAiController::class, 'agentDelete']);
        Route::get('{key}/kb', [AdminAiController::class, 'kbList']);
        Route::post('{key}/kb', [AdminAiController::class, 'kbSave']);
        Route::post('{key}/kb/{id}/toggle', [AdminAiController::class, 'kbToggle'])->whereNumber('id');
        Route::delete('{key}/kb/{id}', [AdminAiController::class, 'kbDelete'])->whereNumber('id');
    });

// ---- Admin: Common Knowledge Bank (shared categorised topics) --------------
Route::prefix('admin/ai-knowledge')
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api'])
    ->group(function () {
        Route::get('/', [\App\Http\Controllers\Api\AiKnowledgeBankController::class, 'index']);
        Route::get('meta', [\App\Http\Controllers\Api\AiKnowledgeBankController::class, 'metaEndpoint']);
        Route::post('/', [\App\Http\Controllers\Api\AiKnowledgeBankController::class, 'save']);
        Route::post('assign', [\App\Http\Controllers\Api\AiKnowledgeBankController::class, 'assign']);
        Route::post('assign-by-category', [\App\Http\Controllers\Api\AiKnowledgeBankController::class, 'assignByCategory']);
        Route::get('agent/{key}', [\App\Http\Controllers\Api\AiKnowledgeBankController::class, 'agentHas']);
        Route::delete('{id}', [\App\Http\Controllers\Api\AiKnowledgeBankController::class, 'destroy'])->whereNumber('id');
    });

// ---- Admin: AI provider settings (port of admin/ai-settings) ----------------
Route::prefix('admin/ai-settings')
    ->middleware(['auth:sanctum', 'role:super_admin', 'throttle:api'])
    ->group(function () {
        Route::get('/', [AdminAiController::class, 'settingsGet']);
        Route::post('/', [AdminAiController::class, 'settingsSave']);
    });

// ---- Module 11: Chat + WebRTC calling (comm suite) -------------------------
Route::prefix('chat')->middleware(['auth:sanctum', 'throttle:api'])->group(function () {
    Route::get('conversations', [ChatController::class, 'conversations']);
    Route::get('unread', [ChatController::class, 'unread']);
    Route::post('start', [ChatController::class, 'start']);
    Route::get('{id}/messages', [ChatController::class, 'messages'])->whereNumber('id');
    Route::post('{id}/send', [ChatController::class, 'send'])->whereNumber('id');
    // Devanagari-capable PDF transcript (members only).
    Route::get('{id}/transcript.pdf', [PdfController::class, 'conversationTranscript'])->whereNumber('id');
});

Route::prefix('call')->middleware(['auth:sanctum', 'throttle:api'])->group(function () {
    Route::get('ice', [CallController::class, 'ice']);
    Route::get('incoming', [CallController::class, 'incoming']);
    Route::post('start', [CallController::class, 'start']);
    Route::get('{id}', [CallController::class, 'show'])->whereNumber('id');
    Route::post('{id}/signal', [CallController::class, 'signal'])->whereNumber('id');
    Route::get('{id}/signals', [CallController::class, 'signals'])->whereNumber('id');
    Route::post('{id}/{action}', [CallController::class, 'transition'])->whereNumber('id')->where('action', 'answer|decline|end');
});

// Public — the detailed Panchang page reads this for a given day.
Route::get('day-specials/for-date', [DaySpecialController::class, 'forDate']);

// Admin — single "Festivals & Special Days" master.
Route::middleware(['auth:sanctum', 'role:super_admin,trust_manager'])->group(function () {
    Route::get('admin/day-specials', [DaySpecialController::class, 'index']);
    Route::post('admin/day-specials', [DaySpecialController::class, 'store']);
    Route::put('admin/day-specials/{id}', [DaySpecialController::class, 'update'])->whereNumber('id');
    Route::delete('admin/day-specials/{id}', [DaySpecialController::class, 'destroy'])->whereNumber('id');
});

// ---- Community Moments (announcements) -------------------------------------
// Public — only published rows; joyful & condolence returned as separate streams.
Route::get('announcements', [AnnouncementController::class, 'publicList']);
Route::get('announcements/types', [AnnouncementController::class, 'types']);
Route::get('announcements/{id}/comments', [AnnouncementController::class, 'comments'])->whereNumber('id');
Route::post('announcements/{id}/like', [AnnouncementController::class, 'like'])->whereNumber('id')->middleware('throttle:api');
Route::post('announcements/{id}/comments', [AnnouncementController::class, 'addComment'])->whereNumber('id')->middleware('throttle:api');
// Public submission from the main page (anyone can apply; admin approves before it
// ever shows). Rate-limited to curb abuse; submitter user id is captured if logged in.
Route::post('announcements', [AnnouncementController::class, 'submit'])->middleware('throttle:api');

// Authenticated devotee — see own submissions.
Route::middleware(['auth:sanctum', 'throttle:api'])->group(function () {
    Route::get('announcements/mine', [AnnouncementController::class, 'mine']);
});

// Admin moderation — approval + phone-call double-confirmation for birth/death.
Route::middleware(['auth:sanctum', 'role:super_admin,trust_manager'])->group(function () {
    Route::get('admin/announcements', [AnnouncementController::class, 'adminList']);
    Route::post('admin/announcements/{id}/confirm-call', [AnnouncementController::class, 'confirmCall'])->whereNumber('id');
    Route::post('admin/announcements/{id}/approve', [AnnouncementController::class, 'approve'])->whereNumber('id');
    Route::post('admin/announcements/{id}/reject', [AnnouncementController::class, 'reject'])->whereNumber('id');
    Route::delete('admin/announcements/{id}', [AnnouncementController::class, 'destroy'])->whereNumber('id');
});

// ---- Module 9: Notifications (admin console) -------------------------------
Route::prefix('notifications')
    ->middleware(['auth:sanctum', 'role:super_admin,trust_manager', 'throttle:api'])
    ->group(function () {
        Route::get('/', [NotificationController::class, 'index']);
        Route::post('test', [NotificationController::class, 'test']);
        Route::post('mode', [NotificationController::class, 'setMode']);
        Route::post('{id}/retry', [NotificationController::class, 'retry'])->whereNumber('id');
    });

// ---- Jyotish Workbench (astrologer console) ---------------------------------
// Client records, charts, consultations and calculation profiles. Everything is
// scoped server-side to the signed-in astrologer: client birth data is personal
// data under the DPDP Act, so there is no cross-practice read path.
Route::prefix('jyotish')
    ->middleware(['auth:sanctum', 'throttle:api'])
    ->group(function () {
        $jw = \App\Http\Controllers\Api\JyotishWorkbenchController::class;

        // Clients — the literal route is declared BEFORE {id} so it is not
        // swallowed by the numeric parameter.
        Route::get('clients/due-erasure', [$jw, 'clientsDueErasure']);
        Route::get('clients', [$jw, 'clientIndex']);
        Route::post('clients', [$jw, 'clientStore']);
        Route::get('clients/{id}', [$jw, 'clientShow'])->whereNumber('id');
        Route::put('clients/{id}', [$jw, 'clientUpdate'])->whereNumber('id');
        Route::post('clients/{id}/archive', [$jw, 'clientArchive'])->whereNumber('id');
        Route::delete('clients/{id}', [$jw, 'clientErase'])->whereNumber('id');

        // Client timeline
        Route::get('clients/{id}/notes', [$jw, 'noteIndex'])->whereNumber('id');
        Route::post('clients/{id}/notes', [$jw, 'noteStore'])->whereNumber('id');
        Route::put('notes/{noteId}', [$jw, 'noteUpdate'])->whereNumber('noteId');
        Route::delete('notes/{noteId}', [$jw, 'noteDestroy'])->whereNumber('noteId');
        Route::get('reminders', [$jw, 'reminders']);

        // Charts
        Route::get('charts', [$jw, 'chartIndex']);
        Route::post('charts', [$jw, 'chartStore']);
        Route::get('charts/{uuid}', [$jw, 'chartShow']);
        Route::post('charts/{uuid}/sections', [$jw, 'chartSections']);
        Route::put('charts/{uuid}', [$jw, 'chartUpdate']);
        Route::post('charts/{uuid}/rectify', [$jw, 'chartRectify']);
        Route::post('charts/{uuid}/archive', [$jw, 'chartArchive']);
        Route::delete('charts/{uuid}', [$jw, 'chartDestroy']);

        // Consultations
        Route::get('consultations', [$jw, 'consultationIndex']);
        Route::post('consultations', [$jw, 'consultationStore']);
        Route::put('consultations/{id}', [$jw, 'consultationUpdate'])->whereNumber('id');

        // Calculation profiles
        Route::get('preferences', [$jw, 'preferences']);
        Route::post('preferences', [$jw, 'savePreferences']);

        // Command registry — the whole UI surface (menus, context menus,
        // shortcuts, palette) is served from data, not hard-coded in the client.
        Route::get('commands', [$jw, 'commands']);
        Route::get('commands/menu', [$jw, 'commandMenu']);
        Route::get('coverage', [$jw, 'coverage']);
        Route::post('charts/{uuid}/run', [$jw, 'runCommand']);

        // Divisional charts under named schemes (23 divisions, 65 schemes)
        // Basic Info panel — nava taras, yogi trio, graha yuddha, latta, sahams
        Route::get('charts/{uuid}/basic-info', [$jw, 'basicInfo']);

        // Ashtakavarga depth — prastara, sodhana reductions, pindas
        Route::get('charts/{uuid}/ashtakavarga', [$jw, 'ashtakavarga']);

        // Rasi dashas — Narayana and variants, Chara, Sudasa, Trikona, Kendradi
        Route::get('charts/{uuid}/rasi-dashas', [$jw, 'rasiDashas']);

        // Nakshatra dashas — Vimshottari under each of its eight seeds
        Route::get('charts/{uuid}/nakshatra-dashas', [$jw, 'nakshatraDashas']);

        // Ayur dashas — Shoola dasa and the five read for relatives
        Route::get('charts/{uuid}/ayur-dashas', [$jw, 'ayurDashas']);

        // Gochara — vedha, taras, murthis and the ashtakavarga bindu thresholds
        Route::get('charts/{uuid}/gochara', [$jw, 'gochara']);

        /* Transits — what each transiting planet occupies and aspects, the
           houses it holds from each natal reference, the divisional
           cross-reading and the sodhya-pinda timing points. Date-relative,
           so never served from cache. */
        Route::get('charts/{uuid}/transits', [$jw, 'transits']);

        /* Highlight sets for the chart's right-click menu — dignities by
           degree arc, the rasi a planet stands in, the rasis tenanted in a
           varga, and drishti on a nakshatra by the portion it covers. */
        Route::get('charts/{uuid}/highlights', [$jw, 'highlights']);
        // Sarvatobhadra and Kota chakras, with the vedha reading for a date.
        // The section serves the boards from cache; this serves the strike.
        Route::get('charts/{uuid}/chakras', [$jw, 'chakras']);


        // Argala and virodhargala
        Route::get('charts/{uuid}/argala', [$jw, 'argala']);

        Route::get('varga-schemes', [$jw, 'vargaSchemes']);
        Route::get('charts/{uuid}/vargas', [$jw, 'vargas']);
        Route::get('charts/{uuid}/varga-custom', [$jw, 'vargaCustom']);
        Route::get('charts/{uuid}/varga-sub', [$jw, 'vargaSub']);
        Route::get('charts/{uuid}/varga/{division}', [$jw, 'varga'])->whereNumber('division');
    });
