<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class EnsureSpatiePermission
{
    /**
     * Handle an incoming request.
     */
    public function handle(Request $request, Closure $next): Response
    {
        $user = $request->user();

        // If not logged in, let authentication middleware handle it
        if (!$user) {
            return $next($request);
        }

        // Super Admins automatically pass all checks
        if ($user->hasRole('Super Admin') || $user->role === 'super_admin') {
            return $next($request);
        }

        $route = $request->route();
        if (!$route) {
            return $next($request);
        }

        $action = $route->getAction();
        $controllerAction = $action['controller'] ?? null;

        if ($controllerAction && str_contains($controllerAction, '@')) {
            [$controller, $method] = explode('@', $controllerAction);

            // Normalize namespaces if they exist
            $controller = ltrim($controller, '\\');

            $permission = $this->getPermissionForAction($controller, $method);

            if ($permission) {
                // Determine if user has any new Spatie roles or permissions assigned
                $hasSpatieConfig = false;
                try {
                    $hasSpatieConfig = $user->roles()->exists() || $user->permissions()->exists();
                } catch (\Exception $e) {
                    // Database not fully migrated or seeded
                }

                if ($hasSpatieConfig) {
                    try {
                        abort_unless($user->hasPermissionTo($permission), 403, "You do not have the required permission: {$permission}");
                    } catch (\Spatie\Permission\Exceptions\PermissionDoesNotExist $e) {
                        abort(403, "You do not have the required permission: {$permission}");
                    }
                } else {
                    // Fall back to legacy module check
                    $module = $this->getModuleForPermission($permission);
                    abort_unless($user->canAccessModule($module), 403, "You do not have permission to access this module.");
                }
            }
        }

        return $next($request);
    }

    /**
     * Map controller and action to Spatie permission name.
     */
    protected function getPermissionForAction(string $controller, string $method): ?string
    {
        $mappings = [
            // Dashboard
            'App\Http\Controllers\Admin\AdminDashboardController' => [
                'index' => 'dashboard.view',
                'getStats' => 'dashboard.view',
            ],

            // Users
            'App\Http\Controllers\Admin\AdminUserController' => [
                'index' => 'users.view',
                'show' => 'users.view',
                'create' => 'users.create',
                'store' => 'users.create',
                'edit' => 'users.update',
                'update' => 'users.update',
                'destroy' => 'users.delete',
            ],

            // Roles & Permissions
            'App\Http\Controllers\Admin\AdminPermissionController' => [
                'index' => 'roles.view',
                'edit' => 'roles.update',
                'update' => 'roles.update',
            ],

            // Role Management CRUD
            'App\Http\Controllers\Admin\AdminRoleController' => [
                'index' => 'roles.view',
                'show' => 'roles.view',
                'create' => 'roles.create',
                'store' => 'roles.create',
                'edit' => 'roles.update',
                'update' => 'roles.update',
                'destroy' => 'roles.delete',
            ],

            // Products
            'App\Http\Controllers\Admin\AdminProductController' => [
                'index' => 'products.view',
                'show' => 'products.view',
                'create' => 'products.create',
                'store' => 'products.create',
                'edit' => 'products.update',
                'update' => 'products.update',
                'destroy' => 'products.delete',
                'duplicate' => 'products.create',
                'export' => 'products.export',
                'updateAvailability' => 'products.update-availability',
            ],

            // Categories
            'App\Http\Controllers\Admin\AdminCategoryController' => [
                'index' => 'categories.view',
                'show' => 'categories.view',
                'create' => 'categories.create',
                'store' => 'categories.create',
                'edit' => 'categories.update',
                'update' => 'categories.update',
                'destroy' => 'categories.delete',
                'createSubcategory' => 'categories.create',
                'storeSubcategory' => 'categories.create',
            ],

            // Subcategories
            'App\Http\Controllers\Admin\AdminSubcategoryController' => [
                'index' => 'categories.view',
                'show' => 'categories.view',
                'create' => 'categories.create',
                'store' => 'categories.create',
                'edit' => 'categories.update',
                'update' => 'categories.update',
                'destroy' => 'categories.delete',
            ],

            // Brands
            'App\Http\Controllers\Admin\AdminBrandController' => [
                'index' => 'brands.view',
                'create' => 'brands.create',
                'store' => 'brands.create',
                'edit' => 'brands.update',
                'update' => 'brands.update',
                'destroy' => 'brands.delete',
            ],

            // Units
            'App\Http\Controllers\Admin\AdminUnitController' => [
                'index' => 'units.view',
                'create' => 'units.create',
                'store' => 'units.create',
                'edit' => 'units.update',
                'update' => 'units.update',
                'destroy' => 'units.delete',
            ],

            // Customers
            'App\Http\Controllers\Admin\AdminCustomerController' => [
                'index' => 'customers.view',
                'show' => 'customers.view',
                'create' => 'customers.create',
                'store' => 'customers.create',
                'edit' => 'customers.update',
                'update' => 'customers.update',
                'toggleStatus' => 'customers.update',
                'destroy' => 'customers.delete',
                'export' => 'customers.export',
            ],

            // Customer Addresses
            'App\Http\Controllers\Admin\AdminCustomerAddressController' => [
                'store' => 'customers.update',
                'update' => 'customers.update',
                'destroy' => 'customers.update',
                'setDefault' => 'customers.update',
            ],

            // Shipping Methods
            'App\Http\Controllers\Admin\AdminShippingMethodController' => [
                'index' => 'shipping-methods.view',
                'create' => 'shipping-methods.create',
                'store' => 'shipping-methods.create',
                'edit' => 'shipping-methods.update',
                'update' => 'shipping-methods.update',
                'destroy' => 'shipping-methods.delete',
            ],

            // Orders
            'App\Http\Controllers\Admin\AdminOrderController' => [
                'index' => 'orders.view',
                'show' => 'orders.view',
                'create' => 'orders.create',
                'store' => 'orders.create',
                'edit' => 'orders.update',
                'update' => 'orders.update',
                'destroy' => 'orders.delete',
                'cancel' => 'orders.cancel',
                'refund' => 'orders.refund',
            ],

            // Payments
            'App\Http\Controllers\Admin\AdminPaymentController' => [
                'index' => 'payments.view',
                'verify' => 'payments.verify',
                'refund' => 'payments.refund',
            ],

            // Payment Methods
            'App\Http\Controllers\Admin\AdminPaymentMethodController' => [
                'index' => 'payments.view',
                'create' => 'payments.view',
                'store' => 'payments.view',
                'edit' => 'payments.view',
                'update' => 'payments.view',
                'destroy' => 'payments.view',
            ],

            // FAQ
            'App\Http\Controllers\Admin\AdminFaqController' => [
                'index' => 'cms.pages.view',
                'show' => 'cms.pages.view',
                'create' => 'cms.pages.create',
                'store' => 'cms.pages.create',
                'edit' => 'cms.pages.update',
                'update' => 'cms.pages.update',
                'destroy' => 'cms.pages.delete',
            ],

            // Slides
            'App\Http\Controllers\Admin\AdminSlideController' => [
                'index' => 'cms.pages.view',
                'show' => 'cms.pages.view',
                'create' => 'cms.pages.create',
                'store' => 'cms.pages.create',
                'edit' => 'cms.pages.update',
                'update' => 'cms.pages.update',
                'destroy' => 'cms.pages.delete',
            ],

            // CMS Page Content
            'App\Http\Controllers\Admin\PageContentController' => [
                'index' => 'cms.pages.view',
                'show' => 'cms.pages.view',
                'create' => 'cms.pages.create',
                'store' => 'cms.pages.create',
                'edit' => 'cms.pages.update',
                'update' => 'cms.pages.update',
                'destroy' => 'cms.pages.delete',
            ],

            // Reports
            'App\Http\Controllers\Admin\AdminReportController' => [
                'sales' => 'reports.sales',
                'products' => 'reports.products',
                'orders' => 'reports.orders',
                'payments' => 'reports.payments',
                'customers' => 'reports.customers',
            ],

            // Settings
            'App\Http\Controllers\Admin\AdminSettingController' => [
                'index' => 'settings.view',
                'update' => 'settings.update',
            ],
        ];

        return $mappings[$controller][$method] ?? null;
    }

    /**
     * Map a granular Spatie permission back to its legacy module name.
     */
    protected function getModuleForPermission(string $permission): string
    {
        $parts = explode('.', $permission);
        $base = $parts[0];

        $map = [
            'dashboard' => 'dashboard',
            'users' => 'staff',
            'roles' => 'staff',
            'products' => 'products',
            'categories' => 'products',
            'brands' => 'products',
            'units' => 'products',
            'attributes' => 'products',
            'customers' => 'customers',
            'shipping-methods' => 'settings',
            'orders' => 'orders',
            'payments' => 'payments',
            'reviews' => 'content',
            'cms' => 'content',
            'reports' => 'reports',
            'settings' => 'settings',
            'activity-logs' => 'staff',
        ];

        return $map[$base] ?? $base;
    }
}
