import {createRouter, createWebHistory} from 'vue-router'
import Dashboard from '@/views/Dashboard.vue';
import Login from '@/views/Login.vue';
import Register from '@/views/Register.vue';
import Pairing from '@/views/Pairing.vue';
import store from '@/store';
import Profile from '@/views/Profile.vue';
import Settings from '@/views/Settings.vue';
import Friends from '@/views/Friends.vue';
import Groups from '@/views/Groups.vue';
import GroupNew from '@/views/GroupNew.vue';
import GroupDetail from '@/views/GroupDetail.vue';
import Inventory from '@/views/Inventory.vue';
import Search from '@/views/Search.vue';
import InventoryDetail from '@/views/InventoryDetail.vue';
import InventoryNew from '@/views/InventoryNew.vue';
import InventoryEdit from '@/views/InventoryEdit.vue';
import StorageLocation from '@/views/StorageLocation.vue';
import StorageLocationDetail from '@/views/StorageLocationDetail.vue';
import StorageLocationNew from '@/views/StorageLocationNew.vue';
import StorageLocationEdit from '@/views/StorageLocationEdit.vue';
import Admin from '@/views/Admin.vue';
import Swatch from '@/views/Swatch.vue';
import Files from '@/views/Files.vue';
import Print from "@/views/Print.vue";
import Scan from "@/views/Scan.vue";
import Workflows from '@/views/Workflows.vue';
import WorkflowDetail from '@/views/WorkflowDetail.vue';
import ShortId from '@/views/ShortId.vue';
import {encodeShortId, serializeShortId,decodeShortId, deserializeShortId} from '@/short-id';

import Account from '@/views/settings/Account.vue';
import Password from '@/views/settings/Password.vue';
import Privacy from '@/views/settings/Privacy.vue';
import Email from '@/views/settings/Email.vue';
import Notifications from '@/views/settings/Notifications.vue';
import Data from '@/views/settings/Data.vue';
import Preferences from '@/views/settings/Preferences.vue';


export function encodeHandleForUrl(handle) {
    return handle.replace(/#/g, "+");
}

export function decodeHandleFromUrl(segment) {
    return segment.replace(/\+/g, "#");
}

// item/group_item share this /inventory/:handle/:id shape; only owner-handle resolution (identity vs. group, see store.js) differs.
function itemDetailRoute(handle, item_local_id) {
    return handle ? `/inventory/${encodeHandleForUrl(handle)}/${item_local_id}` : null;
}

const EXPANDED_ROUTE_BUILDERS = {
    item: ({owner_identity_id, item_local_id}) =>
        itemDetailRoute(store.getters.identityHandleById[owner_identity_id], item_local_id),
    group_item: ({owner_group_id, item_local_id}) =>
        itemDetailRoute(store.getters.groupHandleById[owner_group_id], item_local_id),
    group: ({group_id}) => `/groups/${group_id}`,
    storage_location: ({storage_location_id}) => `/storage-locations/${storage_location_id}`,
    workflow: ({workflow_id}) => `/workflows/${workflow_id}`,
};

// Kinds whose route needs identityHandleById/groupHandleById (from state.idmap); ShortId.vue only waits on an idmap fetch for these.
export const NEEDS_IDMAP = new Set(['item', 'group_item']);

export function expandedRoute({kind, ...fields}) {
    const buildRoute = EXPANDED_ROUTE_BUILDERS[kind];
    return buildRoute ? buildRoute(fields) : null;
}

export function shortenedRoute(named) {
    return '/' + encodeShortId(serializeShortId(named));
}

const routes = [{path: '/', component: Dashboard, meta: {requiresAuth: true}}, {
    path: '/inventory',
    component: Inventory,
    meta: {requiresAuth: true}
}, {
    path: '/inventory/:handle/:id',
    component: InventoryDetail,
    meta: {requiresAuth: true},
    props: true
}, {
    path: '/inventory/:handle/:id/edit',
    component: InventoryEdit,
    meta: {requiresAuth: true},
    props: true
}, {
    // Label/short-link entry point; alias of /inventory/:handle/:id. See docs/implementation.md#item-short-link-redirect-route.
    path: '/i/:handle/:id',
    redirect: to => `/inventory/${to.params.handle}/${to.params.id}`
}, {
    // beforeEnter, not redirect: falls through to ShortId.vue when the route can't resolve synchronously. See docs/implementation.md#beforeenter-guard-vs-redirect-for-short_id.
    path: '/:short_id',
    component: ShortId,
    props: true,
    beforeEnter: to => {
        console.log(to);
        const p = deserializeShortId(decodeShortId(to.params.short_id))
        console.log(p)
        const url = expandedRoute(p);
        console.log(url);
        return url;
    }
}, {path: '/inventory/new', component: InventoryNew, meta: {requiresAuth: true}}, {
    path: '/friends',
    component: Friends,
    meta: {requiresAuth: true}
}, {
    path: '/groups',
    component: Groups,
    meta: {requiresAuth: true}
}, {
    path: '/groups/new',
    component: GroupNew,
    meta: {requiresAuth: true}
}, {
    path: '/groups/:id',
    component: GroupDetail,
    meta: {requiresAuth: true},
    props: true
}, {path: '/files', component: Files, meta: {requiresAuth: true}
}, {path: '/workflows',
    component: Workflows,
    meta: {requiresAuth: true},
}, {path: '/workflows/:id/:phase?',
    name: 'workflow-detail',
    component: WorkflowDetail,
    meta: {requiresAuth: true},
    props: true
}, {path: '/admin',
    component: Admin,
    meta: {requiresAuth: true}
}, {path: '/swatch', component: Swatch, meta: {requiresAuth: true}}, {
    path: '/print',
    component: Print,
    meta: {requiresAuth: true},
    props: route => {
        const {kind, ...components} = route.query;
        // queryFields lets any base var (e.g. ?text=...) be set directly, without going through
        // a `kind` builder - see Print.vue's varValues.
        return {prefill: kind ? {kind, components} : null, queryFields: components};
    }
}, {
    path: '/scan',
    component: Scan,
    meta: {requiresAuth: true},
}, {
    path: '/search/:query',
    component: Search,
    meta: {requiresAuth: true},
    props: true
}, {path: '/login', component: Login, meta: {requiresAuth: false}}, {
    path: '/register',
    component: Register,
    meta: {requiresAuth: false}
}, {path: '/pairing', component: Pairing, meta: {requiresAuth: false}}, {
    path: '/profile',
    component: Profile,
    meta: {requiresAuth: true}
}, {
    path: '/settings', component: Settings, meta: {requiresAuth: true}, children: [{
        path: '', name: 'account', component: Account, meta: {requiresAuth: true}
    },{
        path: 'password/', name: 'password', component: Password, meta: {requiresAuth: true}
    }, {
        path: 'privacy/', name: 'privacy', component: Privacy, meta: {requiresAuth: true}
    }, {
        path: 'email/', name: 'email', component: Email, meta: {requiresAuth: true}
    }, {
        path: 'notifications/', name: 'notifications', component: Notifications, meta: {requiresAuth: true}
    }, {
        path: 'data/', name: 'data', component: Data, meta: {requiresAuth: true}
    }, {
        path: 'preferences/', name: 'preferences', component: Preferences, meta: {requiresAuth: true}
    }]
}, {
    path: '/storage-location',
    component: StorageLocation,
    meta: {requiresAuth: true}
}, {
    path: '/storage-locations/:id',
    component: StorageLocationDetail,
    meta: {requiresAuth: true},
    props: true
}, {
    path: '/storage-locations/:id/edit',
    component: StorageLocationEdit,
    meta: {requiresAuth: true},
    props: true
}, {
    path: '/storage-locations/new',
    component: StorageLocationNew,
    meta: {requiresAuth: true}
}, {
    path: '/debug/:short_id',
    component: ShortId,
    props: true
}, {path: '/:pathMatch(.*)*', redirect: '/'}]

const router = createRouter({
    history: createWebHistory(), linkActiveClass: "active", routes,
})

router.beforeEach((to/*, from*/) => {
    // if this route requires auth, check if logged in, if not, redirect to login page.
    if (to.meta.requiresAuth && !store.getters.isLoggedIn) {
        console.log("Not logged in, redirecting to login page")
        return {
            path: '/login', // save the location we were at to come back later
            query: {redirect: to.fullPath},
        }
    }
})

export default router