import { createRouter, createWebHistory } from 'vue-router';
import { applySeoForPath } from './utils/seo.js';
import { safeLocalStorage, safeSessionStorage } from './utils/storage.js';
import { getDefaultHomeRoute, isProductRouteAllowed, resolveCurrentProduct } from './config/products.js';
import { CLUB_CONCEPT_ROUTES } from './config/clubWorkspace.js';

const Register = () => import('./views/Register.vue');
const Login = () => import('./views/Login.vue');
const Activate = () => import('./views/Activate.vue');
const ForgotPassword = () => import('./views/ForgotPassword.vue');
const ResetPassword = () => import('./views/ResetPassword.vue');
const Home = () => import('./views/Home.vue');
const TableTennisClubSoftware = () => import('./views/TableTennisClubSoftware.vue');
const ClubMemberManagementPage = () => import('./views/ClubMemberManagementPage.vue');
const TrainingPlanningPage = () => import('./views/TrainingPlanningPage.vue');
const TableTennisTournamentSoftwarePage = () => import('./views/TableTennisTournamentSoftwarePage.vue');
const CreateClub = () => import('./views/CreateClub.vue');
const ClubView = () => import('./views/ClubView.vue');
const MembersView = () => import('./views/MembersView.vue');
const DiaryView = () => import('./views/DiaryView.vue');
const CalendarView = () => import('./views/CalendarView.vue');
const PendingApprovalsView = () => import('./views/PendingApprovalsView.vue');
const ScheduleView = () => import('./views/ScheduleView.vue');
const TournamentsView = () => import('./views/TournamentsView.vue');
const OfficialTournaments = () => import('./views/OfficialTournaments.vue');
const TrainingStatsView = () => import('./views/TrainingStatsView.vue');
const ClubSettings = () => import('./views/ClubSettings.vue');
const PredefinedActivities = () => import('./views/PredefinedActivities.vue');
const MyTischtennisAccount = () => import('./views/MyTischtennisAccount.vue');
const ClickTtAccount = () => import('./views/ClickTtAccount.vue');
const TeamManagementView = () => import('./views/TeamManagementView.vue');
const PermissionsView = () => import('./views/PermissionsView.vue');
const LogsView = () => import('./views/LogsView.vue');
const ClickTtView = () => import('./views/ClickTtView.vue');
const MemberTransferSettingsView = () => import('./views/MemberTransferSettingsView.vue');
const PersonalSettings = () => import('./views/PersonalSettings.vue');
const OrdersView = () => import('./views/OrdersView.vue');
const BillingView = () => import('./views/BillingView.vue');
const ClubRequestsView = () => import('./views/ClubRequestsView.vue');
const ClubTasksView = () => import('./views/ClubTasksView.vue');
const ClubHistoryView = () => import('./views/ClubHistoryView.vue');
const ClubStatisticsView = () => import('./views/ClubStatisticsView.vue');
const ClubArchiveView = () => import('./views/ClubArchiveView.vue');
const ClubAccountsView = () => import('./views/ClubAccountsView.vue');
const ClubInvoicesView = () => import('./views/ClubInvoicesView.vue');
const ClubCommunicationView = () => import('./views/ClubCommunicationView.vue');
const ClubOperationsWorkspaceView = () => import('./views/ClubOperationsWorkspaceView.vue');
const ClubConceptModuleView = () => import('./views/ClubConceptModuleView.vue');
const Impressum = () => import('./views/Impressum.vue');
const Datenschutz = () => import('./views/Datenschutz.vue');
const KontoLoeschen = () => import('./views/KontoLoeschen.vue');

function withMeta(meta = {}) {
  return meta;
}

function getStoredCurrentClubPermissions() {
  const currentClub = safeSessionStorage.getItem('currentClub');
  if (!currentClub) {
    return null;
  }

  try {
    const permissionMap = JSON.parse(safeLocalStorage.getItem('clubPermissions') || '{}');
    return permissionMap[currentClub] || null;
  } catch (_error) {
    return null;
  }
}

function hasRoutePermission(resource, action) {
  const permissions = getStoredCurrentClubPermissions();
  if (!permissions) {
    return false;
  }
  if (permissions.isOwner) {
    return true;
  }
  if (resource === 'mytischtennis') {
    return true;
  }

  return permissions.permissions?.[resource]?.[action] === true;
}

function hasRouteCapability(capability) {
  const permissions = getStoredCurrentClubPermissions();
  if (!permissions) {
    return false;
  }

  if (permissions.isOwner || permissions.isAdmin || permissions.role === 'admin') {
    return true;
  }

  if (capability === 'approvals') {
    return hasRoutePermission('approvals', 'read');
  }
  if (capability === 'admin') {
    return false;
  }

  return true;
}

function isRouteAuthorized(to) {
  const protectedRules = to.matched
    .map((record) => record.meta || {})
    .filter((meta) => meta.permission || meta.capability || Array.isArray(meta.anyPermission));

  if (protectedRules.length === 0) {
    return true;
  }

  return protectedRules.every((meta) => {
    if (meta.capability && !hasRouteCapability(meta.capability)) {
      return false;
    }
    if (meta.permission) {
      const [resource, action] = meta.permission;
      if (!hasRoutePermission(resource, action)) {
        return false;
      }
    }
    if (Array.isArray(meta.anyPermission) && !meta.anyPermission.some(([resource, action]) => hasRoutePermission(resource, action))) {
      return false;
    }
    return true;
  });
}

const trainerOnly = ['trainer'];
const clubOnly = ['club'];
const fullAppProducts = ['trainer', 'club'];
const allProducts = ['trainer', 'club', 'player'];

const conceptRoutes = CLUB_CONCEPT_ROUTES
  .filter((route) => route.path !== '/club-requests')
  .filter((route) => route.path !== '/club-tasks')
  .filter((route) => route.path !== '/club-users')
  .filter((route) => route.path !== '/club-roles')
  .filter((route) => route.path !== '/club-history')
  .filter((route) => route.path !== '/club-statistics')
  .filter((route) => route.path !== '/club-archive')
  .filter((route) => route.path !== '/club-accounts')
  .filter((route) => route.path !== '/club-invoices')
  .filter((route) => route.path !== '/club-communication')
  .filter((route) => route.path !== '/club-documents')
  .filter((route) => route.path !== '/club-events')
  .filter((route) => route.path !== '/club-sponsors')
  .filter((route) => route.path !== '/club-fees')
  .filter((route) => route.path !== '/club-payments')
  .filter((route) => route.path !== '/club-reports')
  .map((route) => ({
  path: route.path,
  name: route.name,
  component: ClubConceptModuleView,
  meta: withMeta({ products: clubOnly, moduleMeta: route }),
}));

const routes = [
  { path: '/register', name: 'register', component: Register, meta: withMeta({ public: true, products: allProducts }) },
  { path: '/login', name: 'login', component: Login, meta: withMeta({ public: true, products: allProducts }) },
  { path: '/activate/:activationCode', name: 'activate', component: Activate, meta: withMeta({ public: true, products: allProducts }) },
  { path: '/forgot-password', name: 'forgot-password', component: ForgotPassword, meta: withMeta({ public: true, products: allProducts }) },
  { path: '/reset-password/:token', name: 'reset-password', component: ResetPassword, meta: withMeta({ public: true, products: allProducts }) },
  { path: '/', name: 'home', component: Home, meta: withMeta({ public: true, products: allProducts }) },
  { path: '/vereinssoftware-tischtennis', name: 'club-software-seo', component: TableTennisClubSoftware, meta: withMeta({ public: true, products: fullAppProducts }) },
  { path: '/mitgliederverwaltung-verein', name: 'member-management-seo', component: ClubMemberManagementPage, meta: withMeta({ public: true, products: fullAppProducts }) },
  { path: '/trainingsplanung-tischtennis', name: 'training-planning-seo', component: TrainingPlanningPage, meta: withMeta({ public: true, products: fullAppProducts }) },
  { path: '/turniersoftware-tischtennis', name: 'tournament-software-seo', component: TableTennisTournamentSoftwarePage, meta: withMeta({ public: true, products: fullAppProducts }) },
  { path: '/createclub', name: 'create-club', component: CreateClub, meta: withMeta({ products: fullAppProducts }) },
  { path: '/showclub/:clubId', name: 'show-club', component: ClubView, meta: withMeta({ products: fullAppProducts }) },
  { path: '/members', name: 'members', component: MembersView, meta: withMeta({ products: fullAppProducts, permission: ['members', 'read'] }) },
  { path: '/diary', name: 'diary', component: DiaryView, meta: withMeta({ products: trainerOnly }) },
  { path: '/calendar', name: 'calendar', component: CalendarView, meta: withMeta({ products: allProducts, anyPermission: [['diary', 'read'], ['schedule', 'read'], ['tournaments', 'read']] }) },
  { path: '/pending-approvals', name: 'pending-approvals', component: PendingApprovalsView, meta: withMeta({ products: fullAppProducts, capability: 'approvals' }) },
  { path: '/schedule', name: 'schedule', component: ScheduleView, meta: withMeta({ products: fullAppProducts, permission: ['schedule', 'read'] }) },
  { path: '/friendly-matches', name: 'friendly-matches', component: ScheduleView, props: { friendlyOnly: true }, meta: withMeta({ products: fullAppProducts }) },
  { path: '/tournaments', name: 'tournaments', component: TournamentsView, meta: withMeta({ products: fullAppProducts, permission: ['tournaments', 'read'] }) },
  { path: '/tournament-participations', name: 'tournament-participations', component: OfficialTournaments, meta: withMeta({ products: fullAppProducts, permission: ['tournaments', 'read'] }) },
  { path: '/training-stats', name: 'training-stats', component: TrainingStatsView, meta: withMeta({ products: fullAppProducts, permission: ['statistics', 'read'] }) },
  { path: '/club-settings', name: 'club-settings', component: ClubSettings, meta: withMeta({ products: fullAppProducts, capability: 'admin' }) },
  { path: '/predefined-activities', name: 'predefined-activities', component: PredefinedActivities, meta: withMeta({ products: fullAppProducts, permission: ['predefined_activities', 'read'] }) },
  { path: '/mytischtennis-account', name: 'mytischtennis-account', component: MyTischtennisAccount, meta: withMeta({ products: allProducts }) },
  { path: '/clicktt-account', name: 'clicktt-account', component: ClickTtAccount, meta: withMeta({ products: allProducts }) },
  { path: '/team-management', name: 'team-management', component: TeamManagementView, meta: withMeta({ products: fullAppProducts, permission: ['teams', 'read'] }) },
  { path: '/permissions', name: 'permissions', component: PermissionsView, meta: withMeta({ products: fullAppProducts, permission: ['permissions', 'read'] }) },
  { path: '/club-users', name: 'club-users', component: PermissionsView, props: { viewMode: 'users' }, meta: withMeta({ products: clubOnly, permission: ['permissions', 'read'] }) },
  { path: '/club-roles', name: 'club-roles', component: PermissionsView, props: { viewMode: 'roles' }, meta: withMeta({ products: clubOnly, permission: ['permissions', 'read'] }) },
  { path: '/logs', name: 'logs', component: LogsView, meta: withMeta({ products: fullAppProducts }) },
  { path: '/clicktt', name: 'clicktt', component: ClickTtView, meta: withMeta({ products: fullAppProducts }) },
  { path: '/member-transfer-settings', name: 'member-transfer-settings', component: MemberTransferSettingsView, meta: withMeta({ products: fullAppProducts }) },
  { path: '/personal-settings', name: 'personal-settings', component: PersonalSettings, meta: withMeta({ products: allProducts }) },
  { path: '/orders', name: 'orders', component: OrdersView, meta: withMeta({ products: allProducts }) },
  { path: '/billing', name: 'billing', component: BillingView, meta: withMeta({ products: trainerOnly }) },
  { path: '/club-requests', name: 'club-requests', component: ClubRequestsView, meta: withMeta({ products: clubOnly, permission: ['requests', 'read'] }) },
  { path: '/club-tasks', name: 'club-tasks', component: ClubTasksView, meta: withMeta({ products: clubOnly, permission: ['tasks', 'read'] }) },
  { path: '/club-history', name: 'club-history', component: ClubHistoryView, meta: withMeta({ products: clubOnly, permission: ['history', 'read'] }) },
  { path: '/club-statistics', name: 'club-statistics', component: ClubStatisticsView, meta: withMeta({ products: clubOnly, permission: ['statistics', 'read'] }) },
  { path: '/club-archive', name: 'club-archive', component: ClubArchiveView, meta: withMeta({ products: clubOnly, permission: ['archive', 'read'] }) },
  { path: '/club-accounts', name: 'club-accounts', component: ClubAccountsView, meta: withMeta({ products: clubOnly, permission: ['finance_accounts', 'read'] }) },
  { path: '/club-invoices', name: 'club-invoices', component: ClubInvoicesView, meta: withMeta({ products: clubOnly, permission: ['finance_invoices', 'read'] }) },
  { path: '/club-communication', name: 'club-communication', component: ClubCommunicationView, meta: withMeta({ products: clubOnly, permission: ['communication', 'read'] }) },
  { path: '/club-documents', name: 'club-documents', component: ClubOperationsWorkspaceView, props: { moduleKey: 'documents' }, meta: withMeta({ products: clubOnly, permission: ['settings', 'read'] }) },
  { path: '/club-events', name: 'club-events', component: ClubOperationsWorkspaceView, props: { moduleKey: 'events' }, meta: withMeta({ products: clubOnly, permission: ['schedule', 'read'] }) },
  { path: '/club-sponsors', name: 'club-sponsors', component: ClubOperationsWorkspaceView, props: { moduleKey: 'sponsors' }, meta: withMeta({ products: clubOnly, permission: ['settings', 'read'] }) },
  { path: '/club-fees', name: 'club-fees', component: ClubOperationsWorkspaceView, props: { moduleKey: 'fees' }, meta: withMeta({ products: clubOnly, permission: ['finance_invoices', 'write'] }) },
  { path: '/club-payments', name: 'club-payments', component: ClubOperationsWorkspaceView, props: { moduleKey: 'payments' }, meta: withMeta({ products: clubOnly, permission: ['finance_accounts', 'read'] }) },
  { path: '/club-reports', name: 'club-reports', component: ClubOperationsWorkspaceView, props: { moduleKey: 'reports' }, meta: withMeta({ products: clubOnly, permission: ['statistics', 'read'] }) },
  ...conceptRoutes,
  { path: '/impressum', name: 'impressum', component: Impressum, meta: withMeta({ public: true, products: allProducts }) },
  { path: '/datenschutz', name: 'datenschutz', component: Datenschutz, meta: withMeta({ public: true, products: allProducts }) },
  { path: '/konto-loeschen', name: 'konto-loeschen', component: KontoLoeschen, meta: withMeta({ public: true, products: allProducts }) },
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

router.beforeEach((to, from, next) => {
  const currentProduct = resolveCurrentProduct();
  const defaultHomeRoute = getDefaultHomeRoute(currentProduct);
  const isAuthenticated = Boolean(safeSessionStorage.getItem('token'));
  const isPublicRoute = to.matched.some((record) => record.meta?.public);
  const routeProducts = to.matched.flatMap((record) => record.meta?.products || []);

  if (!isProductRouteAllowed(currentProduct, routeProducts)) {
    next(defaultHomeRoute);
    return;
  }

  if (!isAuthenticated && !isPublicRoute) {
    next({
      path: '/login',
      query: to.fullPath && to.fullPath !== '/' ? { redirect: to.fullPath } : {}
    });
    return;
  }

  if (isAuthenticated && (to.path === '/login' || to.path === '/register')) {
    next(defaultHomeRoute);
    return;
  }

  if (isAuthenticated && !isPublicRoute && !isRouteAuthorized(to)) {
    next(defaultHomeRoute);
    return;
  }

  next();
});

router.afterEach((to) => {
  applySeoForPath(to.path);
});

export default router;
