/**
 * @file RouteConfig.ts
 * Centralized routing configuration for clean, maintainable paths
 *
 * Design Principles:
 * - Single source of truth for all routes
 * - i18n-ready: paths can be localized
 * - Type-safe: compile-time checking
 * - Easy to refactor: change in one place
 * - Environment-specific: can vary by mode
 */

import { ConsoleLogger } from '../infrastructure/logging/ConsoleLogger';

const logger = new ConsoleLogger();

export interface RouteDefinition {
	path: string;
	name: string;
	description?: string;
}

export interface RouteGroup {
	auth: {
		login: string;
		signup: string;
		forgotPassword: string;
		resetPassword: string;
	};
	public: {
		home: string;
		leagues: string;
		drivers: string;
		teams: string;
		leaderboards: string;
		races: string;
		sponsorSignup: string;
	};
	protected: {
		dashboard: string;
		onboarding: string;
		profile: string;
		profileSettings: string;
		profileLeagues: string;
		profileLiveries: string;
		profileLiveryUpload: string;
		profileSponsorshipRequests: string;
	};
	sponsor: {
		root: string;
		dashboard: string;
		billing: string;
		campaigns: string;
		leagues: string;
		leagueDetail: (id: string) => string;
		settings: string;
	};
	admin: {
		root: string;
		users: string;
	};
	league: {
		detail: (id: string) => string;
		roster: (id: string) => string;
		rosterAdmin: (id: string) => string;
		rulebook: (id: string) => string;
		schedule: (id: string) => string;
		scheduleAdmin: (id: string) => string;
		settings: (id: string) => string;
		sponsorships: (id: string) => string;
		standings: (id: string) => string;
		stewarding: (id: string) => string;
		wallet: (id: string) => string;
		create: string;
		migration: string;
	};
	race: {
		root: string;
		all: string;
		detail: (id: string) => string;
		results: (id: string) => string;
		stewarding: (id: string) => string;
	};
	team: {
		root: string;
		leaderboard: string;
		detail: (id: string) => string;
		create: string;
	};
	driver: {
		root: string;
		detail: (id: string) => string;
	};
	leaderboards: {
		root: string;
		drivers: string;
		teams: string;
	};
	error: {
		notFound: string;
		serverError: string;
	};
}

/**
 * Route configuration with i18n support
 * 
 * Usage:
 * ```typescript
 * import { routes } from '@/lib/routing/RouteConfig';
 * 
 * // Navigate to login
 * router.push(routes.auth.login);
 * 
 * // Navigate to league detail
 * router.push(routes.league.detail('league-123'));
 * 
 * // Check if current path is protected
 * if (currentPath.startsWith(routes.protected.dashboard)) {
 *   // Handle protected route
 * }
 * ```
 */
export const routes: RouteGroup & { leaderboards: { root: string; drivers: string; teams: string } } = {
	auth: {
		login: '/auth/login',
		signup: '/auth/signup',
		forgotPassword: '/auth/forgot-password',
		resetPassword: '/auth/reset-password',
	},
	public: {
		home: '/',
		leagues: '/leagues',
		drivers: '/drivers',
		teams: '/teams',
		leaderboards: '/leaderboards',
		races: '/races',
		sponsorSignup: '/sponsor/signup',
	},
	protected: {
		dashboard: '/dashboard',
		onboarding: '/onboarding',
		profile: '/profile',
		profileSettings: '/profile/settings',
		profileLeagues: '/profile/leagues',
		profileLiveries: '/profile/liveries',
		profileLiveryUpload: '/profile/liveries/upload',
		profileSponsorshipRequests: '/profile/sponsorship-requests',
	},
	sponsor: {
		root: '/sponsor',
		dashboard: '/sponsor/dashboard',
		billing: '/sponsor/billing',
		campaigns: '/sponsor/campaigns',
		leagues: '/sponsor/leagues',
		leagueDetail: (id: string) => `/sponsor/leagues/${id}`,
		settings: '/sponsor/settings',
	},
	admin: {
		root: '/admin',
		users: '/admin/users',
	},
	league: {
		detail: (id: string) => `/leagues/${id}`,
		roster: (id: string) => `/leagues/${id}/roster`,
		rosterAdmin: (id: string) => `/leagues/${id}/roster/admin`,
		rulebook: (id: string) => `/leagues/${id}/rulebook`,
		schedule: (id: string) => `/leagues/${id}/schedule`,
		scheduleAdmin: (id: string) => `/leagues/${id}/schedule/admin`,
		settings: (id: string) => `/leagues/${id}/settings`,
		sponsorships: (id: string) => `/leagues/${id}/sponsorships`,
		standings: (id: string) => `/leagues/${id}/standings`,
		stewarding: (id: string) => `/leagues/${id}/stewarding`,
		wallet: (id: string) => `/leagues/${id}/wallet`,
		create: '/leagues/create',
		migration: '/leagues/migration',
	},
	race: {
		root: '/races',
		all: '/races/all',
		detail: (id: string) => `/races/${id}`,
		results: (id: string) => `/races/${id}/results`,
		stewarding: (id: string) => `/races/${id}/stewarding`,
	},
	team: {
		root: '/teams',
		leaderboard: '/teams/leaderboard',
		detail: (id: string) => `/teams/${id}`,
		create: '/teams/create',
	},
	driver: {
		root: '/drivers',
		detail: (id: string) => `/drivers/${id}`,
	},
	leaderboards: {
		root: '/leaderboards',
		drivers: '/leaderboards/drivers',
		teams: '/leaderboards/teams',
	},
	error: {
		notFound: '/404',
		serverError: '/500',
	},
};

/**
 * Route matcher utilities for pattern matching
 */
export const routeMatchers = {
	/**
	 * Check if path matches a pattern
	 */
	matches(path: string, pattern: string): boolean {
	  // Exact match
	  if (pattern === path) return true;
	  
	  // Wildcard match (ends with /*)
	  if (pattern.endsWith('/*') && path.startsWith(pattern.slice(0, -2))) {
	    return true;
	  }
	  
	  // Wildcard match (contains /* in the middle)
	  if (pattern.includes('/*')) {
	    // Convert wildcard pattern to regex
	    // e.g., /leagues/*/schedule -> ^/leagues/[^/]+/schedule$
	    const regexPattern = pattern.replace(/\*/g, '[^/]+');
	    const regex = new RegExp(`^${regexPattern}$`);
	    return regex.test(path);
	  }
	  
	  // Parameterized match (e.g., /leagues/[id])
	  const paramPattern = pattern.replace(/\[([^\]]+)\]/g, '([^/]+)');
	  const regex = new RegExp(`^${paramPattern}$`);
	  return regex.test(path);
	},

	/**
	 * Check if path is in a route group
	 */
	isInGroup(path: string, group: keyof RouteGroup): boolean {
		const groupRoutes = routes[group];
		
		// Handle nested objects (like sponsor.leagueDetail)
		const values = Object.values(groupRoutes);
		
		return values.some(value => {
			if (typeof value === 'function') {
				// For parameterized routes, check pattern
				const pattern = value('placeholder');
				return path.startsWith(pattern.replace('/placeholder', ''));
			}
			return path.startsWith(value as string);
		});
	},

	/**
	 * Get all public route patterns
	 */
	getPublicPatterns(): string[] {
		return [
			routes.public.home,
			routes.public.leagues,
			routes.public.drivers,
			routes.public.teams,
			routes.public.leaderboards,
			routes.leaderboards.drivers,
			routes.leaderboards.teams,
			routes.public.races,
			routes.public.sponsorSignup,
			routes.auth.login,
			routes.auth.signup,
			routes.auth.forgotPassword,
			routes.auth.resetPassword,
			routes.error.notFound,
			routes.error.serverError,
			// League sub-pages (public)
			routes.league.schedule('*'),
			routes.league.standings('*'),
			routes.league.roster('*'),
			routes.league.rulebook('*'),
		];
	},

	/**
	 * Check if path is public
	 */
	isPublic(path: string): boolean {
		// logger.info('[RouteConfig] isPublic check', { path });
		
		const publicPatterns = this.getPublicPatterns();

		// Check exact matches
		if (publicPatterns.includes(path)) {
			// logger.info('[RouteConfig] Path is public (exact match)', { path });
			return true;
		}

		// Treat top-level detail pages as public (e2e relies on this)
		// Examples: /leagues/:id, /races/:id, /drivers/:id, /teams/:id
		const segments = path.split('/').filter(Boolean);
		if (segments.length === 2) {
			const [group, slug] = segments;
			if (group === 'leagues' && slug !== 'create') {
				// logger.info('[RouteConfig] Path is public (league detail)', { path });
				return true;
			}
			if (group === 'races') {
				// logger.info('[RouteConfig] Path is public (race detail)', { path });
				return true;
			}
			if (group === 'drivers') {
				// logger.info('[RouteConfig] Path is public (driver detail)', { path });
				return true;
			}
			if (group === 'teams' && slug !== 'create') {
				// logger.info('[RouteConfig] Path is public (team detail)', { path });
				return true;
			}
		}

		// Check parameterized patterns and wildcard patterns
		const isPublicParam = publicPatterns.some(pattern => {
			// Check for parameterized patterns (e.g., /leagues/[id])
			if (pattern.includes('[')) {
				const paramPattern = pattern.replace(/\[([^\]]+)\]/g, '([^/]+)');
				const regex = new RegExp(`^${paramPattern}$`);
				return regex.test(path);
			}
			// Check for wildcard patterns (e.g., /leagues/*)
			if (pattern.includes('/*')) {
				return this.matches(path, pattern);
			}
			return false;
		});
		
		// if (isPublicParam) {
		//   logger.info('[RouteConfig] Path is public (parameterized match)', { path });
		// } else {
		//   logger.info('[RouteConfig] Path is NOT public', { path });
		// }
		
		return isPublicParam;
	},

	/**
	 * Check if path requires authentication
	 */
	requiresAuth(path: string): boolean {
		return !this.isPublic(path);
	},

	/**
	 * Check if path requires specific role
	 */
	requiresRole(path: string): string[] | null {
		// logger.info('[RouteConfig] requiresRole check', { path });
		
		// Public routes never require a role
		if (this.isPublic(path)) {
			// logger.info('[RouteConfig] Path is public, no role required', { path });
			return null;
		}
		
		if (this.isInGroup(path, 'admin')) {
			// Website session roles come from the API and are more specific than just "admin".
			// Keep "admin"/"owner" for backwards compatibility.
			const roles = ['admin', 'owner', 'league-admin', 'league-steward', 'league-owner', 'system-owner', 'super-admin'];
			// logger.info('[RouteConfig] Path requires admin roles', { path, roles });
			return roles;
		}
		if (this.isInGroup(path, 'sponsor')) {
			// logger.info('[RouteConfig] Path requires sponsor role', { path });
			return ['sponsor'];
		}
		// logger.info('[RouteConfig] Path requires no specific role', { path });
		return null;
	},
};

/**
 * i18n-ready path builder
 * 
 * Usage:
 * ```typescript
 * // With current locale
 * const path = buildPath('leagueDetail', { id: '123' });
 * 
 * // With specific locale
 * const path = buildPath('leagueDetail', { id: '123' }, 'de');
 * ```
 */
export function buildPath(
	routeName: string,
	params: Record<string, string> = {},
	_: string = ''
): string {
	// This is a placeholder for future i18n implementation
	// For now, it just builds the path using the route config
	
	const parts = routeName.split('.');
	let route: any = routes;
	
	for (const part of parts) {
		route = (route as Record<string, any>)[part];
		if (!route) {
			throw new Error(`Unknown route: ${routeName}`);
		}
	}
	
	if (typeof route === 'function') {
		const paramKeys = Object.keys(params);
		const paramKey = paramKeys[0];
		if (!paramKey) {
			throw new Error(`Route ${routeName} requires parameters`);
		}
		return route(params[paramKey]);
	}
	
	return route as string;
}
