"""Génère les données du TP (ventes, clients, texte) dans le dossier data/.

Les données sont fictives et déterministes (graine fixe) : tous les étudiants
obtiennent exactement les mêmes fichiers, donc les mêmes résultats.
"""
import csv
import os
import random
from datetime import date, timedelta

TEXTE = """Apache Spark est un moteur de calcul distribué.
Spark permet de traiter de grandes quantités de données sur plusieurs machines.
Avec Spark, les données sont découpées en partitions.
Chaque partition est traitée en parallèle par un executor.
Le driver coordonne le travail et distribue les tâches aux executors.
Les données restent en mémoire, ce qui rend Spark rapide.
Un RDD est une collection distribuée et immuable de données.
Un DataFrame est une table distribuée avec des colonnes nommées.
Les transformations décrivent un calcul, les actions déclenchent le calcul.
Spark est paresseux : rien ne se passe avant une action.
On peut interroger les données avec Python ou avec SQL.
Le langage Python est très utilisé pour analyser des données.
PySpark est la bibliothèque Python pour utiliser Spark.
Les données de ventes permettent de mesurer le chiffre d'affaires.
Les données des clients permettent de mieux comprendre les ventes.
Analyser les données aide une entreprise à prendre de meilleures décisions.
Une petite boutique a peu de données, une grande plateforme en a énormément.
Quand les données ne tiennent plus sur une machine, Spark devient utile.
Spark fonctionne aussi très bien sur un simple ordinateur portable.
Bravo : vous savez maintenant compter les mots avec Spark !
"""

CATALOGUE = {
    "Informatique": [("Clavier", 29.90), ("Souris", 19.90), ("Écran", 179.00), ("Casque", 59.50), ("Clé USB", 12.00)],
    "Maison": [("Lampe", 24.99), ("Cafetière", 49.90), ("Coussin", 15.00)],
    "Mobilier": [("Chaise", 89.00), ("Bureau", 199.00), ("Étagère", 65.00)],
    "Livres": [("Roman", 18.50), ("BD", 14.90), ("Livre de cuisine", 25.00)],
    "Sport": [("Ballon", 22.00), ("Tapis de yoga", 30.00), ("Gourde", 11.50)],
}
VILLES = ["Paris", "Lyon", "Marseille", "Toulouse", "Lille", "Bordeaux", "Nantes", "Strasbourg"]
PRENOMS = ["Camille", "Léa", "Louis", "Hugo", "Emma", "Nina", "Adam", "Inès", "Lucas", "Sarah",
           "Yanis", "Chloé", "Nathan", "Jade", "Rayan", "Manon", "Noah", "Lina", "Tom", "Zoé"]
PAIEMENTS = ["Carte", "Carte", "Carte", "PayPal", "PayPal", "Virement"]
# Plus de ventes en fin d'année (soldes, Noël)
POIDS_MOIS = [8, 6, 7, 7, 8, 8, 6, 5, 8, 9, 13, 15]


def generer(dossier="data", nb_ventes=5000, nb_clients=500):
    rng = random.Random(42)
    os.makedirs(dossier, exist_ok=True)

    with open(os.path.join(dossier, "texte.txt"), "w", encoding="utf-8") as f:
        f.write(TEXTE)

    with open(os.path.join(dossier, "clients.csv"), "w", newline="", encoding="utf-8") as f:
        w = csv.writer(f)
        w.writerow(["id_client", "prenom", "age", "ville", "date_inscription"])
        for i in range(1, nb_clients + 1):
            inscription = date(2022, 1, 1) + timedelta(days=rng.randint(0, 1400))
            w.writerow([i, rng.choice(PRENOMS), rng.randint(18, 75), rng.choice(VILLES), inscription.isoformat()])

    lignes = []
    for i in range(1, nb_ventes + 1):
        mois = rng.choices(range(1, 13), weights=POIDS_MOIS)[0]
        jour = rng.randint(1, 28)
        categorie = rng.choice(list(CATALOGUE))
        produit, prix = rng.choice(CATALOGUE[categorie])
        quantite = rng.choices([1, 2, 3, 4, 5], weights=[50, 25, 12, 8, 5])[0]
        # ~1 % de ventes passées par des clients absents du fichier clients (pour les jointures)
        id_client = rng.randint(501, 510) if rng.random() < 0.01 else rng.randint(1, nb_clients)
        paiement = rng.choice(PAIEMENTS)
        # Quelques valeurs manquantes, pour l'exercice de nettoyage
        if rng.random() < 0.02:
            quantite = ""
        if rng.random() < 0.01:
            paiement = ""
        lignes.append([i, date(2025, mois, jour).isoformat(), id_client, produit, categorie, quantite, prix, paiement])
    # Quelques doublons exacts, comme dans la vraie vie
    lignes += [list(l) for l in rng.sample(lignes, 25)]
    rng.shuffle(lignes)

    with open(os.path.join(dossier, "ventes.csv"), "w", newline="", encoding="utf-8") as f:
        w = csv.writer(f)
        w.writerow(["id_vente", "date_vente", "id_client", "produit", "categorie", "quantite", "prix_unitaire", "mode_paiement"])
        w.writerows(lignes)


if __name__ == "__main__":
    generer()
    print("Données générées dans data/")
