import json
import os
import pickle
import numpy as np
from lightfm import LightFM
from lightfm.data import Dataset

INPUT_FILE = "reviews_cleaned_final.json"
MODEL_FILE = "recommender_model.pkl"

def train_final():
    print("--- TRAINING RECOMMENDER (LIGHTFM) SU DATI REALI ---")
    
    if not os.path.exists(INPUT_FILE):
        print("❌ Fai prima la pulizia delle recensioni!")
        return

    raw_data = []
    users_set = set()
    items_set = set()

    print("-> Lettura interazioni...")
    with open(INPUT_FILE, 'r', encoding='utf-8') as f:
        for line in f:
            try:
                d = json.loads(line)
                u, p, r = d['reviewerID'], d['asin'], d['overall']
                if r >= 4.0:
                    raw_data.append((u, p))
                    users_set.add(u)
                    items_set.add(p)
            except: continue

    print(f"-> Dati caricati: {len(raw_data)} interazioni.")
    print(f"-> Utenti: {len(users_set)} | Prodotti: {len(items_set)}")

    print("-> Costruzione Dataset LightFM...")
    dataset = Dataset()
    dataset.fit(users=list(users_set), items=list(items_set))
    (interactions, _) = dataset.build_interactions(raw_data)

    print("-> Addestramento Modello (Algoritmo WARP)...")
    model = LightFM(loss='warp')
    model.fit(interactions, epochs=30, num_threads=2)

    # Salvataggio
    print("-> Salvataggio...")
    user_id_map, _, item_id_map, _ = dataset.mapping()
    idx_to_item = {v: k for k, v in item_id_map.items()}

    package = {
        "model": model,
        "item_id_map": item_id_map,
        "idx_to_item": idx_to_item
    }
    
    with open(MODEL_FILE, 'wb') as f:
        pickle.dump(package, f)
        
    print(f"✅ MODELLO REALE SALVATO IN '{MODEL_FILE}'!")

if __name__ == "__main__":
    train_final()