using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.SceneManagement;


public class ExperimentManager9_single : MonoBehaviour
{
    [SerializeField] private GameObject target;
    [SerializeField] private TMP_Text message;
    [SerializeField] private Button light_button;
    [SerializeField] private Button heavy_button;
    [SerializeField] private GameObject canvas;
    [SerializeField] private Button exit_button;

    SingleBlockTrial[] trials;
    private int[] responses;
    private int trial = 0;

    private Dictionary<string,AudioClip> clips;
    private Dictionary<string,Material> materials;

    private float show_time = float.MaxValue;

    private Vector3 reset_position;
    private Quaternion reset_rotation;
    private Vector3 reset_scale;


    // Start is called before the first frame update
    void Start()
    {
        // allocate arrays to match fields
        trials = Configurator.config.GetSingleBlockExperiment();
        responses = new int[trials.Length];

        // locate audio clips and materials, if using
        List<string> soundNames = Configurator.config.AvailableSounds();
        clips = new Dictionary<string, AudioClip>();

        for ( int ii = 0; ii < soundNames.Count; ++ii )
        {
            if ( clips[soundNames[ii]] = Resources.Load<AudioClip>(soundNames[ii]))
            {
            }
            else
            {
                Debug.Log($"Unable to load clip {soundNames[ii]}");
            }
        }

        materials = new Dictionary<string, Material>();
        for ( int ii = 0; ii < Configurator.colours.Length; ++ii )
        {
            materials[Configurator.colours[ii]] = Resources.Load<Material>(Configurator.colours[ii]);
        }

        reset_position = target.transform.position;
        reset_rotation = target.transform.rotation;
        reset_scale = target.transform.localScale;

        // set initial values
        ConfigureTrial();

        // listen for button clicks
        light_button.onClick.AddListener(delegate {Respond(0);});
        heavy_button.onClick.AddListener(delegate {Respond(1);});

        canvas.SetActive(false);
        show_time = Time.time + 1.5f;
    }

    void ConfigureTrial ()
    {
        SingleBlockTrial t = trials[trial];

        target.GetComponent<Rigidbody>().mass = t.block.mass;
        target.transform.localScale = new Vector3(t.block.size * reset_scale.x,
                                                  t.block.size * reset_scale.y,
                                                  t.block.size * reset_scale.z);
        if ( t.block.sound != "" )
        {
            target.GetComponent<AudioSource>().clip = clips[t.block.sound];
        }

        if ( t.block.material != "" )
        {
            target.GetComponent<MeshRenderer>().material = materials[t.block.material];
        }

        message.text = $"[{Configurator.config.experiment}: {trial + 1}/{trials.Length}] Does the block feel heavy or light?";
    }

    // log an experiment response
    void Respond ( int response )
    {
        responses[trial] = response;

        Debug.Log($"response received: {response}");

        trial += 1;
        if ( trial >= trials.Length )
        {
            message.text = $"Experiment complete. Saved to '{Configurator.config.experiment}.csv'.";
            light_button.gameObject.SetActive(false);
            heavy_button.gameObject.SetActive(false);
            exit_button.gameObject.SetActive(true);
            SaveResults();
        }
        else
        {
            ConfigureTrial();
        }

        canvas.SetActive(false);
        show_time = Time.time + 1.5f;
    }

    void Update()
    {
        if ( Time.time >= show_time )
        {
            show_time = float.MaxValue;
            canvas.SetActive(true);
        }
    }

    void SaveResults()
    {
        string outfile = Path.Combine(Application.persistentDataPath, $"{Configurator.config.experiment}.csv");
        Debug.Log(outfile);

        using StreamWriter writer = new StreamWriter(outfile);
        writer.WriteLine($"Trial,{SingleBlockTrial.Header()},Response");
        for (int ii = 0; ii < trials.Length; ++ii)
        {
            writer.WriteLine($"{ii + 1},{trials[ii].Values()},{responses[ii]}");
        }
    }

    public void Exit ()
    {
        SceneManager.LoadScene("SettingsScreen");
    }
}
