#!/bin/bash

# Vibes CLI - Making development flow

set -e

# Get the absolute path to the project root
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
PROJECT_ROOT="$( cd "$SCRIPT_DIR/.." && pwd )"

# Detect package manager from .vibesrc or default to pnpm
if [ -f "$PROJECT_ROOT/.vibesrc" ]; then
    PACKAGE_MANAGER=$(node -e "console.log(JSON.parse(require('fs').readFileSync('$PROJECT_ROOT/.vibesrc', 'utf8')).packageManager)")
else
    PACKAGE_MANAGER="pnpm"
fi

# Package manager commands
if [ "$PACKAGE_MANAGER" = "npm" ]; then
    PM_INSTALL="npm install"
    PM_ADD="npm install"
    PM_ADD_DEV="npm install --save-dev"
    PM_CREATE="npm create"
    PM_RUN="npm run"
    PM_EXEC="npx"
elif [ "$PACKAGE_MANAGER" = "yarn" ]; then
    PM_INSTALL="yarn install"
    PM_ADD="yarn add"
    PM_ADD_DEV="yarn add --dev"
    PM_CREATE="yarn create"
    PM_RUN="yarn"
    PM_EXEC="yarn"
else
    # Default to pnpm
    PM_INSTALL="pnpm install"
    PM_ADD="pnpm add"
    PM_ADD_DEV="pnpm add --save-dev"
    PM_CREATE="pnpm create"
    PM_RUN="pnpm"
    PM_EXEC="pnpm"
fi

# Colors
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
PURPLE='\033[0;35m'
RED='\033[0;31m'
NC='\033[0m'

# Functions
show_help() {
    echo -e "${PURPLE}🌊 Vibes CLI${NC}"
    echo
    echo "Usage: vibe <command> [options]"
    echo
    echo "Package Manager: $PACKAGE_MANAGER"
    echo
    echo "Commands:"
    echo "  create <feature>  Create a new feature"
    echo "  add <app>        Add a new app"
    echo "  dev              Start development"
    echo "  build            Build everything"
    echo "  test             Run tests"
    echo "  check            Vibe check (linting + types)"
    echo "  clean            Clean all build artifacts"
    echo "  doctor           Check your environment"
    echo "  init             Initialize AI context"
    echo "  help             Show this help"
    echo
    echo "Examples:"
    echo "  vibe create user-auth"
    echo "  vibe add mobile"
    echo "  vibe dev"
}

create_feature() {
    cd "$PROJECT_ROOT"

    # Check if TypeScript CLI is available
    if [ -f "tools/vibe-cli.js" ] && [ -d "node_modules/@sprouted/create-vibes" ]; then
        # Use TypeScript CLI
        node tools/vibe-cli.js create "$@"
    elif [ -z "$1" ]; then
        echo "❌ Please provide a feature name"
        echo "Usage: vibe create <feature-name>"
        exit 1
    elif [ -f "tools/create-feature.sh" ]; then
        # Fallback to bash implementation
        ./tools/create-feature.sh "$1"
    else
        echo -e "${RED}❌ create-feature.sh not found${NC}"
        exit 1
    fi
}

add_app() {
    cd "$PROJECT_ROOT"

    # Check if TypeScript CLI is available
    if [ -f "tools/vibe-cli.js" ] && [ -d "node_modules/@sprouted/create-vibes" ]; then
        # Use TypeScript CLI
        node tools/vibe-cli.js add "$@"
        return
    fi

    # Fallback to bash implementation
    if [ -z "$1" ]; then
        echo -e "${YELLOW}What type of app?${NC}"
        echo "1) Web (React/Next.js)"
        echo "2) Mobile (Expo)"
        echo "3) API (Go)"
        echo "4) Desktop (Electron)"
        read -p "Select (1-4): " choice

        case $choice in
            1) APP_TYPE="web" ;;
            2) APP_TYPE="mobile" ;;
            3) APP_TYPE="api" ;;
            4) APP_TYPE="desktop" ;;
            *) echo "Invalid choice"; exit 1 ;;
        esac
    else
        APP_TYPE=$1
    fi

    echo -e "${BLUE}🌊 Creating $APP_TYPE app...${NC}"
    
    # App name
    echo -e "${YELLOW}App name?${NC}"
    read -p "Name (e.g., admin, customer): " APP_NAME
    
    APP_DIR="apps/$APP_NAME"
    
    if [ -d "$APP_DIR" ]; then
        echo "❌ App already exists!"
        exit 1
    fi
    
    mkdir -p "$APP_DIR"
    
    case $APP_TYPE in
        web)
            echo -e "${GREEN}Creating Vite web app...${NC}"
            cd "$APP_DIR"
            $PM_CREATE vite@latest . -- --template react-ts
            
            # Ask about expo-router
            echo -e "${YELLOW}Would you like to add a router?${NC}"
            read -p "Add react-router-dom? (y/n): " ADD_ROUTER
            
            if [ "$ADD_ROUTER" = "y" ] || [ "$ADD_ROUTER" = "Y" ]; then
                $PM_ADD react-router-dom
                echo -e "${GREEN}✅ Added react-router-dom${NC}"
            fi
            
            # Generate .gitignore
            cat > .gitignore << 'EOF'
# Dependencies
node_modules/

# Build output
dist/
build/

# Environment
.env
.env.local
.env.*.local

# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Editor
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.idea/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Testing
coverage/
.nyc_output/

# Temporary
*.tmp
*.temp
EOF
            ;;
            
        mobile)
            echo -e "${GREEN}Creating Expo app...${NC}"
            cd "$APP_DIR"
            # Use the predefined $PM_CREATE variable for consistency
            $PM_CREATE expo-app . --template blank-typescript
            
            # Ask about expo-router
            echo -e "${YELLOW}Would you like to add Expo Router for navigation?${NC}"
            read -p "Add expo-router? (y/n): " ADD_ROUTER
            
            if [ "$ADD_ROUTER" = "y" ] || [ "$ADD_ROUTER" = "Y" ]; then
                $PM_EXEC expo install expo-router
                
                # Create basic file structure for expo-router
                mkdir -p app
                
                # Create _layout.tsx
                cat > app/_layout.tsx << 'EOF'
import { Stack } from 'expo-router';

export default function Layout() {
  return (
    <Stack>
      <Stack.Screen name="index" options={{ title: 'Home' }} />
    </Stack>
  );
}
EOF

                # Create index.tsx
                cat > app/index.tsx << 'EOF'
import { View, Text, StyleSheet } from 'react-native';

export default function Home() {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>Welcome to Vibes!</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
  },
});
EOF

                # Update package.json to use expo-router
                npm pkg set "main"="expo-router/entry"
                
                echo -e "${GREEN}✅ Added expo-router${NC}"
            fi
            
            # Ask about nativewind
            echo -e "${YELLOW}Would you like to add NativeWind for Tailwind-style styling?${NC}"
            read -p "Add nativewind? (y/n): " ADD_NATIVEWIND
            
            if [ "$ADD_NATIVEWIND" = "y" ] || [ "$ADD_NATIVEWIND" = "Y" ]; then
                $PM_ADD nativewind
                $PM_ADD_DEV tailwindcss@3.3.0
                
                # Create tailwind.config.js
                cat > tailwind.config.js << 'EOF'
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./app/**/*.{js,jsx,ts,tsx}", "./src/**/*.{js,jsx,ts,tsx}"],
  presets: [require("nativewind/preset")],
  theme: {
    extend: {},
  },
  plugins: [],
};
EOF

                # Create global.css
                mkdir -p src
                cat > src/global.css << 'EOF'
@tailwind base;
@tailwind components;
@tailwind utilities;
EOF

                # Create nativewind.d.ts
                cat > nativewind.d.ts << 'EOF'
/// <reference types="nativewind/types" />
EOF

                # Update metro.config.js
                cat > metro.config.js << 'EOF'
const { getDefaultConfig } = require('expo/metro-config');
const { withNativeWind } = require('nativewind/metro');

const config = getDefaultConfig(__dirname);

module.exports = withNativeWind(config, { input: './src/global.css' });
EOF

                echo -e "${GREEN}✅ Added NativeWind${NC}"
            fi
            
            # Generate .gitignore
            cat > .gitignore << 'EOF'
# Dependencies
node_modules/
.expo/

# Build output
dist/
build/
*.ipa
*.apk
*.aab

# Environment
.env
.env.local
.env.*.local

# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Expo
.expo-shared/
*.jks
*.p8
*.p12
*.key
*.mobileprovision
*.orig.*
web-build/

# Editor
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.idea/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Testing
coverage/
.nyc_output/

# Temporary
*.tmp
*.temp
EOF
            ;;
            
        api)
            echo -e "${GREEN}Creating Go API...${NC}"
            cd "$APP_DIR"
            go mod init "vibes/$APP_NAME"
            
            # Basic main.go with Gin
            cat > main.go << 'EOF'
package main

import (
    "log"
    "net/http"
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    
    r.GET("/health", func(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "status": "healthy",
            "name": "vibes-api",
        })
    })
    
    // Feature routes will be added here
    // Example: features.RegisterRoutes(r)
    
    port := ":8080"
    log.Printf("Server starting on %s", port)
    if err := r.Run(port); err != nil {
        log.Fatal("Failed to start server:", err)
    }
}
EOF
            
            # Install dependencies
            go get github.com/gin-gonic/gin
            
            # Create basic structure
            mkdir -p {cmd,internal,pkg,api}
            
            # Generate .gitignore
            cat > .gitignore << 'EOF'
# Binaries
*.exe
*.dll
*.so
*.dylib

# Go specific
go.sum
vendor/
.idea/
.vscode/
*.log

# Build output
bin/
dist/
build/

# Environment
.env
.env.local
.env.*.local

# OS
.DS_Store
Thumbs.db

# Testing
*.test
*.out
coverage.txt
coverage.html
EOF
            ;;
            
        desktop)
            echo -e "${GREEN}Creating Electron app...${NC}"
            cd "$APP_DIR"
            # Use direct init command for each package manager
            if [ "$PACKAGE_MANAGER" = "npm" ]; then
                npm init -y
            elif [ "$PACKAGE_MANAGER" = "yarn" ]; then
                yarn init -y
            else
                pnpm init
            fi
            $PM_ADD_DEV electron
            $PM_ADD_DEV electron-builder
            
            # Basic electron setup
            cat > main.js << 'EOF'
const { app, BrowserWindow } = require('electron');
const path = require('path');

function createWindow() {
  const win = new BrowserWindow({
    width: 1200,
    height: 800,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false
    }
  });

  win.loadFile('index.html');
}

app.whenReady().then(createWindow);

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow();
  }
});
EOF

            # Basic HTML
            cat > index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Vibes Desktop</title>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            margin: 0;
            padding: 20px;
            background: #f5f5f5;
        }
        .container {
            max-width: 800px;
            margin: 0 auto;
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        h1 {
            color: #333;
            margin-top: 0;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>🌊 Welcome to Vibes Desktop</h1>
        <p>Start building your Electron app here!</p>
    </div>
</body>
</html>
EOF

            # Update package.json
            npm pkg set "main"="main.js"
            npm pkg set "scripts.start"="electron ."
            npm pkg set "scripts.build"="electron-builder"
            
            # Generate .gitignore
            cat > .gitignore << 'EOF'
# Dependencies
node_modules/

# Build output
dist/
build/
out/

# Environment
.env
.env.local
.env.*.local

# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Electron
*.asar

# Editor
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.idea/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Testing
coverage/
.nyc_output/

# Temporary
*.tmp
*.temp
EOF
            ;;
    esac
    
    echo -e "${GREEN}✅ Created $APP_TYPE app: $APP_NAME${NC}"
    echo
    echo "Next steps:"
    echo "  cd $APP_DIR"

    # Different instructions based on app type
    case $APP_TYPE in
        api)
            echo "  go mod tidy"
            echo "  go run ."
            ;;
        *)
            echo "  $PM_INSTALL"
            echo "  $PM_RUN dev"
            ;;
    esac
}

start_dev() {
    cd "$PROJECT_ROOT"
    echo -e "${BLUE}🌊 Starting development environment...${NC}"
    $PM_RUN dev
}

build_all() {
    cd "$PROJECT_ROOT"
    echo -e "${BLUE}🌊 Building everything...${NC}"
    $PM_RUN build
}

run_tests() {
    cd "$PROJECT_ROOT"
    echo -e "${BLUE}🌊 Running tests...${NC}"
    $PM_RUN test
}

vibe_check() {
    cd "$PROJECT_ROOT"
    echo -e "${BLUE}🌊 Checking the vibe...${NC}"
    $PM_RUN lint && $PM_RUN typecheck
}

clean_all() {
    cd "$PROJECT_ROOT"
    echo -e "${BLUE}🌊 Cleaning build artifacts...${NC}"
    
    # Remove common build directories
    find . -name "dist" -type d -exec rm -rf {} + 2>/dev/null || true
    find . -name "build" -type d -exec rm -rf {} + 2>/dev/null || true
    find . -name ".turbo" -type d -exec rm -rf {} + 2>/dev/null || true
    find . -name ".next" -type d -exec rm -rf {} + 2>/dev/null || true
    find . -name "coverage" -type d -exec rm -rf {} + 2>/dev/null || true
    
    echo -e "${GREEN}✅ Cleaned!${NC}"
}

doctor() {
    echo -e "${BLUE}🌊 Vibes Doctor${NC}"
    echo
    echo "Checking your environment..."
    echo
    echo -e "${PURPLE}Package Manager:${NC} $PACKAGE_MANAGER"
    echo
    
    # Check Node.js
    if command -v node &> /dev/null; then
        echo -e "${GREEN}✓${NC} Node.js: $(node --version)"
    else
        echo -e "${RED}✗${NC} Node.js: not found"
    fi
    
    # Check package managers
    if command -v pnpm &> /dev/null; then
        echo -e "${GREEN}✓${NC} pnpm: $(pnpm --version)"
    else
        echo -e "${YELLOW}⚠${NC} pnpm: not found (recommended)"
    fi
    
    if command -v npm &> /dev/null; then
        echo -e "${GREEN}✓${NC} npm: $(npm --version)"
    else
        echo -e "${RED}✗${NC} npm: not found"
    fi
    
    # Check Go
    if command -v go &> /dev/null; then
        echo -e "${GREEN}✓${NC} Go: $(go version | cut -d' ' -f3)"
    else
        echo -e "${YELLOW}⚠${NC} Go: not found (needed for API apps)"
    fi
    
    # Check Git
    if command -v git &> /dev/null; then
        echo -e "${GREEN}✓${NC} Git: $(git --version | cut -d' ' -f3)"
    else
        echo -e "${RED}✗${NC} Git: not found"
    fi
    
    # Check project structure
    echo
    echo "Project structure:"
    if [ -f "$PROJECT_ROOT/package.json" ]; then
        echo -e "${GREEN}✓${NC} package.json found"
    else
        echo -e "${RED}✗${NC} package.json not found"
    fi
    
    if [ -d "$PROJECT_ROOT/features" ]; then
        echo -e "${GREEN}✓${NC} features/ directory found"
    else
        echo -e "${YELLOW}⚠${NC} features/ directory not found"
    fi
    
    if [ -d "$PROJECT_ROOT/apps" ]; then
        echo -e "${GREEN}✓${NC} apps/ directory found"
    else
        echo -e "${YELLOW}⚠${NC} apps/ directory not found"
    fi
    
    if [ -f "$PROJECT_ROOT/CLAUDE.md" ]; then
        echo -e "${GREEN}✓${NC} CLAUDE.md found"
    else
        echo -e "${YELLOW}⚠${NC} CLAUDE.md not found"
    fi
    
    echo
    echo -e "${GREEN}Diagnosis complete!${NC}"
}

init_ai() {
    if [ -f "$PROJECT_ROOT/init.sh" ]; then
        "$PROJECT_ROOT/init.sh"
    else
        echo -e "${YELLOW}Creating AI context...${NC}"
        echo
        echo "Project: $(basename "$PROJECT_ROOT")"
        echo "Type: Vibes Monorepo"
        echo "Architecture: Vertical Slice"
        echo
        echo "Key files:"
        echo "- CLAUDE.md"
        echo "- ai-docs/navigation.md"
        echo "- ai-docs/patterns.md"
        echo
        echo -e "${GREEN}✅ AI context initialized${NC}"
    fi
}

# Main command handler
case "$1" in
    create)
        create_feature "$2"
        ;;
    add)
        add_app "$2"
        ;;
    dev)
        start_dev
        ;;
    build)
        build_all
        ;;
    test)
        run_tests
        ;;
    check)
        vibe_check
        ;;
    clean)
        clean_all
        ;;
    doctor)
        doctor
        ;;
    init)
        init_ai
        ;;
    help|--help|-h|"")
        show_help
        ;;
    *)
        echo -e "${RED}Unknown command: $1${NC}"
        echo
        show_help
        exit 1
        ;;
esac