import { createRouter, createWebHistory } from 'vue-router';
import PokemonList from '../views/PokemonList.vue';
import PokemonDetail from '../views/PokemonDetail.vue';
import HabitatList from '../views/HabitatList.vue';
import HabitatDetail from '../views/HabitatDetail.vue';
import ItemsList from '../views/ItemsList.vue';
import ItemDetail from '../views/ItemDetail.vue';
import RecipeList from '../views/RecipeList.vue';
import RecipeDetail from '../views/RecipeDetail.vue';
import DailyChecklistView from '../views/DailyChecklistView.vue';
import LifeView from '../views/LifeView.vue';
import ComingSoonView from '../views/ComingSoonView.vue';
import AdminView from '../views/AdminView.vue';
import ForgotPasswordView from '../views/ForgotPasswordView.vue';
import LoginView from '../views/LoginView.vue';
import UserProfileView from '../views/UserProfileView.vue';
import RegisterView from '../views/RegisterView.vue';
import ResetPasswordView from '../views/ResetPasswordView.vue';
import VerifyEmailView from '../views/VerifyEmailView.vue';
import { api, getAuthToken, setAuthToken } from '../services/api';
import type { RouteSeoConfig } from '../seo';

const seo = (config: RouteSeoConfig) => config;

export const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: '/', redirect: '/pokemon' },
    { path: '/pokemon', name: 'pokemon-list', component: PokemonList, meta: { seo: seo({ titleKey: 'pages.pokemon.title', descriptionKey: 'pages.pokemon.subtitle' }) } },
    {
      path: '/pokemon/new',
      name: 'pokemon-new',
      component: PokemonList,
      meta: {
        requiredPermission: 'pokemon.create',
        editorModal: true,
        seo: seo({ titleKey: 'pages.pokemon.newTitle', descriptionKey: 'pages.pokemon.editSubtitle', canonicalPath: '/pokemon', noindex: true })
      }
    },
    {
      path: '/pokemon/:id/edit',
      name: 'pokemon-edit',
      component: PokemonDetail,
      meta: {
        requiredPermission: 'pokemon.update',
        editorModal: true,
        seo: seo({
          titleKey: 'pages.pokemon.editKicker',
          descriptionKey: 'pages.pokemon.editSubtitle',
          canonicalPath: (route) => `/pokemon/${String(route.params.id)}`,
          noindex: true
        })
      }
    },
    { path: '/pokemon/:id', name: 'pokemon-detail', component: PokemonDetail, meta: { seo: seo({ titleKey: 'pages.pokemon.detailKicker', descriptionKey: 'pages.pokemon.subtitle' }) } },
    { path: '/habitats', name: 'habitat-list', component: HabitatList, meta: { seo: seo({ titleKey: 'pages.habitats.title', descriptionKey: 'pages.habitats.subtitle' }) } },
    {
      path: '/habitats/new',
      name: 'habitat-new',
      component: HabitatList,
      meta: {
        requiredPermission: 'habitats.create',
        editorModal: true,
        seo: seo({ titleKey: 'pages.habitats.newTitle', descriptionKey: 'pages.habitats.editSubtitle', canonicalPath: '/habitats', noindex: true })
      }
    },
    {
      path: '/habitats/:id/edit',
      name: 'habitat-edit',
      component: HabitatDetail,
      meta: {
        requiredPermission: 'habitats.update',
        editorModal: true,
        seo: seo({
          titleKey: 'pages.habitats.detailKicker',
          descriptionKey: 'pages.habitats.editSubtitle',
          canonicalPath: (route) => `/habitats/${String(route.params.id)}`,
          noindex: true
        })
      }
    },
    { path: '/habitats/:id', name: 'habitat-detail', component: HabitatDetail, meta: { seo: seo({ titleKey: 'pages.habitats.detailKicker', descriptionKey: 'pages.habitats.subtitle' }) } },
    { path: '/items', name: 'item-list', component: ItemsList, meta: { seo: seo({ titleKey: 'pages.items.title', descriptionKey: 'pages.items.subtitle' }) } },
    {
      path: '/items/new',
      name: 'item-new',
      component: ItemsList,
      meta: {
        requiredPermission: 'items.create',
        editorModal: true,
        seo: seo({ titleKey: 'pages.items.newTitle', descriptionKey: 'pages.items.editSubtitle', canonicalPath: '/items', noindex: true })
      }
    },
    {
      path: '/items/:id/edit',
      name: 'item-edit',
      component: ItemDetail,
      meta: {
        requiredPermission: 'items.update',
        editorModal: true,
        seo: seo({
          titleKey: 'pages.items.editKicker',
          descriptionKey: 'pages.items.editSubtitle',
          canonicalPath: (route) => `/items/${String(route.params.id)}`,
          noindex: true
        })
      }
    },
    { path: '/items/:id', name: 'item-detail', component: ItemDetail, meta: { seo: seo({ titleKey: 'pages.items.detailKicker', descriptionKey: 'pages.items.subtitle' }) } },
    { path: '/recipes', name: 'recipe-list', component: RecipeList, meta: { seo: seo({ titleKey: 'pages.recipes.title', descriptionKey: 'pages.recipes.subtitle' }) } },
    {
      path: '/recipes/new',
      name: 'recipe-new',
      component: RecipeList,
      meta: {
        requiredPermission: 'recipes.create',
        editorModal: true,
        seo: seo({ titleKey: 'pages.recipes.newTitle', descriptionKey: 'pages.recipes.editSubtitle', canonicalPath: '/recipes', noindex: true })
      }
    },
    {
      path: '/recipes/:id/edit',
      name: 'recipe-edit',
      component: RecipeDetail,
      meta: {
        requiredPermission: 'recipes.update',
        editorModal: true,
        seo: seo({
          titleKey: 'pages.recipes.editKicker',
          descriptionKey: 'pages.recipes.editSubtitle',
          canonicalPath: (route) => `/recipes/${String(route.params.id)}`,
          noindex: true
        })
      }
    },
    { path: '/recipes/:id', name: 'recipe-detail', component: RecipeDetail, meta: { seo: seo({ titleKey: 'pages.recipes.detailKicker', descriptionKey: 'pages.recipes.subtitle' }) } },
    {
      path: '/automation',
      name: 'automation',
      component: ComingSoonView,
      props: { page: 'automation' },
      meta: { seo: seo({ titleKey: 'pages.comingSoon.sections.automation.title', descriptionKey: 'pages.comingSoon.sections.automation.subtitle', noindex: true }) }
    },
    {
      path: '/dish',
      name: 'dish',
      component: ComingSoonView,
      props: { page: 'dish' },
      meta: { seo: seo({ titleKey: 'pages.comingSoon.sections.dish.title', descriptionKey: 'pages.comingSoon.sections.dish.subtitle', noindex: true }) }
    },
    {
      path: '/events',
      name: 'events',
      component: ComingSoonView,
      props: { page: 'events' },
      meta: { seo: seo({ titleKey: 'pages.comingSoon.sections.events.title', descriptionKey: 'pages.comingSoon.sections.events.subtitle', noindex: true }) }
    },
    {
      path: '/actions',
      name: 'actions',
      component: ComingSoonView,
      props: { page: 'actions' },
      meta: { seo: seo({ titleKey: 'pages.comingSoon.sections.actions.title', descriptionKey: 'pages.comingSoon.sections.actions.subtitle', noindex: true }) }
    },
    {
      path: '/dream-island',
      name: 'dream-island',
      component: ComingSoonView,
      props: { page: 'dreamIsland' },
      meta: { seo: seo({ titleKey: 'pages.comingSoon.sections.dreamIsland.title', descriptionKey: 'pages.comingSoon.sections.dreamIsland.subtitle', noindex: true }) }
    },
    {
      path: '/clothes',
      name: 'clothes',
      component: ComingSoonView,
      props: { page: 'clothes' },
      meta: { seo: seo({ titleKey: 'pages.comingSoon.sections.clothes.title', descriptionKey: 'pages.comingSoon.sections.clothes.subtitle', noindex: true }) }
    },
    { path: '/checklist', component: DailyChecklistView, meta: { seo: seo({ titleKey: 'pages.checklist.title', descriptionKey: 'pages.checklist.subtitle' }) } },
    { path: '/life', component: LifeView, meta: { seo: seo({ titleKey: 'pages.life.title', descriptionKey: 'pages.life.subtitle' }) } },
    { path: '/admin', component: AdminView, meta: { requiredPermission: 'admin.access', seo: seo({ titleKey: 'pages.admin.title', descriptionKey: 'pages.admin.subtitle', noindex: true }) } },
    { path: '/profile', component: UserProfileView, meta: { requiresAuth: true, seo: seo({ titleKey: 'pages.profile.title', descriptionKey: 'pages.profile.subtitle', noindex: true }) } },
    { path: '/profile/:id', component: UserProfileView, meta: { seo: seo({ titleKey: 'pages.profile.title', descriptionKey: 'pages.profile.publicSubtitle' }) } },
    { path: '/login', component: LoginView, meta: { seo: seo({ titleKey: 'auth.loginTitle', descriptionKey: 'auth.loginSubtitle', noindex: true }) } },
    { path: '/forgot-password', component: ForgotPasswordView, meta: { seo: seo({ titleKey: 'auth.requestResetTitle', descriptionKey: 'auth.requestResetSubtitle', noindex: true }) } },
    { path: '/reset-password', component: ResetPasswordView, meta: { seo: seo({ titleKey: 'auth.resetTitle', descriptionKey: 'auth.resetSubtitle', noindex: true }) } },
    { path: '/register', component: RegisterView, meta: { seo: seo({ titleKey: 'auth.registerTitle', descriptionKey: 'auth.registerSubtitle', noindex: true }) } },
    { path: '/verify-email', component: VerifyEmailView, meta: { seo: seo({ titleKey: 'auth.verifyTitle', descriptionKey: 'auth.verifySubtitle', noindex: true }) } }
  ],
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) return savedPosition;
    if (to.meta.editorModal === true || from.meta.editorModal === true) return false;
    return { top: 0 };
  }
});

router.beforeEach(async (to) => {
  const requiredPermissions = to.matched
    .map((record) => record.meta.requiredPermission)
    .filter((permission): permission is string => typeof permission === 'string');
  const requiredAnyPermissions = to.matched.flatMap((record) =>
    Array.isArray(record.meta.requiredAnyPermission)
      ? record.meta.requiredAnyPermission.filter((permission): permission is string => typeof permission === 'string')
      : []
  );
  const requiresVerified = to.matched.some((record) => record.meta.requiresVerified === true) || requiredPermissions.length > 0 || requiredAnyPermissions.length > 0;
  const requiresAuth = requiresVerified || to.matched.some((record) => record.meta.requiresAuth === true);

  if (!requiresAuth) {
    return true;
  }

  if (!getAuthToken()) {
    return { path: '/login', query: { redirect: to.fullPath } };
  }

  try {
    const response = await api.me();
    if (requiresVerified && !response.user.emailVerified) {
      return { path: '/login', query: { redirect: to.fullPath } };
    }

    const permissionSet = new Set(response.user.permissions);
    if (requiredPermissions.some((permission) => !permissionSet.has(permission))) {
      return { path: '/pokemon' };
    }
    if (requiredAnyPermissions.length && !requiredAnyPermissions.some((permission) => permissionSet.has(permission))) {
      return { path: '/pokemon' };
    }

    return true;
  } catch {
    setAuthToken(null);
    return { path: '/login', query: { redirect: to.fullPath } };
  }
});
