"""
create_hybrid_datasets.py — Dataset per il modello ibrido deterministico

Genera il dataset di training per i modelli Ridge che predirono la domanda media
attesa in funzione dell'assortimento (modello ibrido deterministico).

Logica di campionamento:

  Per ogni campione:
    1. Genera un assortimento casuale a (con probabilità p campionata da U[0.05,0.95]).
    2. Calcola le probabilità di scelta dato l'assortimento (MNL + sostituzione).
    3. Calcola il flusso di domanda totale attesa (primaria + sostituzione in-catalog).
    4. Registra: assortimento e domanda_media + delta_no_buy.

  Nota: NON si usa Gurobi qui. Si calcola direttamente la domanda attesa tramite 
  ClientArrivals._total_demand_flow(), che tiene conto della sostituzione
  aggregando le probabilità.

Struttura del dataset prodotto:

  Ogni riga: [a_0, ..., a_N, d_0_mean, ..., d_N_mean, delta_no_buy]
  - a_i binaria  : assortimento binario
  - d_i_mean     : domanda media attesa per il prodotto i
  - delta_no_buy : variazione del no-buy rispetto al full-assortment baseline

Output:
  - dataset_train_deterministico.csv 
"""

import sys
import os
cartella_progetto = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
if cartella_progetto not in sys.path:
    sys.path.append(cartella_progetto)
from models import *
from optimization import *
from prepare_data import *
import numpy as np
import pandas as pd

def main():
    dataset_filename_train_det= "dataset_train_deterministico.csv"

    #per avere la struttura di base: quindi il caricamento del dataset, il rate degli arrivi
    data=prepare_input_data(force_recalculate=False, SAA_flag=False, n_warm_scenarios=0, used_seed=1673, nome_file='dati_progetto_hybrid_det.pkl')

    if os.path.exists(dataset_filename_train_det):
        print(f"Datasets trovati.")

    else:
        print("Impossibile trovare il dataset. Inizio generazione:") 
        #se non abbiamo già il dataset, chiama la funzione di prepare_data.py: prepare_arrivals_det 
        #quindi bisogna istanziare MakertSimulation, LatentChoiceModel e ClientArrival, e avere il dataset ripulito dei prodotti che sono richiesti dalla funzione 

        rate_arrival=data["base"]["rate_arrival"]
        num_products=data["base"]["prodotti_tab"].shape[0]

        sim=MarketSimulation(data["base"]["prodotti_tab"])
        r=sim.sim_prod_prepare()

        #Modello di scelta
        choice_model=sim.use_model(MNLChoiceModel,LatentChoiceModel)

        #Domanda che si realizza 
        arrivals=ClientArrivals(rate_arrival,seed=3682)
 
        num_sample=30000
        dataset_det=prepare_arrivals_det(arrivals,sim,choice_model,r[1],num_sample)

        X_det,y_det,delta_no_buy=dataset_det

        headers_X_det=[f"a_{i}" for i in range(num_products)]
        headers_y_det=[f"d_{i}_mean" for i in range(num_products)]
        header_no_buy=[f"delta_no_buy"]
        headers_det=headers_X_det+headers_y_det+header_no_buy

        df_det=pd.DataFrame(np.hstack((X_det, y_det, delta_no_buy)), columns=headers_det)

        df_det=df_det.sample(frac=1,random_state=42).reset_index(drop=True)

        df_det.to_csv(dataset_filename_train_det,index=False)        

        print("Dataset creato")
        return df_det
if __name__ == "__main__":
    main()




