import * as plugins from './plugins.js';
import * as appstate from './appstate.js';

const SmartRouter = plugins.domtools.plugins.smartrouter.SmartRouter;

export const validViews = ['overview', 'buckets', 'browser', 'policies', 'config', 'access keys'] as const;

export type TValidView = typeof validViews[number];

class AppRouter {
  private router: InstanceType<typeof SmartRouter>;
  private initialized = false;
  private suppressStateUpdate = false;

  constructor() {
    this.router = new SmartRouter({ debug: false });
  }

  public init(): void {
    if (this.initialized) return;
    this.setupRoutes();
    this.setupStateSync();
    this.handleInitialRoute();
    this.initialized = true;
  }

  private viewToPath(view: string): string {
    return `/${view.replace(/\s+/g, '-')}`;
  }

  private pathToView(path: string): string {
    const segment = path.split('/').filter(Boolean)[0] || '';
    return segment.replace(/-/g, ' ');
  }

  private setupRoutes(): void {
    for (const view of validViews) {
      this.router.on(this.viewToPath(view), async () => {
        this.updateViewState(view);
      });
    }

    // Root redirect
    this.router.on('/', async () => {
      this.navigateTo(this.viewToPath('overview'));
    });
  }

  private setupStateSync(): void {
    appstate.uiStatePart.state.subscribe((uiState) => {
      if (this.suppressStateUpdate) return;

      const currentPath = window.location.pathname;
      const expectedPath = this.viewToPath(uiState.activeView);

      if (currentPath !== expectedPath) {
        this.suppressStateUpdate = true;
        this.router.pushUrl(expectedPath);
        this.suppressStateUpdate = false;
      }
    });
  }

  private handleInitialRoute(): void {
    const path = window.location.pathname;

    if (!path || path === '/') {
      this.router.pushUrl(this.viewToPath('overview'));
    } else {
      const view = this.pathToView(path);
      if (validViews.includes(view as TValidView)) {
        this.updateViewState(view as TValidView);
      } else {
        this.router.pushUrl(this.viewToPath('overview'));
      }
    }
  }

  private updateViewState(view: string): void {
    this.suppressStateUpdate = true;
    const currentState = appstate.uiStatePart.getState();
    if (currentState.activeView !== view) {
      appstate.uiStatePart.setState({
        ...currentState,
        activeView: view,
      });
    }
    this.suppressStateUpdate = false;
  }

  public navigateTo(path: string): void {
    this.router.pushUrl(path);
  }

  public navigateToView(view: string): void {
    if (validViews.includes(view as TValidView)) {
      this.navigateTo(this.viewToPath(view));
    } else {
      this.navigateTo(this.viewToPath('overview'));
    }
  }

  public destroy(): void {
    this.router.destroy();
    this.initialized = false;
  }
}

export const appRouter = new AppRouter();
