#!/usr/bin/env node

const fs = require('fs');
const path = require('path');

const ROOT = process.cwd();
const dashboardRoot = path.join(ROOT, 'src', 'app', 'dashboard');
const scanRoots = [
  path.join(ROOT, 'src', 'app'),
  path.join(ROOT, 'src', 'features'),
  path.join(ROOT, 'src', 'config')
];
const legacyNavRoutes = [
  '/dashboard/billing',
  '/dashboard/chat',
  '/dashboard/elements/icons',
  '/dashboard/exclusive',
  '/dashboard/forms',
  '/dashboard/kanban',
  '/dashboard/product',
  '/dashboard/react-query',
  '/dashboard/workspaces'
];

function walk(dir, predicate = () => true, results = []) {
  if (!fs.existsSync(dir)) {
    return results;
  }

  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
    const fullPath = path.join(dir, entry.name);

    if (entry.isDirectory()) {
      walk(fullPath, predicate, results);
      continue;
    }

    if (predicate(fullPath)) {
      results.push(fullPath);
    }
  }

  return results;
}

function toRoutePattern(filePath) {
  const relative = path.relative(dashboardRoot, filePath).replace(/\\/g, '/');
  const withoutPage = relative.replace(/\/page\.tsx$/, '').replace(/^page\.tsx$/, '');
  const routePath = withoutPage ? `/dashboard/${withoutPage}` : '/dashboard';

  return routePath.split('/').filter(Boolean);
}

function matchesRoute(routePattern, routePath) {
  const targetSegments = routePath.split('/').filter(Boolean);

  if (routePattern.length !== targetSegments.length) {
    return false;
  }

  return routePattern.every((segment, index) => {
    if (segment.startsWith('[') && segment.endsWith(']')) {
      return targetSegments[index].length > 0;
    }

    return segment === targetSegments[index];
  });
}

function collectRoutePatterns() {
  return walk(dashboardRoot, (filePath) => filePath.endsWith(`${path.sep}page.tsx`)).map(
    toRoutePattern
  );
}

function collectDashboardReferences() {
  const routeRegex = /\/dashboard(?:\/[A-Za-z0-9-_[\]/]+)?/g;
  const references = new Map();

  for (const root of scanRoots) {
    const files = walk(root, (filePath) => /\.(ts|tsx|js|jsx|md)$/.test(filePath));

    for (const filePath of files) {
      const content = fs.readFileSync(filePath, 'utf8');
      const matches = content.match(routeRegex) ?? [];

      for (const match of matches) {
        const normalized = match.replace(/\/+$/, '');
        if (!references.has(normalized)) {
          references.set(normalized, []);
        }

        references.get(normalized).push(path.relative(ROOT, filePath).replace(/\\/g, '/'));
      }
    }
  }

  return references;
}

function main() {
  const routePatterns = collectRoutePatterns();
  const references = collectDashboardReferences();
  const missingRoutes = [];

  for (const [routePath, files] of references.entries()) {
    const exists = routePatterns.some((pattern) => matchesRoute(pattern, routePath));

    if (!exists) {
      missingRoutes.push({ routePath, files });
    }
  }

  const navConfigPath = path.join(ROOT, 'src', 'config', 'nav-config.ts');
  const navConfig = fs.existsSync(navConfigPath) ? fs.readFileSync(navConfigPath, 'utf8') : '';
  const leakedLegacyRoutes = legacyNavRoutes.filter((routePath) => navConfig.includes(routePath));

  if (missingRoutes.length === 0 && leakedLegacyRoutes.length === 0) {
    console.log('check-routes: passed');
    return;
  }

  if (missingRoutes.length > 0) {
    console.error('check-routes: missing dashboard route targets detected');
    for (const { routePath, files } of missingRoutes) {
      console.error(`- ${routePath}`);
      console.error(`  referenced from: ${files.join(', ')}`);
    }
  }

  if (leakedLegacyRoutes.length > 0) {
    console.error('check-routes: legacy/demo routes are still present in nav-config');
    for (const routePath of leakedLegacyRoutes) {
      console.error(`- ${routePath}`);
    }
  }

  process.exitCode = 1;
}

main();
