import { Feature } from './types';
import fs from 'fs-extra';
import path from 'path';

export const expoRouterFeature: Feature = {
  id: 'expo-router',
  name: 'Expo Router',
  description: 'File-based routing for React Native apps',
  dependencies: ['expo-router'],
  files: [
    {
      source: 'templates/features/expo-router/app/_layout.tsx',
      destination: 'app/_layout.tsx'
    },
    {
      source: 'templates/features/expo-router/app/index.tsx',
      destination: 'app/index.tsx'
    }
  ],
  postInstall: async (context) => {
    // Update package.json main field
    const packageJsonPath = path.join(context.projectPath, 'package.json');
    const packageJson = await fs.readJson(packageJsonPath);
    packageJson.main = 'expo-router/entry';
    await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
  }
};

export const nativewindFeature: Feature = {
  id: 'nativewind',
  name: 'NativeWind',
  description: 'Tailwind CSS for React Native',
  dependencies: ['nativewind'],
  devDependencies: ['tailwindcss@3.3.0'],
  files: [
    {
      source: 'templates/features/nativewind/tailwind.config.js',
      destination: 'tailwind.config.js'
    },
    {
      source: 'templates/features/nativewind/src/global.css',
      destination: 'src/global.css'
    },
    {
      source: 'templates/features/nativewind/nativewind.d.ts',
      destination: 'nativewind.d.ts'
    },
    {
      source: 'templates/features/nativewind/metro.config.js',
      destination: 'metro.config.js'
    }
  ]
};

export const reactRouterFeature: Feature = {
  id: 'react-router',
  name: 'React Router',
  description: 'Routing for React web applications',
  dependencies: ['react-router-dom'],
  files: [
    {
      source: 'templates/features/react-router/src/App.tsx',
      destination: 'src/App.tsx',
      condition: (vars) => vars.uiFramework === 'react'
    }
  ]
};

export const tailwindCssFeature: Feature = {
  id: 'tailwindcss',
  name: 'Tailwind CSS',
  description: 'Utility-first CSS framework',
  devDependencies: ['tailwindcss', 'postcss', 'autoprefixer'],
  files: [
    {
      source: 'templates/features/tailwindcss/tailwind.config.js',
      destination: 'tailwind.config.js'
    },
    {
      source: 'templates/features/tailwindcss/postcss.config.js',
      destination: 'postcss.config.js'
    },
    {
      source: 'templates/features/tailwindcss/src/index.css',
      destination: 'src/index.css'
    }
  ],
  postInstall: async (context) => {
    console.log('Run "npx tailwindcss init -p" to complete setup');
  }
};

export const goFiberFeature: Feature = {
  id: 'go-fiber',
  name: 'Fiber Framework',
  description: 'Express-inspired web framework for Go',
  dependencies: ['github.com/gofiber/fiber/v2'],
  files: [
    {
      source: 'templates/features/go-fiber/main.go',
      destination: 'main.go',
      condition: (vars) => vars.appType === 'api' && vars.language === 'go'
    }
  ]
};

// Registry of all available features
export const allFeatures: Feature[] = [
  expoRouterFeature,
  nativewindFeature,
  reactRouterFeature,
  tailwindCssFeature,
  goFiberFeature
];

// Helper function to get feature by ID
export function getFeature(id: string): Feature | undefined {
  return allFeatures.find(feature => feature.id === id);
}

// Helper function to resolve feature dependencies
export function resolveFeatureDependencies(featureIds: string[]): string[] {
  const resolved = new Set<string>();
  const visited = new Set<string>();
  
  function resolve(id: string) {
    if (visited.has(id)) return;
    visited.add(id);
    
    const feature = getFeature(id);
    if (!feature) return;
    
    // Add dependencies first (if any)
    // Note: This is a simplified version - real implementation would handle
    // circular dependencies and feature dependencies
    
    resolved.add(id);
  }
  
  featureIds.forEach(resolve);
  
  return Array.from(resolved);
}