import os
import models.models
from simpy import Environment
import pandas as pd
import shutil


def main():
    """
    run the experiment models.py for a number of times defined in the Import_Daten document
    exporting data gathered in the experiment to a experiment folder
    """
    # Setup and start the simulation
    import_document = 'Import_Daten.xlsx'

    simulation_df = pd.read_excel(import_document, sheet_name='simulation', comment='#')
    simulation_parameters = dict(zip(simulation_df['Simulation'], simulation_df['Value']))

    export_product_attributes_df_combined = pd.DataFrame()
    export_product_df_combined = pd.DataFrame()
    export_hr_attributes_df_combined = pd.DataFrame()
    export_hr_df_combined = pd.DataFrame()
    export_offer_attributes_df_combined = pd.DataFrame()
    export_offer_df_combined = pd.DataFrame()
    export_order_df_combined = pd.DataFrame()
    export_demand_attributes_df_combined = pd.DataFrame()
    export_demand_df_combined = pd.DataFrame()

    for run_number in range(simulation_parameters['runs']):
        print(run_number)
        env = Environment()
        model = models.models.ReUseModel(import_document, env)
        env.run(until=simulation_parameters['run_until'])

        # export product data
        export_product_attributes_data = []
        export_product_data = []
        attributes = ['id', 'type', 'quality', 'price']
        for product in model.products_simulation:
            for attr in attributes:
                export_product_attributes_data.append(
                    dict(UUID=product.UUID, variableID=attr, variable_specification='', value=getattr(product, attr)))
            for item in product.status_time:
                export_product_data.append(
                    dict(UUID=product.UUID, variableID=item[1], variable_specification=item[2], value=item[0]))

        export_product_attributes_df = pd.DataFrame(export_product_attributes_data)
        export_product_df = pd.DataFrame(export_product_data)
        export_product_attributes_df['experiment'] = simulation_parameters['experiment']
        export_product_df['experiment'] = simulation_parameters['experiment']
        export_product_attributes_df['run'] = run_number
        export_product_df['run'] = run_number

        export_product_attributes_df_combined = pd.concat([export_product_attributes_df_combined,
                                                           export_product_attributes_df], ignore_index=True)
        export_product_df_combined = pd.concat([export_product_df_combined, export_product_df], ignore_index=True)

        # export offer data
        export_offer_attributes_df = pd.DataFrame(model.offer_attributes_export_data)
        export_offer_df = pd.DataFrame(model.offer_export_data)
        export_offer_attributes_df['experiment'] = simulation_parameters['experiment']
        export_offer_df['experiment'] = simulation_parameters['experiment']
        export_offer_attributes_df['run'] = run_number
        export_offer_df['run'] = run_number

        export_offer_attributes_df_combined = pd.concat([export_offer_attributes_df_combined,
                                                         export_offer_attributes_df], ignore_index=True)
        export_offer_df_combined = pd.concat([export_offer_df_combined, export_offer_df], ignore_index=True)

        # export order data
        export_order_df = pd.DataFrame(model.order_export_data)
        export_order_df['experiment'] = simulation_parameters['experiment']
        export_order_df['run'] = run_number

        export_order_df_combined = pd.concat([export_order_df_combined, export_order_df], ignore_index=True)

        # export demand data
        export_demand_attributes_df = pd.DataFrame(model.demand_attributes_export_data)
        export_demand_df = pd.DataFrame(model.demand_export_data)
        export_demand_attributes_df['experiment'] = simulation_parameters['experiment']
        export_demand_df['experiment'] = simulation_parameters['experiment']
        export_demand_attributes_df['run'] = run_number
        export_demand_df['run'] = run_number

        export_demand_attributes_df_combined = pd.concat([export_demand_attributes_df_combined,
                                                          export_demand_attributes_df], ignore_index=True)
        export_demand_df_combined = pd.concat([export_demand_df_combined, export_demand_df], ignore_index=True)

        # export hr data
        export_hr_attributes_data = []
        export_hr_data = []
        for hr in model.human_resources.get_skilled_workers():
            export_hr_attributes_data.append(
                dict(UUID=hr.UUID, variableID='skill_set', variable_specification='', value=hr.skills))
            for util_data in hr.utilization_data:
                export_hr_data.append(dict(UUID=hr.UUID, variableID=util_data[3], variable_specification=util_data[2],
                                           value=util_data[0]))

        export_hr_attributes_df = pd.DataFrame(export_hr_attributes_data)
        export_hr_df = pd.DataFrame(export_hr_data)
        export_hr_attributes_df['experiment'] = simulation_parameters['experiment']
        export_hr_df['experiment'] = simulation_parameters['experiment']
        export_hr_attributes_df['run'] = run_number
        export_hr_df['run'] = run_number

        export_hr_attributes_df_combined = pd.concat([export_hr_attributes_df_combined,
                                                      export_hr_attributes_df], ignore_index=True)
        export_hr_df_combined = pd.concat([export_hr_df_combined, export_hr_df], ignore_index=True)

    new_experiment_folder = simulation_parameters['experiment']
    os.makedirs(new_experiment_folder, exist_ok=True)

    export_product_attributes_df_combined.to_csv(
        os.path.join(new_experiment_folder, 'export_data_products_attributes.csv'))
    export_product_df_combined.to_csv(os.path.join(new_experiment_folder, 'export_data_products.csv'))
    export_offer_attributes_df_combined.to_csv(os.path.join(new_experiment_folder, 'export_data_offer_attributes.csv'))
    export_offer_df_combined.to_csv(os.path.join(new_experiment_folder, 'export_data_offer.csv'))
    export_order_df_combined.to_csv(os.path.join(new_experiment_folder, 'export_data_order.csv'))
    export_demand_attributes_df_combined.to_csv(
        os.path.join(new_experiment_folder, 'export_data_demand_attributes.csv'))
    export_demand_df_combined.to_csv(os.path.join(new_experiment_folder, 'export_data_demand.csv'))
    export_hr_attributes_df_combined.to_csv(os.path.join(new_experiment_folder, 'export_data_hr_attributes.csv'))
    export_hr_df_combined.to_csv(os.path.join(new_experiment_folder, 'export_data_hr.csv'))
    simulation_df.to_csv(os.path.join(new_experiment_folder, 'export_data_simulation.csv'))

    shutil.copy(import_document, new_experiment_folder)


if __name__ == "__main__":
    main()
