using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class TransmissionManager : MonoBehaviour
{
    public TextAsset TransmissionDatabaseCSV;

    public Dictionary<int, TransmissionData> transmissionDatas;

    void Awake()
    {
        _instance = FindObjectOfType<TransmissionManager>();
        if (_instance == null)
        {
            var newObj = new GameObject();
            newObj.name = "TransmissionManager";
            newObj.AddComponent<TransmissionManager>();
            _instance = FindObjectOfType<TransmissionManager>();
        }
    }

    void Start()
    {
        Init();
    }

    public static TransmissionManager Instance
    {
        get
        {
            return _instance;
        }
    }
    private static TransmissionManager _instance;

    public void Init()
    {
        transmissionDatas = new Dictionary<int, TransmissionData>();
        if(TransmissionDatabaseCSV == null)
        {
            return;
        }
        string[,] csvStrings = SplitCsvGrid(TransmissionDatabaseCSV.text);
        for (int i = 1; i < csvStrings.GetLength(1); i++)
        {
            if (csvStrings[0, i] != null)
            {
                TransmissionData data = new TransmissionData();
                data.TransmissionId = Int32.Parse(csvStrings[0, i]);
                data.FromCharacterId = (CharacterId)Int32.Parse(csvStrings[1, i]);
                data.ToCharacterId = (CharacterId)Int32.Parse(csvStrings[2, i]);
                data.AudioFileName = csvStrings[4, i];
                data.DelayTime = csvStrings[5, i] != "" ? float.Parse(csvStrings[5, i]) : 0f;
                data.EffectId = csvStrings[6, i] != "" ? Int32.Parse(csvStrings[6, i]) : 0;
                data.StartDay = (csvStrings[7, i] == "" || csvStrings[7, i] == "") ? -1 : Int32.Parse(csvStrings[7, i]);

                data.ImmediateAudioFeedbackFileName = new Dictionary<int, string>();
                for (int j = 8; j <= 20; j++)
                {
                    if (csvStrings[j, i] != null && csvStrings[j, i] != "")
                    {
                        data.ImmediateAudioFeedbackFileName.Add(j - 8, csvStrings[j, i]);
                    }
                }
                data.EndGameConnectedText = new Dictionary<CharacterId, string>();
                for (int j = 21; j <= 33; j++)
                {
                    if (csvStrings[j, i] != null && csvStrings[j, i] != "")
                    {
                        data.EndGameConnectedText.Add((CharacterId)(j - 21), csvStrings[j, i]);
                    }
                }
                data.EndGameConnectedImageFileName = new Dictionary<int, string>();
                for (int j = 34; j <= 46; j++)
                {
                    if (csvStrings[j, i] != null && csvStrings[j, i] != "")
                    {
                        data.EndGameConnectedImageFileName.Add(j - 34, csvStrings[j, i]);
                    }
                }
                data.ConnectedTransmissionId = new Dictionary<CharacterId, int>();
                for (int j = 47; j <= 59; j++)
                {
                    if (csvStrings[j, i] != null && csvStrings[j, i] != "")
                    {
                        data.ConnectedTransmissionId.Add((CharacterId)(j - 47), Int32.Parse(csvStrings[j, i]));
                    }
                }
                data.CharacterToKill = new List<CharacterId>();
                for (int j = 60; j <= 71; j++)
                {
                    if (csvStrings[j, i] != null && csvStrings[j, i] != "" && Int32.Parse(csvStrings[j, i]) == 1)
                    {
                        data.CharacterToKill.Add((CharacterId)(j - 60));
                    }
                }
                //Debug.Log("data id: " + data.TransmissionId);
                //Debug.Log("data FromCharacterId: " + data.FromCharacterId);
                //Debug.Log("data ToCharacterId: " + data.ToCharacterId);
                //Debug.Log("data audiofilename: " + data.AudioFileName);
                //Debug.Log("data ImmediateAudioFeedbackFileName: " + data.ImmediateAudioFeedbackFileName.Values.Aggregate(
                //              (c, n) => { return c + "   " + n; }));
                //Debug.Log("data DelayTime: " + data.DelayTime);
                //Debug.Log("data EffectId: " + data.EffectId);
                //Debug.Log("data EndGameConnectedText: " + data.EndGameConnectedText.Values.Aggregate(
                //              (c, n) => { return c + "   " + n; }));
                //Debug.Log("data EndGameConnectedImageFileName: " + data.EndGameConnectedImageFileName.Values.Aggregate(
                //             (c, n) => { return c + "   " + n; }));
                //Debug.Log("data ConnectedTransmissionId: " + data.ConnectedTransmissionId.Values.Select(c => c.ToString()).Aggregate(
                //           (c, n) => { return "" + c + "   " + n; }));
                //Debug.Log("data CharacterToKill: " + data.CharacterToKill.Select(c => c.ToString()).Aggregate(
                //         (c, n) => { return "" + c + "   " + n; }));
                transmissionDatas.Add(data.TransmissionId, data);
            }
        }
    }

    public TransmissionData GetTransmissionDataById(int id)
    {
        return transmissionDatas[id];
    }

    static public void DebugOutputGrid(string[,] grid)
    {
        string textOutput = "";
        for (int y = 0; y < grid.GetUpperBound(1); y++)
        {
            for (int x = 0; x < grid.GetUpperBound(0); x++)
            {

                textOutput += grid[x, y];
                textOutput += "|";
            }
            textOutput += "\n";
        }
        Debug.Log(textOutput);
    }

    static public string[,] SplitCsvGrid(string csvText)
    {
        string[] lines = csvText.Split("\n"[0]);

        // finds the max width of row
        int width = 0;
        for (int i = 0; i < lines.Length; i++)
        {
            string[] row = SplitCsvLine(lines[i]);
            width = Mathf.Max(width, row.Length);
        }

        // creates new 2D string grid to output to
        string[,] outputGrid = new string[width + 1, lines.Length + 1];
        for (int y = 0; y < lines.Length; y++)
        {
            string[] row = SplitCsvLine(lines[y]);
            for (int x = 0; x < row.Length; x++)
            {
                outputGrid[x, y] = row[x];

                // This line was to replace "" with " in my output. 
                // Include or edit it as you wish.
                outputGrid[x, y] = outputGrid[x, y].Replace("\"\"", "\"");
            }
        }

        return outputGrid;
    }

    static public string[] SplitCsvLine(string line)
    {
        return (from System.Text.RegularExpressions.Match m in System.Text.RegularExpressions.Regex.Matches(line,
        @"(((?<x>(?=[,\r\n]+))|""(?<x>([^""]|"""")+)""|(?<x>[^,\r\n]+)),?)",
        System.Text.RegularExpressions.RegexOptions.ExplicitCapture)
                select m.Groups[1].Value).ToArray();
    }
}
