#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Script de sauvegarde des données du site GMPL.
Permet d'exporter les données de la base de données vers un fichier JSON
pour faciliter les migrations et les modifications de structure.
"""

import json
import os
from datetime import datetime
from app import create_app
from models import User, Product, Category, Service, Contact, FAQ, SiteSetting, Page, Section

# Créer l'application avec le contexte
app = create_app()

def backup_data(output_file=None):
    """Sauvegarde toutes les données des modèles principaux dans un fichier JSON"""
    
    # Nom du fichier par défaut avec la date et l'heure
    if not output_file:
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        output_file = f"backup_{timestamp}.json"
    
    with app.app_context():
        # Sauvegarde des utilisateurs
        users = User.query.all()
        users_data = [{
            "username": u.username,
            "email": u.email,
            "role": u.role,
            "created_at": u.created_at.isoformat() if u.created_at else None
        } for u in users]
        
        # Sauvegarde des catégories
        categories = Category.query.all()
        categories_data = [{
            "id": c.id,
            "name": c.name,
            "description": c.description,
            "parent_id": c.parent_id
        } for c in categories]
        
        # Sauvegarde des produits
        products = Product.query.all()
        products_data = [{
            "name": p.name,
            "description": p.description,
            "price": p.price,
            "image_url": p.image_url,
            "category_id": p.category_id,
            "is_available": p.is_available,
            "condition": p.condition,
            "created_at": p.created_at.isoformat() if p.created_at else None,
            "updated_at": p.updated_at.isoformat() if p.updated_at else None
        } for p in products]
        
        # Sauvegarde des services
        services = Service.query.all()
        services_data = [{
            "name": s.name,
            "description": s.description,
            "image_url": s.image_url,
            "is_active": s.is_active,
            "created_at": s.created_at.isoformat() if s.created_at else None,
            "updated_at": s.updated_at.isoformat() if s.updated_at else None
        } for s in services]
        
        # Sauvegarde des contacts
        contacts = Contact.query.all()
        contacts_data = [{
            "name": c.name,
            "email": c.email,
            "phone": c.phone,
            "message": c.message,
            "created_at": c.created_at.isoformat() if c.created_at else None,
            "is_read": c.is_read
        } for c in contacts]
        
        # Sauvegarde des FAQs
        faqs = FAQ.query.all()
        faqs_data = [{
            "question": f.question,
            "answer": f.answer,
            "order": f.order,
            "is_active": f.is_active,
            "created_at": f.created_at.isoformat() if f.created_at else None,
            "updated_at": f.updated_at.isoformat() if f.updated_at else None
        } for f in faqs]
        
        # Sauvegarde des paramètres du site
        settings = SiteSetting.query.all()
        settings_data = [{
            "key": s.key,
            "value": s.value,
            "description": s.description
        } for s in settings]
        
        # Sauvegarde des pages
        pages = Page.query.all()
        pages_data = [{
            "id": p.id,
            "title": p.title,
            "slug": p.slug,
            "description": p.description,
            "is_active": p.is_active,
            "meta_keywords": p.meta_keywords,
            "meta_description": p.meta_description,
            "created_at": p.created_at.isoformat() if p.created_at else None,
            "updated_at": p.updated_at.isoformat() if p.updated_at else None
        } for p in pages]
        
        # Sauvegarde des sections
        sections = Section.query.all()
        sections_data = [{
            "page_id": s.page_id,
            "title": s.title,
            "content": s.content,
            "section_type": s.section_type,
            "order": s.order,
            "is_active": s.is_active,
            "background_color": s.background_color,
            "css_class": s.css_class,
            "image_url": s.image_url,
            "created_at": s.created_at.isoformat() if s.created_at else None,
            "updated_at": s.updated_at.isoformat() if s.updated_at else None
        } for s in sections]
        
        # Création du dictionnaire de sauvegarde
        backup = {
            "metadata": {
                "version": "1.0",
                "generated_at": datetime.now().isoformat(),
                "description": "Sauvegarde des données du site GMPL"
            },
            "users": users_data,
            "categories": categories_data,
            "products": products_data,
            "services": services_data,
            "contacts": contacts_data,
            "faqs": faqs_data,
            "settings": settings_data,
            "pages": pages_data,
            "sections": sections_data
        }
        
        # Création du dossier de sauvegarde s'il n'existe pas
        backup_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'backups')
        if not os.path.exists(backup_dir):
            os.makedirs(backup_dir)
        
        # Chemin complet du fichier de sauvegarde
        backup_path = os.path.join(backup_dir, output_file)
        
        # Sauvegarde dans un fichier JSON
        with open(backup_path, 'w', encoding='utf-8') as f:
            json.dump(backup, f, indent=4, ensure_ascii=False)
        
        print(f"Sauvegarde terminée avec succès dans le fichier '{backup_path}'.")
        return backup_path

def restore_data(input_file):
    """Restaure les données à partir d'un fichier JSON de sauvegarde"""
    from werkzeug.security import generate_password_hash
    
    if not os.path.exists(input_file):
        print(f"Erreur : Le fichier '{input_file}' n'existe pas.")
        return False
    
    # Charger les données de sauvegarde
    with open(input_file, 'r', encoding='utf-8') as f:
        backup = json.load(f)
    
    with app.app_context():
        # Restauration des utilisateurs avec gestion des mots de passe
        for user_data in backup['users']:
            existing_user = User.query.filter_by(username=user_data['username']).first()
            if existing_user:
                print(f"L'utilisateur '{user_data['username']}' existe déjà. Mise à jour...")
                existing_user.email = user_data['email']
                existing_user.role = user_data['role']
            else:
                print(f"Création de l'utilisateur '{user_data['username']}'...")
                # Mot de passe temporaire pour les utilisateurs restaurés
                temp_password = "gmpl2023"
                user = User(
                    username=user_data['username'],
                    email=user_data['email'],
                    password_hash=generate_password_hash(temp_password),
                    role=user_data['role']
                )
                # Ajout à la session mais sans commit immédiat
                app.db.session.add(user)
        
        # Validation des changements pour les utilisateurs
        app.db.session.commit()
        print("Restauration des utilisateurs terminée.")
        
        # Ajouter ici le code pour restaurer les autres modèles si nécessaire
        
        print("Restauration des données terminée avec succès.")
        return True

if __name__ == "__main__":
    print("Script de sauvegarde des données du site GMPL")
    print("-------------------------------------------")
    
    # Demander à l'utilisateur ce qu'il souhaite faire
    print("Que souhaitez-vous faire ?")
    print("1. Sauvegarder les données")
    print("2. Restaurer les données")
    
    choice = input("Votre choix (1 ou 2) : ")
    
    if choice == "1":
        # Sauvegarde des données
        output_file = input("Nom du fichier de sauvegarde (laisser vide pour un nom automatique) : ")
        if not output_file:
            backup_file = backup_data()
        else:
            backup_file = backup_data(output_file)
        print(f"Données sauvegardées dans '{backup_file}'.")
    
    elif choice == "2":
        # Restauration des données
        input_file = input("Chemin vers le fichier de sauvegarde : ")
        if input_file:
            print("ATTENTION : La restauration des données peut écraser des données existantes.")
            confirm = input("Êtes-vous sûr de vouloir continuer ? (oui/non) : ")
            if confirm.lower() in ["oui", "o", "yes", "y"]:
                restore_data(input_file)
            else:
                print("Restauration annulée.")
        else:
            print("Aucun fichier spécifié. Restauration annulée.")
    
    else:
        print("Choix non valide. Opération annulée.")