﻿using UnityEngine;
using System.Collections;
using TMPro;
using UnityEngine.InputSystem;
using UnityEngine.UI;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine.XR.Interaction.Toolkit;

public class DebugLogUnity : MonoBehaviour
{
    [SerializeField]
    private TextMeshProUGUI debugText;
    private string myLog;
    private Queue myLogQueue = new Queue();

    [SerializeField]
    private InputActionReference _inputToggleProperty;

    [SerializeField]
    private InputActionReference _buttonToggleProperty;

    [SerializeField]
    private GameObject _debugConsoleContent;

    [SerializeField]
    private bool _isToggled;

    [SerializeField]
    private TextMeshProUGUI _enableDisableWarningsField_TMPro;

    [SerializeField]
    private TextMeshProUGUI _enableDisableDebuggerField_TMPro;

    [SerializeField]
    private bool _isDebugging = true;

    [SerializeField]
    private bool _isShowingWarnings = false;

    [SerializeField]
    private XRRayInteractor _xrRayInteractor;

    [SerializeField]
    private XRInteractorLineVisual _xrInteractorLineVisual;

    // Text file (assigned from Editor)
    [SerializeField]
    private TextAsset TextFile;

    // List to hold all the lines read from the text file
    private List<string> lineList = new List<string>();
    private StringBuilder sb = new StringBuilder();

    void OnEnable()
    {
        Application.logMessageReceived += HandleLog;
    }

    void OnDisable()
    {
        ClearScreen();
        Application.logMessageReceived -= HandleLog;

        if(_inputToggleProperty != null)
            _inputToggleProperty.action.performed -= CheckForToggle;

        if (_buttonToggleProperty != null)
            _buttonToggleProperty.action.performed -= CheckForToggle;
    }

    private void Start()
    {
        if(_enableDisableDebuggerField_TMPro!=null)
            _enableDisableDebuggerField_TMPro.text = "DISABLE";

        if (_inputToggleProperty != null)
            _inputToggleProperty.action.performed += CheckForToggle;

        if (_buttonToggleProperty != null)
            _buttonToggleProperty.action.performed += CheckForToggle;

        if (TextFile!=null)
        {
            ReadTextList();
            GetTextLine();
        }
        
    }

    public void CheckForToggle(InputAction.CallbackContext context)
    {
        Debug.Log($"CheckForToggle: context.performed {context.performed}");
        if (context.performed)
        {
            // Look for input, and potential value
            float toggleValue = context.action.ReadValue<float>();
            //Debug.Log($"leftHandValue.y = {leftHandValue.y} leftHandValue.x = {leftHandValue.x}");

            //Debug.Log($"currentClick joystick = {toggleValue}");
            _isToggled = !_isToggled;

            if(_isToggled)
            {
                if(_xrRayInteractor != null && _xrInteractorLineVisual != null)
                {
                    _xrRayInteractor.enabled = true;
                    _xrInteractorLineVisual.enabled = true;
                }
            }
            else
            {
                if (_xrRayInteractor != null && _xrInteractorLineVisual != null)
                {
                    _xrRayInteractor.enabled = false;
                    _xrInteractorLineVisual.enabled = false;
                }
            }
            _debugConsoleContent.SetActive(_isToggled);
        }
    }

    void HandleLog(string logString, string stackTrace, LogType type)
    {
        myLog = logString;
        sb.Clear();
        string newString = "\n [" + type + "] : " + myLog;
        if(!_isShowingWarnings && type == LogType.Warning)
        {
            //Skip warnings
        }
        else
        {
            myLogQueue.Enqueue(newString);
        }
        
        if (type == LogType.Exception)
        {
            newString = "\n" + stackTrace;
            myLogQueue.Enqueue(newString);
        }
        myLog = string.Empty;

        foreach (string mylog in myLogQueue)
        {
            sb.Append(mylog);
        }

        if (_isDebugging)
            debugText.text = sb.ToString();
    }

    public void ClearScreen()
    {
        myLogQueue.Clear();
        sb.Clear();
        debugText.text = sb.ToString();
    }

    public void EnableDisableDebugScreen()
    {
        _isDebugging = !_isDebugging;
        if (_isDebugging)
        {
            Application.logMessageReceived += HandleLog;

            if(_enableDisableDebuggerField_TMPro != null)
                _enableDisableDebuggerField_TMPro.text = "DISABLE";
        }
        else
        {
            Application.logMessageReceived -= HandleLog;

            if (_enableDisableDebuggerField_TMPro != null)
                _enableDisableDebuggerField_TMPro.text = "ENABLE";
        }
    }

    public void EnableDisableWarnings()
    {
        _isShowingWarnings = !_isShowingWarnings;
        if (_isShowingWarnings)
        {
            if(_enableDisableWarningsField_TMPro != null)
                _enableDisableWarningsField_TMPro.text = "DISABLE WARNINGS";
        }
        else
        {
            if (_enableDisableWarningsField_TMPro != null)
                _enableDisableWarningsField_TMPro.text = "ENABLE WARNINGS";
        }
    }

    public void ReadTextList()
    {
        // Check if file exists before reading
        if (TextFile)
        {
            string line;
            StringReader textStream = new StringReader(TextFile.text);

            while ((line = textStream.ReadLine()) != null)
            {
                // Read each line from text file and add into list
                lineList.Add(line);
            }

            textStream.Close();
        }
    }

    public void GetTextLine()
    {
        Debug.Log($"NSFMAVRC Version = {lineList[0]}");
    }
}