using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using DG.Tweening;

public class GameController : MonoBehaviour
{
    // Variables
    public enum State { Sleeping, Socializing, Working, Neutral };
    private State activeState = State.Neutral;
    float timer = 0;
    int seconds = 0;
    private Vector3 doorClosePosition;
    private Vector3 doorOpenPosition = new Vector3((float)-7.08, (float)0.34, 0);
    private Tweener tweener;
    public bool isDoorOpen = false;
    public AudioClip doorSound;
    private float maxStat;

    [Header("Player")]
    [SerializeField] PlayerController player;

    [Header("Click Events")]
    [SerializeField] ClickHandler bedClickHandler;
    [SerializeField] ClickHandler tableClickHandler;
    [SerializeField] ClickHandler doorClickHandler;

    [Header("Times")]
    [SerializeField] int SecondsToUpdateStates = 2;

    [Header("States")]
    [SerializeField] float sleeping = 50;
    [SerializeField] float socializing = 50;
    [SerializeField] float working = 50;

    public PaintTriangle paintTriangle;

    [Header("States variations while Sleeping")]
    [SerializeField] float SleepSleepingVariation = 2;
    [SerializeField] float SleepWorkingVariation = -2;
    [SerializeField] float SleepSocializingVariation = -1;

    [Header("States variations while Working")]
    [SerializeField] float WorkSleepingVariation = -2;
    [SerializeField] float WorkWorkingVariation = 2;
    [SerializeField] float WorkSocializingVariation = -1;

    [Header("States variations while Socializing")]
    [SerializeField] float SocialSleepingVariation = -2;
    [SerializeField] float SocialWorkingVariation = -1;
    [SerializeField] float SocialSocializingVariation = 2;

    [Header("States variations while Neutral")]
    [SerializeField] float NeutralSleepingVariation = -1;
    [SerializeField] float NeutralWorkingVariation = -1;
    [SerializeField] float NeutralSocializingVariation = -1;
    
    [Header("Cursor")]
    [SerializeField] Texture2D cursorNormalSprite;
    [SerializeField] Texture2D cursorProhibited;

    private bool canInteract = true;
    private bool final;

    public bool started;
    
    private void Start()
    {
        bedClickHandler.clickEvent.AddListener(BedHandler);
        tableClickHandler.clickEvent.AddListener(TableHandler);
        doorClickHandler.clickEvent.AddListener(DoorHandler);

        doorClosePosition = doorClickHandler.transform.position;
        maxStat = sleeping;
    }

    private void Update()
    {
        if (!started)
            return;
        
        timer += Time.deltaTime;
        seconds = (int)timer % 60;

        switch (activeState)
        {
            case State.Sleeping:
                UpdateStates(SleepSleepingVariation, SleepSocializingVariation, SleepWorkingVariation);
                break;
            case State.Socializing:
                UpdateStates(SocialSleepingVariation, SocialSocializingVariation, SocialWorkingVariation);
                break;
            case State.Working:
                UpdateStates(WorkSleepingVariation, WorkSocializingVariation, WorkWorkingVariation);
                break;
            case State.Neutral:
                UpdateStates(NeutralSleepingVariation, NeutralSocializingVariation, NeutralWorkingVariation);
                break;
        }
    }

    private void BedHandler()
    {
        if (!canInteract || final)
            return;

        BlockInteract();
        
        if (activeState == State.Sleeping)
        {
            player.MoveToNeutral(new Vector3(-0.7f, -1.6f, -1));
        }
        else
        {
            if(activeState == State.Socializing)
            {
                OpenDoor();
                player.MoveToBed(new Vector3(bedClickHandler.position.x - 2.5f, bedClickHandler.position.y + 1f, 0));
            }
            else
            {
                player.MoveToBed(new Vector3(bedClickHandler.position.x - 2.5f, bedClickHandler.position.y + 1f, 0));
            }

        }
    }

    private void TableHandler()
    {
        if (!canInteract || final)
            return;

        BlockInteract();
        
        if (activeState == State.Working)
        {
            player.MoveToNeutral(new Vector3(-0.7f, -1.6f, -1));
        }
        else
        {
            if(activeState == State.Socializing)
            {
                OpenDoor();
                player.MoveToTable(new Vector3(tableClickHandler.position.x - 0.25f, tableClickHandler.position.y - 1.5f, 0));
            }
            else
            {
                player.MoveToTable(new Vector3(tableClickHandler.position.x - 0.25f, tableClickHandler.position.y - 1.5f , 0));
            }
        }
    }

    private void DoorHandler()
    {
        if (!canInteract || final)
            return;

        BlockInteract();
        
        OpenDoor();
        if (activeState == State.Socializing)
        { 
            player.MoveToNeutral(new Vector3(-0.7f, -1.6f, -1));
        }
        else
        {
            if (activeState == State.Sleeping)
            {
                OpenDoor();
                player.MoveToDoor(new Vector3(doorClickHandler.position.x - 2, doorClickHandler.position.y, 0));
            }
            else
            {
                player.MoveToDoor(new Vector3(doorClickHandler.position.x - 2, doorClickHandler.position.y, 0));
            }
        }
    }

    public void ChangeState(State state)
    {
        activeState = state;
        timer = 0;
    }

    public void FinalBlock()
    {
        final = true;
        CursorHandler.ChangeCursor(cursorProhibited, false);
        CursorHandler.ChangeLockState(true);
    }
    
    public void BlockInteract()
    {
        canInteract = false;
        CursorHandler.ChangeCursor(cursorProhibited, false);
        CursorHandler.ChangeLockState(true);
    }
    
    public void CanInteract()
    {
        canInteract = true;
        CursorHandler.ChangeLockState(false);
    }

    /// <sumary>
    /// Update the states and variations variables over the time
    /// </sumary>
    /// <param name="slVar">The sleeping variation</param>
    /// <param name="scVar">The sozializing variation</param>
    /// <param name="wrVar">The working variation</param>
    private void UpdateStates(float slVar, float scVar, float wrVar)
    {
        if(seconds >= SecondsToUpdateStates)
        {
            sleeping += slVar;
            sleeping = Mathf.Clamp(sleeping, 0, maxStat); 
            working += wrVar;
            working = Mathf.Clamp(working, 0, maxStat);
            socializing += scVar;
            socializing = Mathf.Clamp(socializing, 0, maxStat);

            paintTriangle.sleep =  sleeping / maxStat;
            paintTriangle.selfRealisation = working / maxStat;
            paintTriangle.social = socializing / maxStat;
            paintTriangle.IconsChanges(slVar, wrVar, scVar);
            ResetTimer();
        }
    }

    private void ResetTimer()
    {
        timer = 0;
        seconds = 0;
    }

    public Vector3 getBedPosition()
    {
        return bedClickHandler.position;
    }

    private void OpenDoor()
    {
        if (tweener != null)
        {
            tweener.Kill();
        }

        tweener = doorClickHandler.transform.DOMove(doorOpenPosition, 1);
        AudioController.Instance.PlaySound(doorSound);
        isDoorOpen = true;
    }

    public void CloseDoor()
    {
        if(tweener != null)
        {
            tweener.Kill();
        }

        tweener =  doorClickHandler.transform.DOMove(doorClosePosition, 1);
        AudioController.Instance.PlaySound(doorSound);
        isDoorOpen = false;
    }
}
