import type { RouteLocationNormalizedLoadedGeneric } from 'vue-router';

import { getTabKey } from '@easyflow/stores';

import { describe, expect, it } from 'vitest';

import { getRouteViewKey, shouldUseKeepAlive } from './route-view';

interface RouteOptions {
  fullPath: string;
  id?: string;
  keepAlive?: boolean;
  name: string;
  navTitle?: string;
  pageKey?: string;
  paramId?: string;
  path: string;
}

function createRoute(
  options: RouteOptions,
): RouteLocationNormalizedLoadedGeneric {
  const query: Record<string, string> = {};
  if (options.id) {
    query.id = options.id;
  }
  if (options.navTitle) {
    query.navTitle = options.navTitle;
  }
  if (options.pageKey) {
    query.pageKey = options.pageKey;
  }
  return {
    fullPath: options.fullPath,
    hash: '',
    matched: [],
    meta: {
      keepAlive: options.keepAlive,
      title: options.name,
    },
    name: options.name,
    params: options.paramId ? { id: options.paramId } : {},
    path: options.path,
    query,
    redirectedFrom: undefined,
  } as RouteLocationNormalizedLoadedGeneric;
}

describe('route view identity', () => {
  it('separates list and detail rendering while preserving one tab key', () => {
    const listRoute = createRoute({
      fullPath: '/ai/workflow',
      keepAlive: false,
      name: 'WorkflowList',
      path: '/ai/workflow',
    });
    const designRoute = createRoute({
      fullPath:
        '/ai/workflow/design?id=1&pageKey=/ai/workflow&navTitle=Workflow',
      id: '1',
      name: 'WorkflowDesign',
      navTitle: 'Workflow',
      pageKey: '/ai/workflow',
      path: '/ai/workflow/design',
    });

    expect(getTabKey(listRoute)).toBe('/ai/workflow');
    expect(getTabKey(designRoute)).toBe('/ai/workflow');
    expect(getRouteViewKey(listRoute)).not.toBe(getRouteViewKey(designRoute));
  });

  it('keeps title-only query changes on the same component instance', () => {
    const firstRoute = createRoute({
      fullPath: '/ai/workflow/design?id=1&pageKey=/ai/workflow&navTitle=First',
      id: '1',
      name: 'WorkflowDesign',
      navTitle: 'First',
      pageKey: '/ai/workflow',
      path: '/ai/workflow/design',
    });
    const renamedRoute = createRoute({
      fullPath:
        '/ai/workflow/design?id=1&pageKey=/ai/workflow&navTitle=Renamed',
      id: '1',
      name: 'WorkflowDesign',
      navTitle: 'Renamed',
      pageKey: '/ai/workflow',
      path: '/ai/workflow/design',
    });

    expect(getRouteViewKey(firstRoute)).toBe(getRouteViewKey(renamedRoute));
  });

  it('replaces the component instance when the resource id changes', () => {
    const firstRoute = createRoute({
      fullPath: '/ai/workflow/design?id=1&pageKey=/ai/workflow',
      id: '1',
      name: 'WorkflowDesign',
      pageKey: '/ai/workflow',
      path: '/ai/workflow/design',
    });
    const secondRoute = createRoute({
      fullPath: '/ai/workflow/design?id=2&pageKey=/ai/workflow',
      id: '2',
      name: 'WorkflowDesign',
      pageKey: '/ai/workflow',
      path: '/ai/workflow/design',
    });

    expect(getRouteViewKey(firstRoute)).not.toBe(getRouteViewKey(secondRoute));
  });

  it('separates path-param resources that share a tab key', () => {
    const firstRoute = createRoute({
      fullPath: '/ai/agents/designer/1?pageKey=/ai/agents',
      name: 'AgentDesigner',
      pageKey: '/ai/agents',
      paramId: '1',
      path: '/ai/agents/designer/1',
    });
    const secondRoute = createRoute({
      fullPath: '/ai/agents/designer/2?pageKey=/ai/agents',
      name: 'AgentDesigner',
      pageKey: '/ai/agents',
      paramId: '2',
      path: '/ai/agents/designer/2',
    });

    expect(getRouteViewKey(firstRoute)).not.toBe(getRouteViewKey(secondRoute));
  });

  it('bypasses KeepAlive only when caching is explicitly disabled', () => {
    const uncachedRoute = createRoute({
      fullPath: '/ai/workflow',
      keepAlive: false,
      name: 'WorkflowList',
      path: '/ai/workflow',
    });
    const defaultRoute = createRoute({
      fullPath: '/ai/workflow/design?id=1',
      id: '1',
      name: 'WorkflowDesign',
      path: '/ai/workflow/design',
    });

    expect(shouldUseKeepAlive(uncachedRoute, true)).toBe(false);
    expect(shouldUseKeepAlive(defaultRoute, true)).toBe(true);
    expect(shouldUseKeepAlive(defaultRoute, false)).toBe(false);
  });
});
