using System.Collections.Generic;
using UnityEngine;

public class SceneBlock : MonoBehaviour
{
    public GameObject fireBasesAreaObj;
    public GameObject enemyContainerObj;
    public float group1InareaNum = 0;
    public float group2InareaNum = 0;
    public float belongRatio = 0;
    public float blockSize = 10f;
    public Vector3 firebasesAreaPosition;
    public float firebasesAreaScale;
    public float firebasesAreaDiameter;

    public enum SceneType
    { Go, Attack, Defence }

    public SceneType sceneType;
    public bool isDestroyed = false;

    // firebase state
    public string group1Tag = "Player";

    public string group2Tag = "Enemy";
    public float belongMaxPoint = 10f;
    public float firebasesBelong; // -10 mean's belon to group2Tag 10 = belon to group1Tag
    public float addPointInterval = 0.1f; // add point every addPointInterval scecond
    public float stayTimeNeeded = 5f; // howmany time to stay at area to get this area 0->10

    private float addPointEachInterval; // add point in each interval
    private float intervalStart;
    private GameObject environmentObj;
    public GameObject[] group1Objs;
    public GameObject[] group2Objs;

    // Start is called before the first frame update
    private void Start()
    {
        intervalStart = Time.time;
    }

    // Update is called once per frame
    private void Update()
    {
        if (Time.time - intervalStart >= addPointInterval)
        {
            // update belong ratio every addPointInterval scecond
            group1InareaNum = GetInAreaNumber(group1Tag);
            group2InareaNum = GetInAreaNumber(group2Tag);
            belongRatio = group1InareaNum - group2InareaNum;
            if (belongRatio > 0)
            {
                // group 1 have the advantage!
                firebasesBelong += addPointEachInterval;
                if (firebasesBelong >= belongMaxPoint)
                {
                    firebasesBelong = belongMaxPoint;
                }
            }
            else if (belongRatio < 0)
            {
                // group 2 have the advantage!
                firebasesBelong -= addPointEachInterval;
                if (firebasesBelong <= -belongMaxPoint)
                {
                    firebasesBelong = -belongMaxPoint;
                }
            }
            intervalStart = Time.time;
        }
    }

    //Initialize this scene block should be excuted after enemy created
    public void InitBlock(GameObject envObj)
    {
        //Buffer all Player or enemy obj int this environment to list
        environmentObj = envObj;
        GameObject[] allGroup1Objs = GameObject.FindGameObjectsWithTag(group1Tag);
        GameObject[] allGroup2Objs = GameObject.FindGameObjectsWithTag(group2Tag);
        List<GameObject> group1ObjsList = new List<GameObject>();
        List<GameObject> group2ObjsList = new List<GameObject>();
        foreach (GameObject obj in allGroup1Objs)
        {
            if (obj.transform.root.gameObject == envObj && !obj.GetComponent<States>().isDead)
            {
                group1ObjsList.Add(obj);
            }
        }
        foreach (GameObject obj in allGroup2Objs)
        {
            if (obj.transform.root.gameObject == envObj && !obj.GetComponent<States>().isDead)
            {
                group2ObjsList.Add(obj);
            }
        }
        group1Objs = group1ObjsList.ToArray();
        group2Objs = group2ObjsList.ToArray();

        // if firebasesAreaObj is null, find sub object by name
        if (fireBasesAreaObj == null)
        {
            // Debug.Log("SceneBlock.Start: fireBasesAreaObj not found, get it by name");
            fireBasesAreaObj = transform.Find("FirebasesArea").gameObject;
        }
        // if enemyContainerObj is null, find them by name
        if (enemyContainerObj == null)
        {
            // Debug.Log("SceneBlock.Start: enemyContainerObj not found, get it by name");
            enemyContainerObj = transform.Find("EnemyContainer").gameObject;
        }
        firebasesAreaPosition = transform.position + fireBasesAreaObj.transform.position;
        firebasesAreaScale = fireBasesAreaObj.transform.localScale.x;
        firebasesAreaDiameter = firebasesAreaScale * blockSize;
        firebasesBelong = -belongMaxPoint;
        addPointEachInterval = belongMaxPoint / (stayTimeNeeded / addPointInterval);
        intervalStart = Time.time;
    }

    //check game over 0=notover 1=win
    public int CheckOver()
    {
        return 0;
    }

    // get in area player number by tag
    public float GetInAreaNumber(string thisTag)
    {
        float inAreaNum = 0;
        float dist = 0f;
        float isInarea = 0f;
        int index = 0;
        if (thisTag == group1Tag)
        {
            foreach (GameObject obj in group1Objs)
            {
                // if object is dead then delete it from list
                if (obj == null)
                {
                    // delete null object from list
                    List<GameObject> group1ObjsList = new List<GameObject>(group1Objs);
                    group1ObjsList.RemoveAt(index);
                    group1Objs = group1ObjsList.ToArray();
                }
                else
                {
                    (dist, isInarea) = GetDistInArea(obj.transform.position);
                    if (isInarea != 0f)
                    {
                        inAreaNum += 1;
                    }
                }
                index++;
            }
        }
        else if (thisTag == group2Tag)
        {
            foreach (GameObject obj in group2Objs)
            {
                // if object is dead then delete it from list
                if (obj == null)
                {
                    // delete null object from list
                    List<GameObject> group2ObjsList = new List<GameObject>(group2Objs);
                    group2ObjsList.RemoveAt(index);
                    group2Objs = group2ObjsList.ToArray();
                }
                else
                {
                    (dist, isInarea) = GetDistInArea(obj.transform.position);
                    if (isInarea != 0f)
                    {
                        inAreaNum += 1;
                    }
                }
                index++;
            }
        }
        else
        {
            Debug.LogError("SceneBlock.getinAreaNumber:TagError");
        }
        return inAreaNum;
    }

    // get this position and target's distance and is in firebase area
    public (float, int) GetDistInArea(Vector3 thisPosition)
    {
        thisPosition.y = fireBasesAreaObj.transform.position.y;
        float dist = Vector3.Distance(thisPosition, fireBasesAreaObj.transform.position) - (firebasesAreaDiameter / 2);
        int isinarea = 0;
        if (dist <= 0)
        {
            dist = 0f;
            isinarea = 1;
        }
        else
        {
            isinarea = 0;
        }
        return (dist, isinarea);
    }

    //destroy this block
    public void DestroyMe()
    {
        Destroy(this.gameObject);
        foreach (Transform childObj in enemyContainerObj.transform)
        {
            childObj.GetComponent<States>().DestroyMe();
        }
        isDestroyed = true;
    }
}