# ============================================================
#  frameworks.py — Détection, confirmation et init frameworks
#  rolax1212 v2.0 by Roland
# ============================================================

import os
import re
import sys
import subprocess
from pathlib import Path
from .ui import console, ok, info, warn, err, separateur, confirmer

# ============================================================
#  CATALOGUE DES FRAMEWORKS
# ============================================================
FRAMEWORKS = {
    # ── Python ──
    "django": {
        "nom":      "Django",
        "langage":  "Python",
        "version":  "5.x",
        "couleur":  "green",
        "icone":    "🟢",
        "detecteurs": [
            "manage.py", "django", "INSTALLED_APPS", "django.contrib"
        ],
        "install":  ["pip install django mysqlclient pillow python-decouple"],
        "verifier": ["python", "-m", "django", "--version"],
        "init_fn":  "init_django",
        "fichiers_natifs": [
            "manage.py", "settings.py", "wsgi.py", "asgi.py",
            "models.py", "views.py", "urls.py", "forms.py",
            "admin.py", "apps.py", "migrations"
        ],
        "docs": {
            "version_min": "4.2",
            "notes": [
                "Utilise path() et non url()",
                "Class-based views avec as_view()",
                "LoginRequiredMixin pour les CBV",
                "AUTH_USER_MODEL pour custom user",
                "django-environ pour les variables d'env",
                "python manage.py startapp pour créer une app",
            ]
        }
    },

    "fastapi": {
        "nom":      "FastAPI",
        "langage":  "Python",
        "version":  "0.110+",
        "couleur":  "cyan",
        "icone":    "⚡",
        "detecteurs": ["fastapi", "uvicorn", "APIRouter", "from fastapi"],
        "install":  ["pip install fastapi uvicorn sqlalchemy pydantic python-dotenv"],
        "verifier": None,
        "init_fn":  "init_fastapi",
        "fichiers_natifs": [],
        "docs": {
            "version_min": "0.100",
            "notes": [
                "Utilise Annotated pour les dépendances",
                "asyncio natif — préférer async def",
                "Pydantic v2 pour la validation",
                "APIRouter pour organiser les routes",
                "Depends() pour l'injection de dépendances",
            ]
        }
    },

    "flask": {
        "nom":      "Flask",
        "langage":  "Python",
        "version":  "3.x",
        "couleur":  "white",
        "icone":    "🌶",
        "detecteurs": ["flask", "from flask import", "Flask(__name__)", "app.route"],
        "install":  ["pip install flask flask-sqlalchemy flask-login python-dotenv"],
        "verifier": None,
        "init_fn":  "init_flask",
        "fichiers_natifs": [],
        "docs": {
            "version_min": "2.3",
            "notes": [
                "Application factory pattern recommandé",
                "Blueprints pour organiser les routes",
                "flask-login pour l'authentification",
                "flask-sqlalchemy pour la base de données",
                "flask db init/migrate/upgrade pour les migrations",
            ]
        }
    },

    "laravel": {
        "nom":      "Laravel",
        "langage":  "PHP",
        "version":  "11.x",
        "couleur":  "red",
        "icone":    "🔴",
        "detecteurs": ["artisan", "laravel", "Illuminate", "composer.json"],
        "install":  ["composer create-project laravel/laravel"],
        "verifier": ["php", "artisan", "--version"],
        "init_fn":  "init_laravel",
        "fichiers_natifs": [
            "artisan", "composer.json", "routes/web.php", "routes/api.php"
        ],
        "docs": {
            "version_min": "10.0",
            "notes": [
                "Structure slim — plus de app/Http/Kernel.php en v11",
                "php artisan make:model -mcr pour model+migration+controller",
                "Sanctum pour l'authentification API",
                "Eloquent ORM pour la base de données",
                "php artisan make:middleware pour les middlewares",
                "Blade pour les templates",
            ]
        }
    },

    "symfony": {
        "nom":      "Symfony",
        "langage":  "PHP",
        "version":  "7.x",
        "couleur":  "white",
        "icone":    "⚫",
        "detecteurs": ["symfony", "bin/console", "Symfony\\Component"],
        "install":  ["composer create-project symfony/skeleton"],
        "verifier": ["php", "bin/console", "--version"],
        "init_fn":  "init_symfony",
        "fichiers_natifs": ["bin/console", "config/", "src/"],
        "docs": {
            "version_min": "6.4",
            "notes": [
                "Doctrine ORM pour la base de données",
                "php bin/console make:entity pour les entités",
                "php bin/console make:controller pour les contrôleurs",
                "Security component pour l'authentification",
            ]
        }
    },

    "spring": {
        "nom":      "Spring Boot",
        "langage":  "Java",
        "version":  "3.x",
        "couleur":  "green",
        "icone":    "🍃",
        "detecteurs": ["pom.xml", "spring-boot", "@SpringBootApplication", "build.gradle"],
        "install":  ["spring init --dependencies=web,jpa,mysql,security"],
        "verifier": None,
        "init_fn":  "init_spring",
        "fichiers_natifs": ["pom.xml", "src/main/java", "src/main/resources"],
        "docs": {
            "version_min": "3.0",
            "notes": [
                "@SpringBootApplication sur la classe principale",
                "@RestController pour les API REST",
                "@Entity et @Repository pour JPA",
                "@Service pour la logique métier",
                "application.properties ou application.yml pour la config",
                "spring.jpa.hibernate.ddl-auto=update pour les migrations",
            ]
        }
    },

    "express": {
        "nom":      "Express.js",
        "langage":  "JavaScript",
        "version":  "4.x / 5.x",
        "couleur":  "yellow",
        "icone":    "🟡",
        "detecteurs": ["express", "app.listen", "router.get", "require('express')"],
        "install":  ["npm init -y", "npm install express dotenv cors helmet"],
        "verifier": None,
        "init_fn":  "init_express",
        "fichiers_natifs": [],
        "docs": {
            "version_min": "4.18",
            "notes": [
                "Router modulaire avec express.Router()",
                "Middleware : helmet, cors, morgan",
                "Prisma ou Sequelize pour la BDD",
                "JWT pour l'authentification",
                "express-validator pour la validation",
            ]
        }
    },

    "nestjs": {
        "nom":      "NestJS",
        "langage":  "TypeScript",
        "version":  "10.x",
        "couleur":  "red",
        "icone":    "🔺",
        "detecteurs": ["@nestjs", "NestFactory", "@Module", "@Controller", "@Injectable"],
        "install":  ["npm i -g @nestjs/cli", "nest new"],
        "verifier": ["nest", "--version"],
        "init_fn":  "init_nestjs",
        "fichiers_natifs": ["nest-cli.json", "src/app.module.ts", "src/main.ts"],
        "docs": {
            "version_min": "10.0",
            "notes": [
                "@Module, @Controller, @Injectable, @Service",
                "nest g module/controller/service pour générer",
                "TypeORM ou Prisma pour la BDD",
                "@nestjs/passport pour l'auth",
                "DTOs avec class-validator",
            ]
        }
    },

    "react": {
        "nom":      "React",
        "langage":  "JavaScript",
        "version":  "18.x",
        "couleur":  "cyan",
        "icone":    "⚛",
        "detecteurs": ["react", "ReactDOM", "useState", "useEffect", "jsx", "tsx"],
        "install":  ["npm create vite@latest . -- --template react"],
        "verifier": None,
        "init_fn":  "init_react",
        "fichiers_natifs": ["package.json", "vite.config.js", "src/App.jsx"],
        "docs": {
            "version_min": "18.0",
            "notes": [
                "Hooks uniquement — pas de class components",
                "useState, useEffect, useContext, useRef",
                "React Router v6 pour la navigation",
                "Vite comme bundler (plus rapide que CRA)",
                "Axios ou fetch pour les appels API",
                "Tailwind CSS ou MUI pour le style",
            ]
        }
    },

    "nextjs": {
        "nom":      "Next.js",
        "langage":  "TypeScript",
        "version":  "14.x / 15.x",
        "couleur":  "white",
        "icone":    "▲",
        "detecteurs": ["next", "next.config", "app/page", "pages/index"],
        "install":  ["npx create-next-app@latest"],
        "verifier": None,
        "init_fn":  "init_nextjs",
        "fichiers_natifs": ["next.config.js", "app/", "pages/"],
        "docs": {
            "version_min": "13.0",
            "notes": [
                "App Router (app/) recommandé sur Pages Router",
                "Server Components par défaut",
                "'use client' pour les composants interactifs",
                "Server Actions pour les formulaires",
                "next/image pour les images optimisées",
                "Middleware pour l'authentification",
            ]
        }
    },

    "vue": {
        "nom":      "Vue.js",
        "langage":  "JavaScript",
        "version":  "3.x",
        "couleur":  "green",
        "icone":    "💚",
        "detecteurs": ["vue", "createApp", "defineComponent", ".vue", "Composition API"],
        "install":  ["npm create vue@latest"],
        "verifier": None,
        "init_fn":  "init_vue",
        "fichiers_natifs": ["vite.config.js", "src/App.vue", "src/main.js"],
        "docs": {
            "version_min": "3.0",
            "notes": [
                "Composition API recommandée (pas Options API)",
                "script setup pour les composants",
                "Pinia pour le state management",
                "Vue Router 4 pour la navigation",
                "Vite comme bundler",
            ]
        }
    },

    "angular": {
        "nom":      "Angular",
        "langage":  "TypeScript",
        "version":  "17.x / 18.x",
        "couleur":  "red",
        "icone":    "🔴",
        "detecteurs": ["@angular", "NgModule", "Component", "angular.json"],
        "install":  ["npm i -g @angular/cli", "ng new"],
        "verifier": ["ng", "version"],
        "init_fn":  "init_angular",
        "fichiers_natifs": ["angular.json", "src/app/app.module.ts"],
        "docs": {
            "version_min": "17.0",
            "notes": [
                "Standalone components (plus de NgModule obligatoire)",
                "Signals pour la réactivité",
                "ng generate component/service/module",
                "HttpClient pour les appels API",
                "Angular Material pour l'UI",
            ]
        }
    },

    "react-native": {
        "nom":      "React Native / Expo",
        "langage":  "JavaScript",
        "version":  "0.73+",
        "couleur":  "cyan",
        "icone":    "📱",
        "detecteurs": ["react-native", "expo", "AppRegistry", "StyleSheet.create"],
        "install":  ["npx create-expo-app@latest"],
        "verifier": None,
        "init_fn":  "init_react_native",
        "fichiers_natifs": ["app.json", "App.js", "app/"],
        "docs": {
            "version_min": "0.72",
            "notes": [
                "Expo SDK recommandé pour démarrer",
                "React Navigation pour la navigation",
                "StyleSheet.create pour les styles",
                "AsyncStorage pour le stockage local",
                "Expo Router (file-based routing)",
            ]
        }
    },

    "flutter": {
        "nom":      "Flutter",
        "langage":  "Dart",
        "version":  "3.x",
        "couleur":  "cyan",
        "icone":    "💙",
        "detecteurs": ["flutter", "pubspec.yaml", "Widget", "StatelessWidget", "StatefulWidget"],
        "install":  ["flutter create"],
        "verifier": ["flutter", "--version"],
        "init_fn":  "init_flutter",
        "fichiers_natifs": ["pubspec.yaml", "lib/main.dart"],
        "docs": {
            "version_min": "3.0",
            "notes": [
                "StatelessWidget et StatefulWidget",
                "Provider ou Riverpod pour le state management",
                "Navigator 2.0 ou GoRouter pour la navigation",
                "dio pour les appels HTTP",
                "flutter pub add pour installer les packages",
            ]
        }
    },

    "aucun": {
        "nom":      "Langage libre",
        "langage":  "Tous",
        "version":  "",
        "couleur":  "white",
        "icone":    "📝",
        "detecteurs": [],
        "install":  [],
        "verifier": None,
        "init_fn":  None,
        "fichiers_natifs": [],
        "docs":     {}
    }
}

LISTE_FRAMEWORKS = list(FRAMEWORKS.keys())


# ============================================================
#  DETECTION AUTOMATIQUE
# ============================================================
def detecter_framework(path, fichiers):
    """
    Détecte le framework depuis les fichiers du projet.
    Requiert des fichiers signatures spécifiques — pas juste du texte.
    """
    noms_fichiers = list(fichiers.keys())
    contenu_total = " ".join(fichiers.values())
    noms_str      = " ".join(noms_fichiers).lower()

    # Fichiers signatures — présence d'un fichier = preuve forte
    signatures = {
        "django":       ["manage.py"],
        "laravel":      ["artisan", "composer.json"],
        "symfony":      ["bin/console", "symfony.lock"],
        "spring":       ["pom.xml", "build.gradle"],
        "nestjs":       ["nest-cli.json"],
        "angular":      ["angular.json"],
        "flutter":      ["pubspec.yaml"],
        "react-native": ["app.json", "expo.json"],
    }

    for cle, fichiers_sig in signatures.items():
        for sig in fichiers_sig:
            if any(sig.lower() in n.lower() for n in noms_fichiers):
                return cle

    # Détection par contenu — score minimum de 3 pour éviter les faux positifs
    scores = {}
    for cle, fw in FRAMEWORKS.items():
        if cle in ["aucun"] + list(signatures.keys()):
            continue
        # Cherche dans les noms de fichiers ET le contenu
        score_noms     = sum(2 for d in fw["detecteurs"] if d.lower() in noms_str)
        score_contenu  = sum(1 for d in fw["detecteurs"] if d.lower() in contenu_total.lower())
        score_total    = score_noms + score_contenu
        if score_total >= 3:
            scores[cle] = score_total

    if not scores:
        return None

    return max(scores, key=scores.get)


def confirmer_framework(framework_detecte):
    """Affiche le framework détecté et demande confirmation."""
    if not framework_detecte:
        return None

    fw = FRAMEWORKS[framework_detecte]
    console.print()
    console.print(
        f"[bold cyan][>>] Framework détecté :[/bold cyan] "
        f"{fw['icone']} [bold {fw['couleur']}]{fw['nom']} {fw['version']}[/bold {fw['couleur']}]"
    )

    if confirmer("C'est correct ?", defaut=True):
        ok(f"Mode [bold]{fw['nom']}[/bold] activé")
        _afficher_docs(framework_detecte)
        return framework_detecte
    else:
        return choisir_framework()





def choisir_framework():
    """Affiche la liste des frameworks et demande le choix."""
    console.print("\n[bold cyan]Frameworks disponibles :[/bold cyan]\n")

    items = [(k, v) for k, v in FRAMEWORKS.items()]
    for i, (cle, fw) in enumerate(items, 1):
        tag = f"[{fw['couleur']}]{fw['icone']} {fw['nom']}[/{fw['couleur']}]"
        lang = f"[dim]{fw['langage']}[/dim]" if fw['langage'] != "Tous" else "[dim]Tous langages[/dim]"
        console.print(f"  [bold]{i:2}.[/bold] {tag}  {lang}")

    console.print()
    choix = console.input("[cyan]Choisis un framework (numéro) : [/cyan]").strip()

    try:
        idx = int(choix) - 1
        if 0 <= idx < len(items):
            cle = items[idx][0]
            fw  = FRAMEWORKS[cle]
            ok(f"Mode [bold]{fw['nom']}[/bold] activé")
            _afficher_docs(cle)
            return cle
    except ValueError:
        pass

    warn("Choix invalide — mode langage libre activé")
    return "aucun"


def _afficher_docs(cle):
    """Affiche les notes de documentation du framework."""
    fw   = FRAMEWORKS.get(cle, {})
    docs = fw.get("docs", {})
    notes = docs.get("notes", [])
    if not notes:
        return
    console.print(f"\n[dim]Notes {fw['nom']} v{fw.get('version','')} :[/dim]")
    for n in notes:
        console.print(f"  [dim]•[/dim] [dim]{n}[/dim]")
    console.print()


# ============================================================
#  INITIALISATION DES FRAMEWORKS
# ============================================================
def init_framework(cle, path_projet):
    """Point d'entrée pour initialiser un projet."""
    fw      = FRAMEWORKS.get(cle)
    init_fn = fw.get("init_fn") if fw else None

    if not init_fn:
        warn("Pas d'initialisation automatique pour ce framework.")
        return False

    fns = {
        "init_django":       init_django,
        "init_fastapi":      init_fastapi,
        "init_flask":        init_flask,
        "init_laravel":      init_laravel,
        "init_express":      init_express,
        "init_nestjs":       init_nestjs,
        "init_react":        init_react,
        "init_nextjs":       init_nextjs,
        "init_vue":          init_vue,
        "init_angular":      init_angular,
        "init_react_native": init_react_native,
        "init_flutter":      init_flutter,
        "init_spring":       init_spring,
        "init_symfony":      init_symfony,
    }

    fn = fns.get(init_fn)
    if fn:
        return fn(path_projet)

    warn(f"Initialisation {fw['nom']} non encore implémentée.")
    return False


def _run(cmd, cwd, label):
    """Exécute une commande shell et affiche le résultat."""
    info(f"{label}...")
    try:
        r = subprocess.run(
            cmd, cwd=str(cwd), shell=isinstance(cmd, str),
            capture_output=True, text=True, timeout=120
        )
        if r.returncode == 0:
            ok(label)
            return True
        else:
            err(f"{label} — {r.stderr.strip()[:200]}")
            return False
    except FileNotFoundError:
        err(f"Commande introuvable : {cmd[0] if isinstance(cmd, list) else cmd}")
        return False
    except subprocess.TimeoutExpired:
        err(f"Timeout — {label}")
        return False


def _verifier_outil(commande, nom, install_hint):
    """Vérifie qu'un outil est installé."""
    try:
        subprocess.run([commande, "--version"], capture_output=True, timeout=5)
        return True
    except FileNotFoundError:
        err(f"{nom} non trouvé.")
        warn(f"Installe-le d'abord : {install_hint}")
        return False


# ── DJANGO ──────────────────────────────────────────────────
def init_django(path):
    path = Path(path)

    nom_projet = console.input("[cyan]Nom du projet Django [le_restaurant] : [/cyan]").strip() or "le_restaurant"
    apps_raw   = console.input("[cyan]Apps à créer (séparées par virgule) [restaurant] : [/cyan]").strip() or "restaurant"
    apps       = [a.strip() for a in apps_raw.split(",") if a.strip()]

    info("Vérification de Django...")
    try:
        subprocess.run(["python", "-m", "django", "--version"], capture_output=True, check=True)
    except Exception:
        info("Django non installé — installation...")
        _run("pip install django mysqlclient pillow python-decouple", path, "pip install django")

    # Crée le projet
    _run(["django-admin", "startproject", nom_projet, "."], path, f"django-admin startproject {nom_projet}")

    # Crée les apps
    for app in apps:
        _run(["python", "manage.py", "startapp", app], path, f"python manage.py startapp {app}")

    # Crée les dossiers standards
    for dossier in ["templates", "static/css", "static/js", "static/img", "media"]:
        (path / dossier).mkdir(parents=True, exist_ok=True)
        ok(f"Dossier créé : {dossier}/")

    # .gitignore Django
    _creer_gitignore(path, "django")

    # requirements.txt
    (path / "requirements.txt").write_text(
        "Django>=4.2\nmysqlclient>=2.2\nPillow>=10.0\npython-decouple>=3.8\n"
    )
    ok("requirements.txt créé")

    console.print(f"\n[bold green]Projet Django '{nom_projet}' initialisé ![/bold green]")
    console.print("[dim]Prochaines étapes :[/dim]")
    console.print("  [cyan]1.[/cyan] Configurer settings.py (MySQL, INSTALLED_APPS, templates)")
    console.print("  [cyan]2.[/cyan] python manage.py makemigrations")
    console.print("  [cyan]3.[/cyan] python manage.py migrate")
    console.print("  [cyan]4.[/cyan] python manage.py createsuperuser")
    return True


# ── FASTAPI ──────────────────────────────────────────────────
def init_fastapi(path):
    path = Path(path)
    _run("pip install fastapi uvicorn sqlalchemy pydantic python-dotenv alembic", path, "pip install fastapi")

    for d in ["app/routers", "app/models", "app/schemas", "app/services"]:
        (path / d).mkdir(parents=True, exist_ok=True)

    (path / "app/__init__.py").write_text("")
    (path / "app/main.py").write_text(
        'from fastapi import FastAPI\n\napp = FastAPI(title="Mon API")\n\n@app.get("/")\ndef root():\n    return {"message": "Hello"}\n'
    )
    (path / "requirements.txt").write_text("fastapi>=0.110\nuvicorn>=0.27\nsqlalchemy>=2.0\npydantic>=2.0\npython-dotenv\nalembic\n")
    _creer_gitignore(path, "python")

    ok("Projet FastAPI initialisé !")
    console.print("  [cyan]Lance avec :[/cyan] uvicorn app.main:app --reload")
    return True


# ── FLASK ────────────────────────────────────────────────────
def init_flask(path):
    path = Path(path)
    _run("pip install flask flask-sqlalchemy flask-login flask-migrate python-dotenv", path, "pip install flask")

    for d in ["app/templates", "app/static/css", "app/static/js", "app/models", "app/routes"]:
        (path / d).mkdir(parents=True, exist_ok=True)

    (path / "app/__init__.py").write_text(
        'from flask import Flask\nfrom flask_sqlalchemy import SQLAlchemy\n\ndb = SQLAlchemy()\n\ndef create_app():\n    app = Flask(__name__)\n    db.init_app(app)\n    return app\n'
    )
    (path / "run.py").write_text('from app import create_app\napp = create_app()\nif __name__ == "__main__":\n    app.run(debug=True)\n')
    (path / "requirements.txt").write_text("Flask>=3.0\nflask-sqlalchemy>=3.1\nflask-login>=0.6\nflask-migrate>=4.0\npython-dotenv\n")
    _creer_gitignore(path, "python")

    ok("Projet Flask initialisé !")
    console.print("  [cyan]Lance avec :[/cyan] python run.py")
    return True


# ── LARAVEL ──────────────────────────────────────────────────
def init_laravel(path):
    path = Path(path)
    if not _verifier_outil("composer", "Composer", "https://getcomposer.org"):
        return False
    if not _verifier_outil("php", "PHP", "https://www.php.net"):
        return False

    nom = console.input("[cyan]Nom du projet Laravel : [/cyan]").strip() or "mon-laravel"
    dest = path / nom
    _run(["composer", "create-project", "laravel/laravel", str(dest)], path, f"composer create-project laravel/laravel {nom}")

    ok(f"Projet Laravel '{nom}' initialisé !")
    console.print(f"  [cyan]Lance avec :[/cyan] cd {nom} && php artisan serve")
    return True


# ── EXPRESS ──────────────────────────────────────────────────
def init_express(path):
    path = Path(path)
    _run(["npm", "init", "-y"], path, "npm init")
    _run(["npm", "install", "express", "dotenv", "cors", "helmet", "morgan"], path, "npm install express")

    for d in ["src/routes", "src/controllers", "src/models", "src/middleware"]:
        (path / d).mkdir(parents=True, exist_ok=True)

    (path / "src/app.js").write_text(
        "const express = require('express');\nconst cors = require('cors');\nconst helmet = require('helmet');\n\nconst app = express();\napp.use(express.json());\napp.use(cors());\napp.use(helmet());\n\napp.get('/', (req, res) => res.json({ message: 'API OK' }));\n\nmodule.exports = app;\n"
    )
    (path / "src/server.js").write_text(
        "const app = require('./app');\nconst PORT = process.env.PORT || 3000;\napp.listen(PORT, () => console.log(`Server running on port ${PORT}`));\n"
    )
    _creer_gitignore(path, "node")

    ok("Projet Express.js initialisé !")
    console.print("  [cyan]Lance avec :[/cyan] node src/server.js")
    return True


# ── NESTJS ───────────────────────────────────────────────────
def init_nestjs(path):
    path = Path(path)
    nom  = console.input("[cyan]Nom du projet NestJS : [/cyan]").strip() or "mon-nest"
    if not _verifier_outil("nest", "NestJS CLI", "npm i -g @nestjs/cli"):
        _run(["npm", "install", "-g", "@nestjs/cli"], path, "npm install @nestjs/cli")
    _run(["nest", "new", nom, "--skip-git"], path, f"nest new {nom}")
    ok(f"Projet NestJS '{nom}' initialisé !")
    return True


# ── REACT ────────────────────────────────────────────────────
def init_react(path):
    path = Path(path)
    _run(["npm", "create", "vite@latest", ".", "--", "--template", "react"], path, "create vite react")
    _run(["npm", "install"], path, "npm install")
    _creer_gitignore(path, "node")
    ok("Projet React (Vite) initialisé !")
    console.print("  [cyan]Lance avec :[/cyan] npm run dev")
    return True


# ── NEXTJS ───────────────────────────────────────────────────
def init_nextjs(path):
    path = Path(path)
    nom  = console.input("[cyan]Nom du projet Next.js : [/cyan]").strip() or "mon-next"
    _run(["npx", "create-next-app@latest", nom], path, f"create-next-app {nom}")
    ok(f"Projet Next.js '{nom}' initialisé !")
    return True


# ── VUE ──────────────────────────────────────────────────────
def init_vue(path):
    path = Path(path)
    _run(["npm", "create", "vue@latest", "."], path, "create vue")
    _run(["npm", "install"], path, "npm install")
    ok("Projet Vue.js initialisé !")
    console.print("  [cyan]Lance avec :[/cyan] npm run dev")
    return True


# ── ANGULAR ──────────────────────────────────────────────────
def init_angular(path):
    path = Path(path)
    nom  = console.input("[cyan]Nom du projet Angular : [/cyan]").strip() or "mon-angular"
    if not _verifier_outil("ng", "Angular CLI", "npm i -g @angular/cli"):
        _run(["npm", "install", "-g", "@angular/cli"], path, "npm install @angular/cli")
    _run(["ng", "new", nom], path, f"ng new {nom}")
    ok(f"Projet Angular '{nom}' initialisé !")
    return True


# ── REACT NATIVE ─────────────────────────────────────────────
def init_react_native(path):
    path = Path(path)
    nom  = console.input("[cyan]Nom de l'app React Native : [/cyan]").strip() or "MonApp"
    _run(["npx", "create-expo-app@latest", nom], path, f"create-expo-app {nom}")
    ok(f"App React Native '{nom}' initialisée !")
    console.print("  [cyan]Lance avec :[/cyan] cd " + nom + " && npx expo start")
    return True


# ── FLUTTER ──────────────────────────────────────────────────
def init_flutter(path):
    path = Path(path)
    nom  = console.input("[cyan]Nom de l'app Flutter : [/cyan]").strip() or "mon_app"
    if not _verifier_outil("flutter", "Flutter", "https://flutter.dev"):
        return False
    _run(["flutter", "create", nom], path, f"flutter create {nom}")
    ok(f"App Flutter '{nom}' initialisée !")
    console.print("  [cyan]Lance avec :[/cyan] cd " + nom + " && flutter run")
    return True


# ── SPRING BOOT ──────────────────────────────────────────────
def init_spring(path):
    path = Path(path)
    warn("Spring Boot nécessite Spring Initializr.")
    console.print("  Génère ton projet sur : [cyan]https://start.spring.io[/cyan]")
    console.print("  Puis extrais-le ici et tape : [cyan]mvn spring-boot:run[/cyan]")
    return True


# ── SYMFONY ──────────────────────────────────────────────────
def init_symfony(path):
    path = Path(path)
    if not _verifier_outil("composer", "Composer", "https://getcomposer.org"):
        return False
    nom = console.input("[cyan]Nom du projet Symfony : [/cyan]").strip() or "mon-symfony"
    _run(["composer", "create-project", "symfony/skeleton", nom], path, f"composer create-project symfony/skeleton {nom}")
    ok(f"Projet Symfony '{nom}' initialisé !")
    return True


# ============================================================
#  GITIGNORE
# ============================================================
def _creer_gitignore(path, type_projet):
    contenu = {
        "django": "*.pyc\n__pycache__/\n*.env\n.env\nvenv/\n.venv/\ndb.sqlite3\nmedia/\nstaticfiles/\n",
        "python": "*.pyc\n__pycache__/\n*.env\n.env\nvenv/\n.venv/\n",
        "node":   "node_modules/\n.env\ndist/\nbuild/\n.next/\n",
    }
    c = contenu.get(type_projet, "*.env\n.env\n")
    (path / ".gitignore").write_text(c)
    ok(".gitignore créé")


# ============================================================
#  PROMPT SYSTEME ADAPTE AU FRAMEWORK
# ============================================================
def prompt_framework(cle):
    """Retourne les instructions spécifiques au framework pour le LLM."""
    fw = FRAMEWORKS.get(cle)
    if not fw or cle == "aucun":
        return ""

    docs   = fw.get("docs", {})
    notes  = docs.get("notes", [])
    natifs = fw.get("fichiers_natifs", [])

    prompt = f"\n\nFRAMEWORK DÉTECTÉ : {fw['nom']} {fw['version']}\n"
    prompt += f"LANGAGE : {fw['langage']}\n"

    if notes:
        prompt += "\nRÈGLES SPÉCIFIQUES AU FRAMEWORK (OBLIGATOIRES) :\n"
        for n in notes:
            prompt += f"- {n}\n"

    if natifs:
        prompt += f"\nFICHIERS GÉNÉRÉS PAR LE FRAMEWORK (ne pas recréer manuellement) :\n"
        for f in natifs:
            prompt += f"- {f}\n"
        prompt += "Ces fichiers existent déjà. Modifie-les seulement si demandé.\n"

    return prompt
