using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;

/// <summary>
/// This class is responsible for loading all data from the Course-scriptableobject.
/// Specifically it fetches and displays the correct title, videos and images while also keeping track of the progress.
/// </summary>
public class StartPause : MonoBehaviour
{

    /// <summary>
    /// Reference to instructional video player
    /// </summary>
    public VideoPlayer player;
    /// <summary>
    /// Reference to pause button
    /// </summary>
    public Button button;
    
    /// <summary>
    /// Reference to sprite for the pause button
    /// </summary>
    public Sprite pauseSprite;
    
    /// <summary>
    /// Reference to the image for displaying the current words sprite
    /// </summary>
    public Image wordImage;
    
    /// <summary>
    /// Reference to the text object for displaying the current word
    /// </summary>
    public TextMeshProUGUI title;


    /// <summary>
    /// Reference to user list to get current user
    /// </summary>
    public UserList userList;

    /// <summary>
    /// The current user
    /// </summary>
    private User user;
    
    /// <summary>
    /// Current user progress for this course
    /// </summary>
    private Progress progress = null;


    /// <summary>
    /// ScriptableObject with list of all courses
    /// </summary>
    public CourseList courselist;
    
    /// <summary>
    /// Reference to Course ScriptableObject
    /// </summary>
    private Course course;

    
    /// <summary>
    /// Index of the current word/letter in the course.learnables list
    /// </summary>
    private int currentWordIndex = 0;
    
    /// <summary>
    /// This holds the amount of words in the course
    /// </summary>
    private int maxWords;

    /// <summary>
    /// Number of correct words so far
    /// (can be modified to a list or something like that to give better feedback)
    /// </summary>
    private int correctWords = 0;


    /// <summary>
    /// This function is called when the script is initialised.
    /// It takes the correct course from the courselist, using the courseIndex.
    /// Then it checks whether or not the User has started the course yet, to possibly create a new progress atribute for the course.
    /// Then it sets up the course-screen to display relevant information from the course-scriptable.
    /// </summary>
    public void Awake()
    {
        // Setting up course
        course = courselist.courses[courselist.currentCourseIndex];
        maxWords = course.learnables.Count;

        // Create entry in current user for keeping track of progress
        user = userList.GetCurrentUser();
        progress = user.courses.Find((p) => p != null && p.Get<CourseIndex>("courseIndex") == course.index);
        if (progress == null)
        {
            progress = new Progress();
            progress.AddOrUpdate<CourseIndex>("courseIndex", CourseIndex.FINGERSPELLING);
            progress.AddOrUpdate<float>("courseProgress", -1.0f);
            user.courses.Add(progress);
        }
        userList.Save();

        // Setup UI
        button.image.sprite = pauseSprite;
        title.text = course.name;
        NextVideo();
        NextImage();
    }

    // These two functions generate video and image from files 
    /// <summary>
    /// This function uses the word_i integer to grab the correct video from the course.learnabels.
    /// When it has this video, it will load it into the videoplayer and set it to start.
    /// </summary>
    private void NextVideo()
    {
        player.clip = course.learnables[currentWordIndex].clip;
        // This loads first frame, so that it can be used as a sort-of preview for the video
        player.Play();
        // As the video will start playiing -> hide button
        Color col = button.image.color;
        col.a = 0;
        button.image.color = col;
    }

    /// <summary>
    /// This function uses the word_i integer to grab the correct image from the course.learnabels.
    /// Then it simply loads it into wordImage so that it can be displayed.
    /// </summary>
    private void NextImage()
    {
        wordImage.sprite = course.learnables[currentWordIndex].image;
    }

    /// <summary>
    /// This function is called when the pause-button is pressed on the video.
    /// It switches between playing and pausing the video. 
    /// It then makes the button invisible when the video is playing, or visible when it's paused.
    /// </summary>
    public void Pause()
    {
        if (!player.isPlaying)
        {
            // Play video and hide button
            player.Play();
            Color col = button.image.color;
            col.a = 0;
            button.image.color = col;
        }
        else
        {
            // Pause video and show button
            player.Pause();
            Color col = button.image.color;
            col.a = 255;
            button.image.color = col;
        }
    }

    // Press next-sign button for next word
    /// <summary>
    /// This function is called when the next-sign button is pressed.
    /// It increased the wordindex and fetches new videos/images if index<max, because then the coure is not fincished yet.
    /// If the maximum is reached, finishcourse is called to save the "finished" progress to the user.
    /// </summary>
    public void NextSign()
    {
        // If the currentindex >= maxwords, it indicated that the course is already finished, running the next code is the meaningless.
        if (currentWordIndex >= maxWords) { return; }

        // Goto the next word/letter
        currentWordIndex++;

        // TODO: fix correct word count
        correctWords++;
        progress.AddOrUpdate<float>("courseProgress", (float)correctWords / (float)maxWords);
        userList.Save();

        // Update UI if course is not finished yet
        if (currentWordIndex < maxWords)
        {
            NextVideo();
            NextImage();
        }
        // Finish course and record progress
        else
        {
            FinishCourse();
        }
    }


    /// <summary>
    /// finishcourse is called to save the "finished" progress to the user.
    /// </summary>
    public void FinishCourse()
    {
        // TODO: update progress (maybe this can also be at the `NextSign()`-method)
        progress.AddOrUpdate<float>("courseProgress", correctWords / maxWords);
        userList.Save();
    }
}
