<?php

declare(strict_types=1);

namespace App\Http\Controllers\Support;

use Hypervel\Support\Facades\Route;
use Hypervel\Support\Facades\Auth;
use App\Enums\UserTypes;
use App\Support\ModuleHelper;

/**
 * VueRouteMap handles automated registration of Vue SPA pages mapped via the Custom Inertia setup.
 * It provides a modular way to handle ViewMap functionality without cluttering web.php.
 */
class VueRouteMap
{
    /**
     * Define the route mappings here.
     * key: The URI route
     * value: An array with:
     *   - 'component' (string): The Vue component path (e.g. 'ListProductsMarket')
     *   - 'middlewares' (array|string): Optional middlewares to apply to this route
     *   - 'name' (string): Optional route name
     *   - 'loginRequired' (bool): Whether authentication is required to access this page
     *   - 'allowedUserTypes' (array): List of allowed user types who can view this page
     */
    protected static array $routes = [
        /*
     |--------------------------------------------------------------------------
     | Example Usage
     |--------------------------------------------------------------------------
     |
     | '/my-path' => [
     |     'component'       => 'MyVueComponent',
     |     'middlewares'     => ['auth'],
     |     'name'            => 'my.route.name',
     |     'loginRequired'   => true,
     |     'allowedUserTypes' => ['ult', 'operator'],
     | ],
     */

        // Public pages - no login required
        '/' => [
            'component'       => 'Home',
            'loginRequired'   => false,
        ],
        '/app' => [
            'component'       => 'Home',
            'loginRequired'   => false,
        ],
        '/bukidbountyapp' => [
            'component'       => 'Home',
            'loginRequired'   => false,
        ],

        // Market pages - public access
        '/list-products-market' => [
            'component'       => 'ListProductsMarket',
            'loginRequired'   => false,
        ],
        '/list-stores' => [
            'component'       => 'ListStores',
            'loginRequired'   => false,
        ],
        '/my-stores' => [
            'component'       => 'MyStores',
            'loginRequired'   => true,
            'module'          => 'stores',
        ],
        '/buy-view-product-market' => [
            'component'       => 'BuyViewProductMarket',
            'loginRequired'   => false,
        ],
        '/view-store-market' => [
            'component'       => 'ViewStoreMarket',
            'loginRequired'   => false,
        ],
        '/view-all-photos' => [
            'component'       => 'ViewAllPhotos',
            'loginRequired'   => false,
        ],
        '/photo-viewer' => [
            'component'       => 'PhotoViewer',
            'loginRequired'   => false,
        ],
        '/create-store' => [
            'component'       => 'CreateStore',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner'],
            'module'          => 'stores',
        ],
        '/pos' => [
            'component'       => 'PosMain',
            'loginRequired'   => false,
            'module'          => 'pos',
        ],

        // Account settings - requires login
        '/account-settings' => [
            'component'       => 'AccountSettings',
            'loginRequired'   => true,
        ],

        '/create-user' => [
            'component'       => 'CreateUser',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'coordinator', 'store owner', 'store manager', 'supplier overseer', 'supplier'],
        ],

        // Administrative & Management pages
        '/create-product' => [
            'component'       => 'CreateProductUltimate',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner'],
            'module'          => 'products',
        ],
        '/add-products-to-store' => [
            'component'       => 'AddProductsToStore',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
            'module'          => 'stores',
        ],
        '/create-product-store-owner' => [
            'component'       => 'CreateProductStoreOwner',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
            'module'          => 'products',
        ],
        '/edit-product' => [
            'component'       => 'EditProductUltimate',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner'],
            'module'          => 'products',
        ],
        '/edit-store' => [
            'component'       => 'EditStoreUltimate',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
            'module'          => 'stores',
        ],
        '/transfer-credit' => [
            'component'       => 'TransferMyCredit',
            'loginRequired'   => true,
            'module'          => 'credits',
        ],
        '/user-list' => [
            'component'       => 'UserList',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'audit'],
        ],
        '/manage-transactions' => [
            'component'       => 'ManageGlobalTransactions',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator'],
            'module'          => 'transactions',
        ],
        '/remove-product' => [
            'component'       => 'RemoveProductFromStoreAdmin',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator'],
            'module'          => 'stores',
        ],
        '/assign-product-to-store' => [
            'component'       => 'AssignProductToStore',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
        ],
        '/manage-products' => [
            'component'       => 'ManageProductsAdmin',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
            'module'          => 'products',
        ],
        '/manage-stores' => [
            'component'       => 'ManageStoresAdmin',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
            'module'          => 'stores',
        ],
        '/pos-access-keys' => [
            'component'       => 'PosAccessKeys',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
            'module'          => 'pos',
        ],
        '/add-transaction' => [
            'component'       => 'AddTransaction',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
            'module'          => 'transactions',
        ],
        '/manage-product-admin' => [
            'component'       => 'ManageProductAdmin',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
            'module'          => 'products',
        ],
        '/batch-add-products' => [
            'component'       => 'BatchAddProducts',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner'],
            'module'          => 'batch',
        ],
        '/batch-add-stores' => [
            'component'       => 'BatchAddStores',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator'],
            'module'          => 'batch',
        ],
        '/batch-add-users' => [
            'component'       => 'BatchAddUsers',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator'],
            'module'          => 'batch',
        ],
        '/batch-add-cooperatives' => [
            'component'       => 'BatchAddCooperatives',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator'],
            'module'          => 'batch',
        ],
        '/pos-history' => [
            'component'       => 'PosHistory',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
            'module'          => 'pos',
        ],

        // Logistics & Shipments



        // Property Management
        '/list-properties' => [
            'component'       => 'ListProperties',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator'],
            'module'          => 'properties',
        ],
        '/list-referrals' => [
            'component'       => 'ListReferrals',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator'],
            'module'          => 'properties',
        ],

        // Reports
        '/list-reports' => [
            'component'       => 'ListReports',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
            'module'          => 'accounting',
        ],
        '/shipment-list' => [
            'component'       => 'ShipmentList',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager', 'rider', 'audit'],
            'module'          => 'shipments',
        ],
        '/shipment-detail' => [
            'component'       => 'ShipmentDetail',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager', 'rider', 'audit'],
            'module'          => 'shipments',
        ],
        '/farmer-profile-edit' => [
            'component'       => 'FarmerProfileEdit',
            'loginRequired'   => true,
            'module'          => 'farmers',
        ],
        '/verification-dashboard' => [
            'component'       => 'VerificationDashboard',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator'],
            'module'          => 'farmers',
        ],
        '/cooperative-list' => [
            'component'       => 'CooperativeList',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'coordinator', 'coop officer', 'coop member'],
            'module'          => 'cooperatives',
        ],
        '/chapter-org-chart' => [
            'component'        => 'ChapterOrgChart',
            'loginRequired'    => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'coordinator', 'coop officer', 'coop member'],
            'module'           => 'cooperatives',
        ],
        '/coop-member-search' => [
            'component'        => 'CoopMemberSearch',
            'loginRequired'    => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'coordinator', 'coop officer'],
            'module'           => 'cooperatives',
        ],
        '/create-coop-user' => [
            'component'        => 'CreateCoopUser',
            'loginRequired'    => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'coordinator', 'coop officer'],
            'module'           => 'cooperatives',
        ],
        '/assign-chapter-officer' => [
            'component'        => 'AssignChapterOfficer',
            'loginRequired'    => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'coordinator', 'coop officer'],
            'module'           => 'cooperatives',
        ],
        '/create-chapter' => [
            'component'        => 'CreateChapter',
            'loginRequired'    => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'coordinator', 'coop officer'],
            'module'           => 'cooperatives',
        ],
        '/register-chapter' => [
            'component'     => 'RegisterChapter',
            'loginRequired' => false,
            'module'        => 'cooperatives',
        ],
        '/create-cooperative' => [
            'component'       => 'CreateCooperative',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'coordinator'],
            'module'          => 'cooperatives',
        ],

        '/cooperative-detail' => [
            'component'       => 'CooperativeDetail',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'coordinator', 'coop officer', 'coop member'],
            'module'          => 'cooperatives',
        ],
        '/enroll-farmer' => [
            'component'       => 'EnrollFarmer',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator'],
            'module'          => 'farmers',
        ],
        '/cooperative-member-register' => [
            'component'       => 'CooperativeMemberRegister',
            'loginRequired'   => true,
            'module'          => 'cooperatives',
        ],
        '/register-coop' => [
            'component'     => 'RegisterCoop',
            'loginRequired' => false,
            'module'        => 'cooperatives',
        ],
        '/user-registration' => [
            'component'     => 'UserRegistration',
            'loginRequired' => false,
        ],
        '/user-info-edit' => [
            'component'       => 'UserInfoEdit',
            'loginRequired'   => true,
        ],
        '/ultimate-console' => [
            'component'       => 'UltimateConsole',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult'],
        ],
        '/system-settings' => [
            'component'       => 'SystemSettings',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult'],
        ],
        '/landing-page-editor' => [
            'component'       => 'LandingPageEditor',
            'loginRequired'   => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'coordinator'],
            'module'          => 'landing_pages',
        ],
        '/accounting-dashboard' => [
            'component'        => 'AccountingDashboard',
            'loginRequired'    => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
            'module'           => 'accounting',
            'store_module'     => 'accounting_store',
        ],
        '/manage-accounts' => [
            'component'        => 'ManageAccounts',
            'loginRequired'    => true,
            'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
            'module'           => 'accounting',
            'store_module'     => 'accounting_store',
        ],
    ];


    /**
     * Helper method to check if user is allowed based on their type.
     * Returns true if the user can access the page, false otherwise.
     */
    private static function isUserAllowed(string $currentUserType, array $allowedUserTypes): bool
    {
        // If no restrictions specified, allow all authenticated users
        if (empty($allowedUserTypes)) {
            return true;
        }
        
        // Check if user type matches any allowed types
        foreach ($allowedUserTypes as $type) {
            if (is_string($type) && $currentUserType === $type) {
                return true;
            }
        }
        
        return false;
    }

    /**
     * Registers the defined Vue routes into the application.
     * This should be called in `routes/web.php`.
     */
    public static function registerRoutes(): void
    {
        foreach (self::$routes as $uri => $settings) {
            $component = $settings['component'] ?? '';
            $middlewares = $settings['middlewares'] ?? [];
            $name = $settings['name'] ?? null;
            $loginRequired = $settings['loginRequired'] ?? false;
            $allowedUserTypes = $settings['allowedUserTypes'] ?? [];

            $options = [];

            if (!empty($middlewares)) {
                $options['middleware'] = $middlewares;
            }

            if ($name) {
                $options['as'] = $name;
            }

            // Add login requirement middleware if needed
            if ($loginRequired) {
                $options['middleware'] = array_unique(array_merge($options['middleware'] ?? [], ['auth']));
            }

            // Add module requirement middleware if specified
            $moduleKey = $settings['module'] ?? null;
            if ($moduleKey) {
                $options['middleware'] = array_unique(array_merge($options['middleware'] ?? [], ["module:{$moduleKey}"]));
            }

            Route::get($uri, function (...$routeParams) use ($component, $loginRequired, $allowedUserTypes, $moduleKey) {
                // Check if user is authenticated
                if (empty(Auth::user())) {
                    // If login is required but not available, redirect to login page
                    if ($loginRequired) {
                        return redirect('/login');
                    }
                }

                // Check if module is enabled
                if ($moduleKey && ModuleHelper::isDisabled($moduleKey)) {
                    return redirect('/');
                }

                // Global Page Disabled Check
                /** @var \App\Models\User $user */
                $user = Auth::user();
                $disabledPages = \App\Models\SystemSetting::getValue('disabled_pages', []);
                if (is_array($disabledPages) && in_array(strtolower((string)$component), array_map('strtolower', $disabledPages))) {
                    // Ultimate accounts can still access to allow fixing settings
                    if (!$user || $user->acct_type !== UserTypes::ULTIMATE) {
                        return redirect('/');
                    }
                }

                // Check allowed user types if specified
                if (!empty($allowedUserTypes)) {
                    $currentUserType = $user->acct_type?->value ?? $user->acct_type ?? UserTypes::PUBLIC->value;
                    $isAllowed = self::isUserAllowed($currentUserType, $allowedUserTypes);
                    if (!$isAllowed) {
                        // Redirect to a forbidden page or login
                        return redirect('/login');
                    }
                }

                // Return Inertia page properly set up with current user data
                // Pass parameterized URL segments to the Vue component as properties
                $page = Inertia::render($component, [
                    'user' => Auth::user(),
                    'routeParams' => empty($routeParams) ? null : $routeParams
                ]);

                return view('layouts/application-layout', compact('page'));
            }, $options);
        }
    }

    /**
     * Handles a generic SPA request by converting the path into a component name.
     * This acts as a catch-all universal router.
     */
    public static function handleSpa(string $path = '/')
    {
        $path = trim($path, '/');
        
        // Get user type for access control
        /** @var \App\Models\User $user */
        $user = Auth::user();
        $currentUserType = null;
        
        if ($user) {
            $currentUserType = $user->acct_type?->value ?? $user->acct_type ?? UserTypes::PUBLIC->value;
        }

        // Strip hashkey/payload suffix from path (e.g., "edituser--h:HASHKEY" -> "edituser")
        // Use RouteArgumentParser to properly extract the base component name
        $component = $path;
        
        try {
            $parser = new \App\Support\RouteArgumentParser();
            $parsedData = $parser->parseArgument($path);
            
            // If we have a hash or payload format, use the slug as the component
            if (isset($parsedData['slug']) && ($parsedData['type'] === 'hash' || $parsedData['type'] === 'payload')) {
                $component = $parsedData['slug'];
            }
        } catch (\Throwable $th) {
            // If parsing fails or no hash/payload format, use original path
        }

        // fallback to Home if empty
        $component = empty($component) ? 'Home' : $component;

        // Convert lowercase component names to camelCase for Vue component matching
        // e.g., "edituser" -> "EditUser"
        $vueComponent = self::toCamelCase($component);
        
        // Find base component from routes map using the route key
        $componentLower = strtolower($component);
        $routeKey = '/' . $componentLower;
        
        $loginRequired = true; // Default: require login
        $pathWithSlash = '/' . ltrim($path, '/');
        $pathLower = strtolower($pathWithSlash);
        
        $routeSettings = self::$routes[$pathWithSlash] ?? self::$routes[$pathLower] ?? null;
        $allowedUserTypes = [];
        $moduleKey = null;
        $foundInMap = false;

        if ($routeSettings) {
            $settings = $routeSettings;
            $vueComponent = $settings['component'] ?? $vueComponent;
            $loginRequired = $settings['loginRequired'] ?? true;
            $allowedUserTypes = $settings['allowedUserTypes'] ?? [];
            $moduleKey = $settings['module'] ?? null;
            $foundInMap = true;
        } else {
            // Try hyphen-insensitive match (e.g. "viewstoremarket" vs "view-store-market")
            $cleanSlug = str_replace(['-', '_'], '', $componentLower);
            foreach (self::$routes as $uri => $settings) {
                $cleanUri = str_replace(['-', '_'], '', strtolower(trim($uri, '/')));
                if ($cleanUri === $cleanSlug) {
                    $vueComponent = $settings['component'] ?? $vueComponent;
                    $loginRequired = $settings['loginRequired'] ?? true;
                    $allowedUserTypes = $settings['allowedUserTypes'] ?? [];
                    $moduleKey = $settings['module'] ?? null;
                    $foundInMap = true;
                    break;
                }
            }

            if (!$foundInMap) {
                // Fallback: search by Vue component name (case-insensitive) in case they passed the component direct name
                foreach (self::$routes as $uri => $settings) {
                    $mappedComponent = $settings['component'] ?? '';
                    if (strcasecmp($mappedComponent, $vueComponent) === 0) {
                        $vueComponent = $mappedComponent; // Use the correctly cased name from map
                        $loginRequired = $settings['loginRequired'] ?? true;
                        $allowedUserTypes = $settings['allowedUserTypes'] ?? [];
                        $moduleKey = $settings['module'] ?? null;
                        $foundInMap = true;
                        break;
                    }
                }
            }
        }

        // Enforce login requirement
        if ($loginRequired && empty($user)) {
            return redirect('/login');
        }

        // Enforce module requirement
        if ($moduleKey && ModuleHelper::isDisabled($moduleKey)) {
            return redirect('/');
        }

        // For store-level users, check the store-specific module toggle
        $storeModuleKey = $routeSettings['store_module'] ?? null;
        if ($storeModuleKey && in_array($currentUserType, ['store owner', 'store manager'])) {
            if (ModuleHelper::isDisabled($storeModuleKey)) {
                return redirect('/');
            }
        }

        // Global Page Disabled Check
        $disabledPages = \App\Models\SystemSetting::getValue('disabled_pages', []);
        if (is_array($disabledPages) && in_array(strtolower((string)$vueComponent), array_map('strtolower', $disabledPages))) {
            // Ultimate accounts can still access to allow fixing settings
            if (!$user || $user->acct_type !== UserTypes::ULTIMATE) {
                return redirect('/');
            }
        }

        // Check allowed user types if specified
        if (!empty($allowedUserTypes) && $currentUserType !== null) {
            $isAllowed = self::isUserAllowed($currentUserType, $allowedUserTypes);
            if (!$isAllowed) {
                // Redirect to a forbidden page or login
                return redirect('/login');
            }
        }

        // Pass standard Inertia props with hashkey if present
        $props = [
            'user' => Auth::user(),
        ];
        
        // Add hashkey to props if it was in the URL for special pages
        if (isset($parsedData['type']) && $parsedData['type'] === 'hash') {
            // Provide the hash value under multiple common prop names for better compatibility
            $props['hashkey'] = $parsedData['value'];
            $props['target'] = $parsedData['value'];
            $props['id'] = $parsedData['value'];
        } elseif (isset($parsedData['type']) && $parsedData['type'] === 'payload') {
            $props['payload'] = $parsedData['value'];
        }

        $page = Inertia::render($vueComponent, $props);

        return view('layouts/application-layout', compact('page'));
    }
    
    /**
     * Convert snake_case or lowercase to camelCase for Vue component matching.
     */
    private static function toCamelCase(string $name): string
    {
        // Replace slashes with dots first to handle directory structures
        $name = str_replace('/', '.', $name);
        
        // Split by dot (hierarchy)
        $parts = explode('.', $name);
        $pascalParts = array_map(function($part) {
            // Split by hyphen and capitalize each part for PascalCase
            $subParts = explode('-', $part);
            return implode('', array_map('ucfirst', $subParts));
        }, $parts);
        
        // Return with dots if original had them, otherwise just one string
        return implode('.', $pascalParts);
    }
}
