using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Reflection.Emit;
using UnityEngine;
using UnityEngine.UI;
public class ScienceManager : MonoBehaviour
{   
    public int ScienceCostCurrentTech;
    public GameObject ScienceUI;
    public Text AccScienceLabel;

    public static int TechnologiesTotal = 4;
    public Tech[] techs = new Tech[TechnologiesTotal];


    public Text CostText;
    public Text[] TechQueueUIArr = new Text[4];
    public Text[] TechLevelLabels = new Text[4];
    
    public List<Tech> TechQueue = new();
    public int Amount = 0;

    private int ScienceAcumulated = 0;

    // Start is called before the first frame update
    void Start()
    {
        techs[0] = new Tech(1,1, "IndustryTech");
        techs[1] = new Tech(1,1, "WealthTech");
        techs[2] = new Tech(1,1, "ScienceTech");
        techs[3] = new Tech(1,1, "FoodTech");
        UpdateScience(0);
    }

    // Update is called once per frame
    void Update()
    {
        Amount = techs.Length ;
    }
    /// <summary>
    /// blend in/out science window
    /// </summary>
    public void SwitchScienceUI() 
    {
        if (ScienceUI.activeInHierarchy == true)
        {
            ScienceUI.SetActive(false);
        }
        else 
        {
            ScienceUI.SetActive(true);
        }
    }
    /// <summary>
    /// increase tech level
    /// reduce acumulated Science
    /// remove Tech from TechQueue
    /// </summary>
    public void UpdateScience(int actualScience) 
    {       
        this.ScienceAcumulated = actualScience;
        if ( this.TechQueue.Count > 0 ) 
        {
            ScienceCostCurrentTech = this.CalcScienceCost(this.TechQueue[0]);
            if (ScienceCostCurrentTech <= this.ScienceAcumulated)
            {
                for (int i = 0; i < this.techs.Length; i++)
                {
                    if (String.Equals(TechQueue[0].Name, techs[i].Name))
                    {
                        techs[i].Level++;
                    }
                }
                this.ScienceAcumulated -= ScienceCostCurrentTech;
                this.RemoveTechFromQueue(true);
                Debug.Log("TechQueue Count: " + TechQueue.Count);
            }
            else 
            {
                Debug.Log("Nicht genug Science Punkte");
            }           
        }
        UpdateScienceUI();
    }

    public int PublicScienceAcumulated => this.ScienceAcumulated;

    /// <summary>
    /// calculates the cost of next level of tech based on base cost and level
    /// </summary>
    /// <param name="t"></param>
    /// <returns></returns>
    public int CalcScienceCost(Tech t) 
    {
        int lvl = t.Level;      
        int result = (lvl * lvl )* t.Cost;
        //Debug.Log("Cost:" + result);
        ScienceCostCurrentTech = result;
        Debug.Log("Result: " + result);
        return result;
    }

    /// <summary>
    /// calculates the cost of next level of tech based on base cost and level
    /// </summary>
    /// <param name="t"></param>
    /// <returns></returns>
    public int CalcScienceCost(Tech t, int InQueue)
    {
        int lvl = t.Level + InQueue;
        int result = (lvl * lvl) * t.Cost;
        //Debug.Log("Cost:" + result);
        ScienceCostCurrentTech = result;
        Debug.Log("Result: " + result);
        return result;
    }


    public void AddToQueue(String name) 
    {
        
        //safequard agains queue overlfow
        if (TechQueue.Count >= 4) 
        {
            Debug.Log("Queue full");
            return;
        }
        for (int i = 0; i < this.techs.Length; i++)
        {
            
            if (String.Equals(name, techs[i].Name))
            {
                Debug.Log("i: " + i);
                TechQueue.Add(this.techs[i]);                
            }
        }        
        UpdateScienceUI();
        Debug.Log("TechQueue.Count: " + TechQueue.Count);
    }
    /// <summary>
    /// first=true is first element, first=false is last index
    /// </summary>
    /// <param name="first"></param>
    public void RemoveTechFromQueue(bool first) 
    {
        //safeguard against TechQueue underflow
        if (TechQueue.Count < 1) 
        {
            return;
        }
        
        if (first == true)
        {
            //remove first
            TechQueue.RemoveAt(0);
        }
        else 
        {
            //remove last
            TechQueue.RemoveAt(TechQueue.Count-1);
        }
        UpdateScienceUI();
    }
    public void UpdateQueueText()
    {
        
        //empty queue ui
        for (int i = 0; i < TechQueueUIArr.Length; i++)
        {
            TechQueueUIArr[i].text = "--";
        }
        // fill queue ui
        
        for (int i = 0; i < TechQueue.Count ; i++) 
        {
            Debug.Log("TechQueue.Count: " + TechQueue.Count);
            TechQueueUIArr[i].text =  TechQueue[i].Name;            
        }
    }
    public void UpdateScienceUI() 
    {
        UpdateQueueText();
        AccScienceLabel.text =  ScienceAcumulated.ToString();
        for (int i = 0; i < TechLevelLabels.Length; i++) 
        {            
            TechLevelLabels[i].text = techs[i].Level.ToString();
        }
        CostText.text = ScienceCostCurrentTech.ToString();
    }
    public void ResetPoints() 
    {
        this.ScienceAcumulated += 20;
        UpdateScienceUI();
    }
    public void DisplayCostReset() 
    {
        CostText.text = "0";
    }
    public void DisplayCost(String name) 
    {
        int NumberOcc = 0;
        for (int i = 0; i < this.TechQueue.Count; i++) 
        {
            if (String.Equals(TechQueue[i].Name, name))
            {
                NumberOcc++;
            }
        }
        
        for (int i = 0; i < this.techs.Length; i++)
        {
            if (String.Equals(name, techs[i].Name))
            {
                CostText.text = CalcScienceCost(techs[i], NumberOcc).ToString();
            }
        }
    }
}
public class Tech
{
    public int Cost;
    public int Level;
    public String Name;
    /// <summary>
    /// 
    /// </summary>
    /// <param name="c"></param>
    /// <param name="l"></param>
    /// <param name="n"></param>
    public Tech(int c, int l, String n) 
    {
        this.Cost = c;
        this.Level = l;
        this.Name = n;
    }
}

