#!/bin/bash

# 🎯 GÉNÉRATEUR DE FEATURE - VEZA
# Script pour générer une nouvelle feature complète

set -e

# Couleurs
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m'

# Fonction pour afficher les messages
log_info() {
    echo -e "${BLUE}ℹ️  $1${NC}"
}

log_success() {
    echo -e "${GREEN}✅ $1${NC}"
}

log_warning() {
    echo -e "${YELLOW}⚠️  $1${NC}"
}

# Vérification des arguments
if [ $# -eq 0 ]; then
    echo "Usage: $0 <feature-name>"
    echo "Exemple: $0 user-authentication"
    exit 1
fi

FEATURE_NAME=$1
FEATURE_DIR="features/feature-$(date +%Y%m%d)-${FEATURE_NAME}"

log_info "Génération de la feature: $FEATURE_NAME"

# Création de la structure de la feature
mkdir -p "$FEATURE_DIR"/{backend,frontend,mobile,tests,docs}

log_success "Structure de répertoires créée"

# Génération du backend (Go)
log_info "Génération du code backend..."

cat > "$FEATURE_DIR/backend/${FEATURE_NAME}_service.go" << 'GOEOF'
package main

import (
    "context"
    "fmt"
    "time"
)

// ${FEATURE_NAME^}Service gère les fonctionnalités de ${FEATURE_NAME}
type ${FEATURE_NAME^}Service struct {
    // Ajoutez vos dépendances ici
}

// New${FEATURE_NAME^}Service crée une nouvelle instance du service
func New${FEATURE_NAME^}Service() *${FEATURE_NAME^}Service {
    return &${FEATURE_NAME^}Service{}
}

// Exemple de méthode - remplacez par vos méthodes
func (s *${FEATURE_NAME^}Service) Process${FEATURE_NAME^}(ctx context.Context, input string) (string, error) {
    // Implémentation de votre logique métier
    return fmt.Sprintf("Processed: %s", input), nil
}

// Health check pour le service
func (s *${FEATURE_NAME^}Service) HealthCheck() error {
    // Implémentation du health check
    return nil
}
GOEOF

cat > "$FEATURE_DIR/backend/${FEATURE_NAME}_handler.go" << 'GOEOF'
package main

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

// ${FEATURE_NAME^}Handler gère les endpoints HTTP pour ${FEATURE_NAME}
type ${FEATURE_NAME^}Handler struct {
    service *${FEATURE_NAME^}Service
}

// New${FEATURE_NAME^}Handler crée un nouveau handler
func New${FEATURE_NAME^}Handler(service *${FEATURE_NAME^}Service) *${FEATURE_NAME^}Handler {
    return &${FEATURE_NAME^}Handler{
        service: service,
    }
}

// SetupRoutes configure les routes pour cette feature
func (h *${FEATURE_NAME^}Handler) SetupRoutes(r *gin.RouterGroup) {
    r.GET("/${FEATURE_NAME}", h.Get${FEATURE_NAME^})
    r.POST("/${FEATURE_NAME}", h.Create${FEATURE_NAME^})
    r.PUT("/${FEATURE_NAME}/:id", h.Update${FEATURE_NAME^})
    r.DELETE("/${FEATURE_NAME}/:id", h.Delete${FEATURE_NAME^})
}

// Get${FEATURE_NAME^} récupère les données de ${FEATURE_NAME}
func (h *${FEATURE_NAME^}Handler) Get${FEATURE_NAME^}(c *gin.Context) {
    // Implémentation
    c.JSON(http.StatusOK, gin.H{"message": "Get ${FEATURE_NAME} endpoint"})
}

// Create${FEATURE_NAME^} crée une nouvelle entrée
func (h *${FEATURE_NAME^}Handler) Create${FEATURE_NAME^}(c *gin.Context) {
    // Implémentation
    c.JSON(http.StatusCreated, gin.H{"message": "Create ${FEATURE_NAME} endpoint"})
}

// Update${FEATURE_NAME^} met à jour une entrée existante
func (h *${FEATURE_NAME^}Handler) Update${FEATURE_NAME^}(c *gin.Context) {
    // Implémentation
    c.JSON(http.StatusOK, gin.H{"message": "Update ${FEATURE_NAME} endpoint"})
}

// Delete${FEATURE_NAME^} supprime une entrée
func (h *${FEATURE_NAME^}Handler) Delete${FEATURE_NAME^}(c *gin.Context) {
    // Implémentation
    c.JSON(http.StatusOK, gin.H{"message": "Delete ${FEATURE_NAME} endpoint"})
}
GOEOF

log_success "Code backend généré"

# Génération du frontend (React)
log_info "Génération du code frontend..."

cat > "$FEATURE_DIR/frontend/${FEATURE_NAME^}Page.tsx" << 'REACTEOF'
import React, { useState, useEffect } from 'react';
import { Card, Button, Input, Modal } from '../components/DesignSystem';

interface ${FEATURE_NAME^}Data {
  id: string;
  name: string;
  // Ajoutez vos propriétés ici
}

const ${FEATURE_NAME^}Page: React.FC = () => {
  const [data, setData] = useState<${FEATURE_NAME^}Data[]>([]);
  const [loading, setLoading] = useState(false);
  const [isModalOpen, setIsModalOpen] = useState(false);

  useEffect(() => {
    fetch${FEATURE_NAME^}Data();
  }, []);

  const fetch${FEATURE_NAME^}Data = async () => {
    setLoading(true);
    try {
      // Implémentation de la récupération des données
      const response = await fetch('/api/${FEATURE_NAME}');
      const result = await response.json();
      setData(result);
    } catch (error) {
      console.error('Erreur lors de la récupération des données:', error);
    } finally {
      setLoading(false);
    }
  };

  const handleCreate = async (formData: any) => {
    try {
      // Implémentation de la création
      const response = await fetch('/api/${FEATURE_NAME}', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(formData),
      });
      
      if (response.ok) {
        fetch${FEATURE_NAME^}Data();
        setIsModalOpen(false);
      }
    } catch (error) {
      console.error('Erreur lors de la création:', error);
    }
  };

  return (
    <div className="p-6">
      <div className="flex justify-between items-center mb-6">
        <h1 className="text-3xl font-bold text-white">${FEATURE_NAME^}</h1>
        <Button onClick={() => setIsModalOpen(true)}>
          Créer ${FEATURE_NAME^}
        </Button>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
        {data.map((item) => (
          <Card key={item.id} className="p-4">
            <h3 className="text-lg font-semibold text-white">{item.name}</h3>
            {/* Ajoutez vos éléments d'affichage ici */}
          </Card>
        ))}
      </div>

      <Modal
        isOpen={isModalOpen}
        onClose={() => setIsModalOpen(false)}
        title="Créer ${FEATURE_NAME^}"
      >
        {/* Ajoutez votre formulaire ici */}
        <form onSubmit={(e) => {
          e.preventDefault();
          // Implémentation de la soumission
        }}>
          <Input
            type="text"
            placeholder="Nom"
            required
          />
          <Button type="submit" className="mt-4">
            Créer
          </Button>
        </form>
      </Modal>
    </div>
  );
};

export default ${FEATURE_NAME^}Page;
REACTEOF

log_success "Code frontend généré"

# Génération des tests
log_info "Génération des tests..."

cat > "$FEATURE_DIR/tests/${FEATURE_NAME}_test.go" << 'TESTEOF'
package main

import (
    "testing"
    "context"
    "github.com/stretchr/testify/assert"
)

func Test${FEATURE_NAME^}Service(t *testing.T) {
    service := New${FEATURE_NAME^}Service()
    
    t.Run("should process ${FEATURE_NAME} successfully", func(t *testing.T) {
        ctx := context.Background()
        input := "test input"
        
        result, err := service.Process${FEATURE_NAME^}(ctx, input)
        
        assert.NoError(t, err)
        assert.Contains(t, result, input)
    })
    
    t.Run("should pass health check", func(t *testing.T) {
        err := service.HealthCheck()
        assert.NoError(t, err)
    })
}
TESTEOF

cat > "$FEATURE_DIR/tests/${FEATURE_NAME}_integration_test.go" << 'INTEGEOF'
package main

import (
    "testing"
    "net/http"
    "net/http/httptest"
    "github.com/gin-gonic/gin"
    "github.com/stretchr/testify/assert"
)

func Test${FEATURE_NAME^}Endpoints(t *testing.T) {
    gin.SetMode(gin.TestMode)
    
    service := New${FEATURE_NAME^}Service()
    handler := New${FEATURE_NAME^}Handler(service)
    
    router := gin.New()
    handler.SetupRoutes(router.Group("/api"))
    
    t.Run("GET /api/${FEATURE_NAME}", func(t *testing.T) {
        w := httptest.NewRecorder()
        req, _ := http.NewRequest("GET", "/api/${FEATURE_NAME}", nil)
        router.ServeHTTP(w, req)
        
        assert.Equal(t, http.StatusOK, w.Code)
    })
    
    t.Run("POST /api/${FEATURE_NAME}", func(t *testing.T) {
        w := httptest.NewRecorder()
        req, _ := http.NewRequest("POST", "/api/${FEATURE_NAME}", nil)
        router.ServeHTTP(w, req)
        
        assert.Equal(t, http.StatusCreated, w.Code)
    })
}
INTEGEOF

log_success "Tests générés"

# Génération de la documentation
log_info "Génération de la documentation..."

cat > "$FEATURE_DIR/docs/README.md" << 'DOCEOF'
# ${FEATURE_NAME^} Feature

## Description
Cette feature implémente la fonctionnalité de ${FEATURE_NAME}.

## Composants

### Backend
- `${FEATURE_NAME}_service.go` - Service principal
- `${FEATURE_NAME}_handler.go` - Handlers HTTP

### Frontend
- `${FEATURE_NAME^}Page.tsx` - Page React

### Tests
- `${FEATURE_NAME}_test.go` - Tests unitaires
- `${FEATURE_NAME}_integration_test.go` - Tests d'intégration

## API Endpoints

### GET /api/${FEATURE_NAME}
Récupère la liste des ${FEATURE_NAME}.

### POST /api/${FEATURE_NAME}
Crée une nouvelle entrée ${FEATURE_NAME}.

### PUT /api/${FEATURE_NAME}/:id
Met à jour une entrée ${FEATURE_NAME} existante.

### DELETE /api/${FEATURE_NAME}/:id
Supprime une entrée ${FEATURE_NAME}.

## Utilisation

1. Implémentez la logique métier dans le service
2. Ajoutez les validations nécessaires
3. Implémentez les tests
4. Intégrez dans l'application principale

## Tests

```bash
# Tests unitaires
go test ./features/feature-$(date +%Y%m%d)-${FEATURE_NAME}/tests/

# Tests d'intégration
go test -tags=integration ./features/feature-$(date +%Y%m%d)-${FEATURE_NAME}/tests/
```
DOCEOF

log_success "Documentation générée"

# Génération du fichier de configuration
cat > "$FEATURE_DIR/feature-config.yaml" << 'CONFIGEOF'
feature:
  name: ${FEATURE_NAME}
  version: 1.0.0
  description: "Feature ${FEATURE_NAME} implementation"
  
components:
  backend:
    service: true
    handler: true
    repository: false
    middleware: false
    
  frontend:
    page: true
    component: false
    hook: false
    
  mobile:
    screen: false
    component: false
    
  tests:
    unit: true
    integration: true
    e2e: false
    
  docs:
    readme: true
    api: true
    user_guide: false

dependencies:
  backend:
    - gin
    - context
  frontend:
    - react
    - typescript
  mobile:
    - react-native
    - expo
CONFIGEOF

log_success "Configuration générée"

# Résumé
echo -e "${GREEN}"
echo "╔══════════════════════════════════════════════════════════════╗"
echo "║                    FEATURE GÉNÉRÉE AVEC SUCCÈS             ║"
echo "╚══════════════════════════════════════════════════════════════╝"
echo -e "${NC}"

echo -e "${BLUE}📁 Feature créée dans: $FEATURE_DIR${NC}"
echo -e "${BLUE}📋 Prochaines étapes:${NC}"
echo "1. Implémentez la logique métier dans les services"
echo "2. Ajoutez les validations et la gestion d'erreurs"
echo "3. Implémentez les tests"
echo "4. Intégrez dans l'application principale"
echo "5. Mettez à jour la documentation"

log_success "Feature $FEATURE_NAME générée avec succès!"
