#!/bin/bash
set -euo pipefail

# POST-CHECK: Frontend — CSS, Forms, Components, I18n
# C3a, C3-C7, C9, C11, C24-C27, C36-C37, C49, C52: Page structure, forms, i18n, routing

FAIL=false

# POST-CHECK C3a: Frontend must not be empty if Layer 3 was planned (BLOCKING)
APP_TSX=$(find web/ src/ -name "App.tsx" -not -path "*/node_modules/*" 2>/dev/null | head -1)
if [ -n "$APP_TSX" ]; then
  # Check for DynamicRouter pattern (v3.7+)
  COMPONENT_REGISTRY=$(find web/ src/ -name "componentRegistry.generated.ts" -not -path "*/node_modules/*" 2>/dev/null | head -1)
  if [ -n "$COMPONENT_REGISTRY" ]; then
    echo "OK: componentRegistry.generated.ts found (DynamicRouter pattern)"
  else
    EMPTY_ROUTES=$(grep -P "applicationRoutes.*=\s*\{[\s/]*\}" "$APP_TSX" 2>/dev/null || true)
    if [ -n "$EMPTY_ROUTES" ]; then
      echo "BLOCKING: applicationRoutes in App.tsx is empty — Layer 3 frontend was NOT executed"
      echo "Expected: at least one application key with route definitions"
      echo "Fix: Run Layer 3 (scaffold_routes + scaffold_extension)"
      FAIL=true
    fi
  fi

  PAGE_COUNT=$(find web/ src/ -path "*/pages/*" -name "*.tsx" -not -path "*/node_modules/*" 2>/dev/null | wc -l)
  if [ "$PAGE_COUNT" -eq 0 ]; then
    echo "BLOCKING: No page components found in pages/ directory"
    echo "Fix: Generate pages via scaffold_extension or /ui-components"
    FAIL=true
  fi

  NAV_ROUTES=$(find web/ src/ -name "navRoutes.generated.ts" -not -path "*/node_modules/*" 2>/dev/null | head -1)
  if [ -z "$NAV_ROUTES" ]; then
    echo "BLOCKING: navRoutes.generated.ts not found — scaffold_routes was never called"
    echo "Fix: Run scaffold_routes(source: 'controllers', outputFormat: 'componentRegistry')"
    FAIL=true
  fi
fi

# POST-CHECK C3: Translation files must exist for all 4 languages (if frontend)
TSX_FILES=$(find src/pages/ -name "*.tsx" 2>/dev/null || true)
if [ -n "$TSX_FILES" ]; then
  NAMESPACES=$(grep -ohP "useTranslation\(\[?'([^']+)" $TSX_FILES 2>/dev/null | sed "s/.*'//" | sort -u || true)
  for NS in $NAMESPACES; do
    for LANG in fr en it de; do
      if [ ! -f "src/i18n/locales/$LANG/$NS.json" ]; then
        echo "WARNING: Missing translation file: src/i18n/locales/$LANG/$NS.json"
      fi
    done
  done
fi

# POST-CHECK C4: Forms must be full pages with routes — ZERO modals/popups/drawers/slide-overs
PAGE_FILES=$(find src/pages/ -name "*.tsx" 2>/dev/null || true)
if [ -n "$PAGE_FILES" ]; then
  MODAL_IMPORTS=$(grep -Pn "import.*(?:Modal|Dialog|Drawer|Popup|Sheet|SlideOver|Overlay)" $PAGE_FILES 2>/dev/null || true)
  if [ -n "$MODAL_IMPORTS" ]; then
    echo "WARNING: Form pages must NOT use Modal/Dialog/Drawer/Popup/SlideOver components"
    echo "$MODAL_IMPORTS"
    FAIL=true
  fi

  FORM_STATE=$(grep -Pn "useState.*(?:isOpen|showModal|showDialog|showCreate|showEdit|showForm|isCreating|isEditing|showDrawer|showPanel|showSlideOver|selectedEntity|editingEntity)" $PAGE_FILES 2>/dev/null || true)
  if [ -n "$FORM_STATE" ]; then
    echo "WARNING: Inline form state detected — forms embedded in ListPage as drawers/panels"
    echo "Create/Edit forms MUST be separate page components with their own URL routes"
    echo "$FORM_STATE"
    FAIL=true
  fi

  if [ "$FAIL" = true ]; then
    echo ""
    echo "Fix: Create EntityCreatePage.tsx with route /create and EntityEditPage.tsx with route /:id/edit"
    echo "NEVER embed create/edit forms as inline drawers, panels, or slide-overs in ListPage"
  fi
fi

# POST-CHECK C5: Create/Edit pages must exist as separate route pages (CRITICAL)
LIST_PAGES=$(find src/pages/ -name "*ListPage.tsx" -o -name "*sPage.tsx" 2>/dev/null | grep -v test || true)
if [ -n "$LIST_PAGES" ]; then
  FAIL_C5=false
  for LIST_PAGE in $LIST_PAGES; do
    PAGE_DIR=$(dirname "$LIST_PAGE")
    MODULE_NAME=$(basename "$PAGE_DIR")

    HAS_CREATE_NAV=$(grep -P "navigate\(.*['/]create" "$LIST_PAGE" 2>/dev/null || true)
    HAS_EDIT_NAV=$(grep -P "navigate\(.*['/]edit|navigate\(.*/:id/edit" "$LIST_PAGE" 2>/dev/null || true)

    CREATE_PAGE=$(find "$PAGE_DIR" -name "*CreatePage.tsx" 2>/dev/null || true)
    if [ -z "$CREATE_PAGE" ]; then
      if [ -n "$HAS_CREATE_NAV" ]; then
        echo "CRITICAL: Module $MODULE_NAME ListPage navigates to /create but CreatePage does NOT exist"
        echo "  Dead link: $HAS_CREATE_NAV"
        echo "  Fix: Create ${MODULE_NAME}CreatePage.tsx in $PAGE_DIR"
        FAIL_C5=true
      fi
    fi

    EDIT_PAGE=$(find "$PAGE_DIR" -name "*EditPage.tsx" 2>/dev/null || true)
    if [ -z "$EDIT_PAGE" ]; then
      if [ -n "$HAS_EDIT_NAV" ]; then
        echo "CRITICAL: Module $MODULE_NAME ListPage navigates to /:id/edit but EditPage does NOT exist"
        echo "  Dead link: $HAS_EDIT_NAV"
        echo "  Fix: Create ${MODULE_NAME}EditPage.tsx in $PAGE_DIR"
        FAIL_C5=true
      fi
    fi
  done

  if [ "$FAIL_C5" = true ]; then
    echo ""
    echo "CRITICAL: Create/Edit pages are MISSING but ListPage buttons link to them."
    echo "Users will see white screen / 404 when clicking Create or Edit buttons."
    echo "Fix: Generate form pages using /ui-components skill patterns (smartstack-frontend.md section 3b)"
    FAIL=true
  fi
fi

# POST-CHECK C6: Form pages must have companion test files
PAGE_FILES=$(find src/pages/ -name "*.tsx" ! -name "*.test.tsx" 2>/dev/null || true)
if [ -n "$PAGE_FILES" ]; then
  ALL_TESTS=$(find src/pages/ -name "*.test.tsx" 2>/dev/null || true)
  if [ -z "$ALL_TESTS" ]; then
    echo "WARNING: No frontend test files found in src/pages/"
    echo "Every form page MUST have a companion .test.tsx file"
  fi
fi

FORM_PAGES=$(find src/pages/ -name "*CreatePage.tsx" -o -name "*EditPage.tsx" 2>/dev/null | grep -v test || true)
if [ -n "$FORM_PAGES" ]; then
  for FORM_PAGE in $FORM_PAGES; do
    TEST_FILE="${FORM_PAGE%.tsx}.test.tsx"
    if [ ! -f "$TEST_FILE" ]; then
      echo "WARNING: Form page missing test file: $FORM_PAGE"
      echo "Expected: $TEST_FILE"
      echo "All form pages MUST have companion test files (rendering, validation, submit, navigation)"
    fi
  done
fi

# POST-CHECK C7: FK fields must use EntityLookup — NO <input>, NO <select> (WARNING)
ALL_PAGES=$(find src/pages/ -name "*.tsx" 2>/dev/null | grep -v node_modules | grep -v "\.test\." || true)
if [ -n "$ALL_PAGES" ]; then
  FAIL_C7=false

  FK_INPUTS=$(grep -Pn '<input[^>]*(?:name|value)=["\x27{][^>]*[a-zA-Z]Id["\x27}]' $ALL_PAGES 2>/dev/null | grep -Pv 'type=["\x27]hidden["\x27]' || true)
  if [ -n "$FK_INPUTS" ]; then
    echo "WARNING: FK fields rendered as <input> — MUST use EntityLookup component"
    echo "$FK_INPUTS"
    FAIL_C7=true
  fi

  FK_SELECTS=$(grep -Pn '<select[^>]*value=\{[^}]*[a-zA-Z]Id\b' $ALL_PAGES 2>/dev/null || true)
  if [ -n "$FK_SELECTS" ]; then
    echo "WARNING: FK fields rendered as <select> dropdown — MUST use EntityLookup component"
    echo "A <select> loaded from API state is NOT a valid substitute for EntityLookup."
    echo "EntityLookup provides: debounced search, paginated results, display name resolution."
    echo "$FK_SELECTS"
    FAIL_C7=true
  fi

  FK_SELECT_ONCHANGE=$(grep -Pn 'onChange=.*[a-zA-Z]Id[^a-zA-Z].*e\.target\.value' $ALL_PAGES 2>/dev/null || true)
  if [ -n "$FK_SELECT_ONCHANGE" ]; then
    echo "WARNING: FK field set via e.target.value (select/input pattern) — use EntityLookup onChange(id)"
    echo "$FK_SELECT_ONCHANGE"
    FAIL_C7=true
  fi

  FK_PLACEHOLDER=$(grep -Pn 'placeholder=["\x27].*(?:[Ee]nter.*[Ii][Dd]|[Gg][Uu][Ii][Dd]|[Ss]elect.*[Ee]mployee|[Ss]elect.*[Dd]epartment|[Ss]elect.*[Pp]osition|[Ss]elect.*[Pp]roject|[Ss]elect.*[Cc]ategory)' $ALL_PAGES 2>/dev/null || true)
  if [ -n "$FK_PLACEHOLDER" ]; then
    echo "WARNING: Form has placeholder for FK field selection — use EntityLookup search instead"
    echo "$FK_PLACEHOLDER"
    FAIL_C7=true
  fi

  FK_OPTIONS=$(grep -Pn '<option[^>]*value=\{[^}]*\.id\}' $ALL_PAGES 2>/dev/null || true)
  if [ -n "$FK_OPTIONS" ]; then
    echo "WARNING: <option> with entity .id value detected — this is a FK <select> anti-pattern"
    echo "Replace the entire <select>/<option> block with <EntityLookup />"
    echo "$FK_OPTIONS"
    FAIL_C7=true
  fi

  if [ "$FAIL_C7" = true ]; then
    echo ""
    echo "Fix: Replace ALL FK fields with <EntityLookup /> from @/components/ui/EntityLookup"
    echo "See smartstack-frontend.md section 6 for the EntityLookup pattern"
    echo "FORBIDDEN for FK Guid fields: <input>, <select>, <option>, e.target.value"
    echo "REQUIRED: <EntityLookup apiEndpoint={...} mapOption={...} value={...} onChange={...} />"
  fi
fi

# POST-CHECK C9: No hardcoded Tailwind colors in generated pages (WARNING)
ALL_PAGES=$(find src/pages/ src/components/ -name "*.tsx" 2>/dev/null | grep -v node_modules | grep -v "\.test\." || true)
if [ -n "$ALL_PAGES" ]; then
  HARDCODED=$(grep -Pn '(bg|text|border)-(?!\[)(red|blue|green|gray|white|black|slate|zinc|neutral|stone)-' $ALL_PAGES 2>/dev/null || true)
  if [ -n "$HARDCODED" ]; then
    echo "WARNING: Pages MUST use CSS variables instead of hardcoded Tailwind colors"
    echo "SmartStack uses a theme system — hardcoded colors break dark mode and custom themes"
    echo ""
    echo "Fix mapping:"
    echo "  bg-white         → bg-[var(--bg-card)]"
    echo "  bg-gray-50       → bg-[var(--bg-primary)]"
    echo "  text-gray-900    → text-[var(--text-primary)]"
    echo "  text-gray-500    → text-[var(--text-secondary)]"
    echo "  border-gray-200  → border-[var(--border-color)]"
    echo "  bg-blue-600      → bg-[var(--color-accent-500)]"
    echo "  text-blue-600    → text-[var(--color-accent-500)]"
    echo "  text-red-500     → text-[var(--error-text)]"
    echo "  bg-green-500     → bg-[var(--success-bg)]"
    echo ""
    echo "See references/smartstack-frontend.md section 4 for full variable reference"
    echo ""
    echo "$HARDCODED"
  fi
fi

# POST-CHECK C11: Frontend routes must use kebab-case (BLOCKING)
APP_TSX=$(find src/ -name "App.tsx" -not -path "*/node_modules/*" 2>/dev/null | head -1)
if [ -n "$APP_TSX" ]; then
  FE_PATHS=$(grep -oP "path:\s*['\"]([^'\"]+)['\"]" "$APP_TSX" | grep -oP "['\"][^'\"]+['\"]" | tr -d "'" | tr -d '"')
  for FE_PATH in $FE_PATHS; do
    for SEG in $(echo "$FE_PATH" | tr '/' '\n'); do
      echo "$SEG" | grep -qP '^:' && continue
      if echo "$SEG" | grep -qP '^[a-z]{10,}$'; then
        SEED_MATCH=$(echo "$SEED_ROUTES" | tr '/' '\n' | grep -P "^[a-z]+-[a-z]+" | tr -d '-' | grep -x "$SEG" || true)
        if [ -n "$SEED_MATCH" ]; then
          echo "BLOCKING: Frontend route segment '$SEG' appears to be missing hyphens"
          echo "Seed data uses kebab-case (e.g., 'human-resources') but frontend has '$SEG'"
          echo "Fix: Use kebab-case in App.tsx route paths to match seed data exactly"
          FAIL=true
        fi
      fi
    done
  done
fi

# POST-CHECK C24: i18n must use separate JSON files per language (not embedded in index.ts)
TSX_FILES=$(find src/pages/ -name "*.tsx" 2>/dev/null | grep -v node_modules | grep -v "\.test\." || true)
if [ -n "$TSX_FILES" ]; then
  if [ ! -d "src/i18n/locales" ]; then
    echo "WARNING: Missing src/i18n/locales/ directory"
    echo "Translations must be in separate JSON files: src/i18n/locales/{fr,en,it,de}/{module}.json"
    echo "NEVER embed translations in src/i18n/index.ts or a single TypeScript file"
  fi

  I18N_INDEX=$(find src/i18n/ -maxdepth 1 -name "index.ts" -o -name "index.tsx" -o -name "config.ts" 2>/dev/null || true)
  if [ -n "$I18N_INDEX" ]; then
    EMBEDDED=$(grep -Pn '^\s*(resources|translations)\s*[:=]\s*\{' $I18N_INDEX 2>/dev/null || true)
    if [ -n "$EMBEDDED" ]; then
      echo "WARNING: Translations embedded in i18n config file — must be in separate JSON files"
      echo "Found embedded translations in:"
      echo "$EMBEDDED"
      echo ""
      echo "Fix: Move translations to src/i18n/locales/{fr,en,it,de}/{module}.json"
      echo "The i18n config should import from locales/ directory, not contain inline translations"
    fi
  fi

  for LANG in fr en it de; do
    if [ ! -d "src/i18n/locales/$LANG" ]; then
      echo "WARNING: Missing language directory: src/i18n/locales/$LANG/"
      echo "SmartStack requires 4 languages: fr, en, it, de"
    fi
  done

  for LANG in fr en it de; do
    JSON_COUNT=$(find "src/i18n/locales/$LANG" -name "*.json" 2>/dev/null | wc -l)
    if [ "$JSON_COUNT" -eq 0 ]; then
      echo "WARNING: No translation JSON files in src/i18n/locales/$LANG/"
      echo "Each module must have a {module}.json file per language"
    fi
  done
fi

# POST-CHECK C25: Pages must use useTranslation hook (no hardcoded user-facing strings)
PAGE_FILES=$(find src/pages/ -name "*.tsx" 2>/dev/null | grep -v node_modules | grep -v "\.test\." || true)
if [ -n "$PAGE_FILES" ]; then
  TOTAL_PAGES=$(echo "$PAGE_FILES" | wc -l)
  I18N_PAGES=$(grep -l "useTranslation" $PAGE_FILES 2>/dev/null | wc -l)
  if [ "$TOTAL_PAGES" -gt 0 ] && [ "$I18N_PAGES" -eq 0 ]; then
    echo "WARNING: No page files use useTranslation — all user-facing text must be translated"
    echo "Found $TOTAL_PAGES page files but 0 use useTranslation"
    echo ""
    echo "Fix: Import and use useTranslation in every page component:"
    echo "  const { t } = useTranslation(['{module}']);"
    echo "  t('{module}:title', 'Fallback text')"
  fi

  HARDCODED_TEXT=$(grep -Pn '>\s*(Create|Edit|Delete|Save|Cancel|Search|Loading|Error|No data|Not found|Submit|Back|Actions|Name|Status|Description)\s*<' $PAGE_FILES 2>/dev/null | grep -v '{t(' | head -10 || true)
  if [ -n "$HARDCODED_TEXT" ]; then
    echo "WARNING: Possible hardcoded user-facing strings detected in JSX"
    echo "All user-facing text MUST use t('namespace:key', 'Fallback')"
    echo "$HARDCODED_TEXT"
  fi
fi

# POST-CHECK C26: List/Detail pages must include DocToggleButton (documentation panel)
LIST_PAGES=$(find src/pages/ -name "*ListPage.tsx" -o -name "*sPage.tsx" 2>/dev/null | grep -v node_modules | grep -v "\.test\." || true)
if [ -n "$LIST_PAGES" ]; then
  MISSING_DOC=0
  for PAGE in $LIST_PAGES; do
    if ! grep -q "DocToggleButton" "$PAGE" 2>/dev/null; then
      echo "WARNING: Page missing DocToggleButton: $PAGE"
      echo "  Import: import { DocToggleButton } from '@/components/docs/DocToggleButton';"
      echo "  Place in header actions: <DocToggleButton />"
      MISSING_DOC=$((MISSING_DOC + 1))
    fi
  done
  if [ "$MISSING_DOC" -gt 0 ]; then
    echo ""
    echo "WARNING: $MISSING_DOC pages missing DocToggleButton — users cannot access inline documentation"
    echo "See smartstack-frontend.md section 7 for placement pattern"
  fi
fi

# POST-CHECK C27: Module documentation must be generated (doc-data.ts)
TSX_PAGES=$(find src/pages/ -name "*.tsx" -not -name "*.test.*" 2>/dev/null | grep -v node_modules | grep -v "docs/" || true)
DOC_DATA=$(find src/pages/docs/ -name "doc-data.ts" 2>/dev/null || true)
if [ -n "$TSX_PAGES" ] && [ -z "$DOC_DATA" ]; then
  echo "WARNING: Frontend pages exist but no documentation generated"
  echo "Fix: Invoke /documentation {module} --type user to generate doc-data.ts"
  echo "The DocToggleButton in page headers will link to this documentation"
fi

# POST-CHECK C36: Frontend navigate() calls must have matching route definitions (CRITICAL)
PAGE_FILES=$(find web/ -name "*.tsx" -path "*/pages/*" ! -name "*.test.tsx" 2>/dev/null || true)
if [ -n "$PAGE_FILES" ]; then
  NAV_TARGETS=$(grep -oP "navigate\(['\"]([^'\"]+)['\"]" $PAGE_FILES 2>/dev/null | grep -oP "['\"][^'\"]+['\"]" | tr -d "'" | tr -d '"' | sort -u || true)
  APP_FILES=$(find web/ -name "App.tsx" -o -name "routes.tsx" -o -name "applicationRoutes*.tsx" -o -name "clientRoutes*.tsx" -o -name "componentRegistry.generated.ts" 2>/dev/null || true)
  if [ -n "$APP_FILES" ] && [ -n "$NAV_TARGETS" ]; then
    ROUTE_PATHS=$(grep -oP "path:\s*['\"]([^'\"]+)['\"]" $APP_FILES 2>/dev/null | grep -oP "['\"][^'\"]+['\"]" | tr -d "'" | tr -d '"' | sort -u || true)
    for TARGET in $NAV_TARGETS; do
      if echo "$TARGET" | grep -qP '^(:|/api|http|-[0-9])'; then continue; fi
      LAST_SEG=$(echo "$TARGET" | grep -oP '[a-z][-a-z0-9]*$' || true)
      if [ -z "$LAST_SEG" ]; then continue; fi
      FOUND=$(echo "$ROUTE_PATHS" | grep -F "$LAST_SEG" 2>/dev/null || true)
      if [ -z "$FOUND" ]; then
        SEG_PASCAL=$(echo "$LAST_SEG" | sed -r 's/(^|-)([a-z])/\U\2/g')
        PAGE_EXISTS=$(find web/ -name "${SEG_PASCAL}Page.tsx" -o -name "${SEG_PASCAL}ListPage.tsx" -o -name "${SEG_PASCAL}sPage.tsx" 2>/dev/null || true)
        if [ -z "$PAGE_EXISTS" ]; then
          SOURCE_FILE=$(grep -rl "navigate(['\"].*${LAST_SEG}" $PAGE_FILES 2>/dev/null | head -1 || true)
          echo "CRITICAL: Dead link detected — navigate('$TARGET') in $SOURCE_FILE"
          echo "  Route segment '$LAST_SEG' has no matching route in App.tsx and no page component"
          echo "  Fix: Either create the page component + route, or remove the navigate() button"
          FAIL=true
        fi
      fi
    done
  fi
fi

# POST-CHECK C37: Detail page tabs must NOT navigate() — content switches locally (CRITICAL)
DETAIL_PAGES=$(find src/ web/ -name "*DetailPage.tsx" 2>/dev/null | grep -v node_modules | grep -v "\.test\." || true)
if [ -n "$DETAIL_PAGES" ]; then
  FAIL_C37=false
  for DP in $DETAIL_PAGES; do
    HAS_TABS=$(grep -P "useState.*activeTab|setActiveTab" "$DP" 2>/dev/null || true)
    if [ -z "$HAS_TABS" ]; then continue; fi

    TAB_NAVIGATE=$(grep -Pn "navigate\(" "$DP" 2>/dev/null | grep -v "navigate\(\s*['\"]edit['\"]" | grep -v "navigate\(\s*-1\s*\)" | grep -v "navigate\(\s*['\`].*/:id/edit" | grep -v "//" || true)
    if [ -n "$TAB_NAVIGATE" ]; then
      RELATIVE_NAV=$(echo "$TAB_NAVIGATE" | grep -P "navigate\(['\"\`]\.\./" 2>/dev/null || true)
      if [ -n "$RELATIVE_NAV" ]; then
        echo "CRITICAL: Detail page tabs use navigate() instead of local content switching: $DP"
        echo "  Tab click handlers MUST only call setActiveTab() — render content inline"
        echo "  Found navigate() calls (likely in tab handlers):"
        echo "$RELATIVE_NAV"
        echo ""
        echo "  Fix: Remove navigate() from tab handlers. Render sub-resource content inline:"
        echo "    {activeTab === 'leaves' && <LeaveRequestsTable employeeId={entity.id} />}"
        echo "  See smartstack-frontend.md section 3 'Tab Behavior Rules' for the correct pattern."
        FAIL_C37=true
      fi
    fi
  done
  if [ "$FAIL_C37" = true ]; then
    FAIL=true
  fi
fi

# POST-CHECK C49: Route Ordering in App.tsx — static before dynamic (BLOCKING)
APP_TSX=$(find web/ src/ -name "App.tsx" -not -path "*/node_modules/*" 2>/dev/null | head -1)
if [ -n "$APP_TSX" ]; then
  ROUTE_PATHS=$(grep -oP "path:\s*'([^']+)'" "$APP_TSX" | sed "s/path: '//;s/'//")
  FAIL_C49=false
  PREV_PREFIX=""
  PREV_IS_DYNAMIC=false

  while IFS= read -r ROUTE; do
    [ -z "$ROUTE" ] && continue
    PREFIX=$(echo "$ROUTE" | sed 's|/[^/]*$||')
    LAST_SEGMENT=$(echo "$ROUTE" | grep -oP '[^/]+$')
    IS_DYNAMIC=$(echo "$LAST_SEGMENT" | grep -c '^:')

    if [ "$PREV_IS_DYNAMIC" = true ] && [ "$IS_DYNAMIC" -eq 0 ] && [ "$PREFIX" = "$PREV_PREFIX" ]; then
      echo "BLOCKING: Static route '$ROUTE' is AFTER a dynamic route with prefix '$PREFIX' in App.tsx"
      echo "  React Router will match the dynamic route first → '$ROUTE' is unreachable (404)"
      echo "  Fix: Move static routes BEFORE dynamic routes within the same prefix group"
      FAIL_C49=true
    fi

    PREV_PREFIX="$PREFIX"
    if [ "$IS_DYNAMIC" -gt 0 ]; then
      PREV_IS_DYNAMIC=true
    else
      PREV_IS_DYNAMIC=false
    fi
  done <<< "$ROUTE_PATHS"

  if [ "$FAIL_C49" = true ]; then
    FAIL=true
  fi
fi

# POST-CHECK C52: Frontend route paths must include module segment (BLOCKING)
APP_TSX=$(find . -path "*/src/App.tsx" -not -path "*/node_modules/*" 2>/dev/null | head -1)
if [ -n "$APP_TSX" ]; then
  ROUTE_PATHS=$(grep -oP "path:\s*'[^']+'" "$APP_TSX" | grep -v "^path: ''" | grep -v ":id" | grep -v "create" | grep -v "edit" | sed "s/path: '//;s/'//")

  NAV_SEED_FILES=$(find src/ -name "*NavigationSeedData.cs" -o -name "*NavigationModuleSeedData.cs" 2>/dev/null)
  if [ -n "$NAV_SEED_FILES" ]; then
    MODULE_CODES=$(grep -oP 'Code\s*=\s*"\K[^"]+' $NAV_SEED_FILES 2>/dev/null | sort -u || true)

    for route in $ROUTE_PATHS; do
      if [ -z "$route" ]; then continue; fi

      if ! echo "$route" | grep -q "/"; then
        IS_MODULE=false
        for mod in $MODULE_CODES; do
          if [ "$route" = "$mod" ]; then IS_MODULE=true; break; fi
        done
        if [ "$IS_MODULE" = false ]; then
          echo "BLOCKING: Frontend route '$route' is missing module segment"
          echo "  Expected: '{module}/{route}' (e.g., 'employee-management/$route')"
          echo "  Backend navigation seed data defines routes with full hierarchy: /app/module/section"
          echo "  Frontend routes must match: module/section (relative to app root)"
          FAIL=true
        fi
      fi
    done
  fi
fi

if [ "$FAIL" = true ]; then
  exit 1
fi
