import { ModuleType } from '@/components/helper';
import deepParseJson from '@/lib/utils';

// Map routes to their corresponding module types
export const routeToModuleMap: Record<string, ModuleType> = {
    '/masters/departments': ModuleType.Department,
    '/masters/business-verticals': ModuleType.BusinessVertical,
    '/masters/country-master': ModuleType.CountryMaster,
    '/masters/state-master': ModuleType.StateMaster,
    '/masters/city-master': ModuleType.CityMaster,
    '/masters/currency-master': ModuleType.CurrencyMaster,
    '/masters/roles-permissions': ModuleType.Roles,
    '/masters/team-members': ModuleType.TeamMembers,
    '/masters/client-type-master': ModuleType.ClientTypeMaster,
    '/masters/vehicle-type-master': ModuleType.VehicleTypeMaster,
    '/masters/vehicle-make-master': ModuleType.VehicleMakeMaster,
    '/masters/vehicle-model-master': ModuleType.VehicleModelMaster,
    '/masters/add-ons-master': ModuleType.AddOnsMaster,
    '/masters/vehicle-status-master': ModuleType.VehicleStatusMaster,
    '/masters/contract-coverage-master': ModuleType.ContractCoverageMaster,
    '/masters/price-management': ModuleType.PriceManagement,
    '/masters/inspection-questions': ModuleType.InspectionQuestions,
    '/masters/organogram': ModuleType.Organogram,
    '/masters/charges-types-master': ModuleType.ChargesTypesMaster,
    '/masters/customer-tag-master': ModuleType.CustomerTagsMaster,
    '/fleet': ModuleType.FleetManagement,
    '/hospitals': ModuleType.Hospitals,
    '/incident-reporting': ModuleType.Incidents,
    '/clients': ModuleType.ClientCompanies,
    '/drivers': ModuleType.DriverManagement,
    '/customers': ModuleType.CustomerManagement,
    '/trips': ModuleType.TripManagement,
    '/report': ModuleType.Reports,
    '/report/operational/trip-summary': ModuleType.Reports,
    '/invoices': ModuleType.Invoice,
    '/payments': ModuleType.Payment,
};

// Routes that don't require module permissions (public routes)
export const publicRoutes = [
    '/login',
    '/forgot-password',
    '/reset-password',
    '/dashboard', // Dashboard is always accessible
    '/account',
    '/account/change-password',
];

// Routes that require authentication but no specific module permission
export const authOnlyRoutes = ['/dashboard', '/account', '/account/change-password'];

interface ModulePermission {
    module_type: string;
    permission_name: string;
}

const isViewOnlyPermission = (permission: string | undefined): boolean => {
    if (!permission) return false;
    const level = permission.toLowerCase().trim();

    // Project uses only: 'admin' | 'editor' | 'viewer' | 'none'
    // Treat ONLY 'viewer' as view-only
    return level === 'viewer';
};

/**
 * Get the module type required for a given route
 */
export const getModuleTypeForRoute = (pathname: string): ModuleType | null => {
    // Check exact match first
    if (routeToModuleMap[pathname]) {
        return routeToModuleMap[pathname];
    }

    // Check for nested routes (e.g., /masters/team-members/add should map to TeamMembers)
    for (const [route, moduleType] of Object.entries(routeToModuleMap)) {
        if (pathname.startsWith(route + '/') || pathname === route) {
            return moduleType;
        }
    }

    return null;
};

/**
 * Check if a route is public (doesn't require authentication)
 */
export const isPublicRoute = (pathname: string): boolean => {
    return publicRoutes.some((route) => pathname === route || pathname.startsWith(route + '/'));
};

/**
 * Some routes behave like "create/update" screens even though the URL
 * doesn't contain add/create/edit/update keywords (e.g. `/trips/schedule`).
 */
const specialActionRoutes: Record<string, 'create' | 'update'> = {
    '/trips/schedule': 'update',
};

/**
 * Derive the "action" user is trying to perform from the URL.
 * - default: 'view' (listing / details)
 * - '/add' or '/create' in path: 'create'
 * - '/edit' or '/update' in path: 'update'
 * - specialActionRoutes: explicit mapping
 */
const getActionFromPathname = (pathname: string): 'view' | 'create' | 'update' => {
    const lowerPath = pathname.toLowerCase();

    // Explicit overrides first
    for (const [route, action] of Object.entries(specialActionRoutes)) {
        if (lowerPath === route || lowerPath.startsWith(`${route}/`)) {
            return action;
        }
    }

    if (lowerPath.includes('/add') || lowerPath.includes('/create')) {
        return 'create';
    }

    if (lowerPath.includes('/edit') || lowerPath.includes('/update')) {
        return 'update';
    }

    return 'view';
};

/**
 * Check if user has permission to access a route
 */
export const hasRoutePermission = (pathname: string, modules: ModulePermission[] | null | undefined): boolean => {
    // Public routes are always accessible
    if (isPublicRoute(pathname)) {
        return true;
    }

    // If no modules data, deny access (except public routes)
    if (!modules || !Array.isArray(modules)) {
        return false;
    }

    // Get required module type for this route
    const requiredModuleType = getModuleTypeForRoute(pathname);

    // If route doesn't require a specific module, allow access (for authenticated users)
    if (!requiredModuleType) {
        return true;
    }

    // Check if user has permission for this module
    const userModule = modules.find((module) => module.module_type === requiredModuleType);

    if (!userModule || userModule.permission_name === 'none') {
        return false;
    }

    // If module permission is "view" only, block create / update pages
    const routeAction = getActionFromPathname(pathname);
    const modulePermission = userModule.permission_name.toLowerCase();

    if (isViewOnlyPermission(modulePermission) && routeAction !== 'view') {
        return false;
    }

    // For any other permission level (edit, all, etc.) allow access
    return true;
};

/**
 * Get user modules from localStorage (for middleware/server-side use)
 */
export const getUserModulesFromStorage = (): ModulePermission[] | null => {
    if (typeof window === 'undefined') {
        return null;
    }

    try {
        const rawPersistData = localStorage.getItem('admin');
        if (!rawPersistData) {
            return null;
        }

        const persistData = deepParseJson(rawPersistData);
        return persistData?.auth?.modules || null;
    } catch {
        return null;
    }
};
