using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class CommonParameterContainer : Singleton<CommonParameterContainer>
{
    [Header("Env")]
    public bool lockMouse = false;
    public float damage = 50; // damage to enemy
    public float fireRate = 0.5f;
    public int timeLimit = 30;
    public bool lockCameraX = false;
    public bool lockCameraY = true;
    public bool oneHotRayTag = false;
    public bool spawnAgentInAllMap = true;
    public int spinRecordMax = 40;
    public float spinPenaltyThreshold = 10;
    public float facingInviewEnemyDisCOEF = 0.5f;
    public string group1Tag = "Player";
    public string group2Tag = "Enemy";

    [Header("Dynamic Defaut Rewards")]
    //[Tooltip("Hit Enemy reward")]
    //public float hitRewardDefault = 60.0f;
    [Tooltip("Free mode Hit Enemy reward")]
    public float hitTargetRewardDefault = 25f;
    //[Tooltip("Enemy down reward")]
    //public float killRewardDefault = 60.0f;
    [Tooltip("Enemy down in area Reward")]
    public float killTargetEnemyRewardDefault = 25f;
    [Tooltip("stay in firebasesArea reward")]
    public float inAreaRewardDefault = 25.0f;
    [Tooltip("free left time bonus reward. ALLR + leftTime * r")]
    public float freeTimeBonusPerSec = 1.0f;
    [Tooltip("target left time bonus reward. ALLR + leftTime * r")]
    public float targetTimeBonusPerSec = 0.5f;
    [Tooltip("in area left time bonus reward. ALLR + leftTime * r")]
    public float areaTimeBonusPerSec = 0.2f;
    [Tooltip("distance reward reward = r*(1-(nowDis/startDis))")]
    public float distanceReward = 50.0f;
    [Tooltip("facing to Target distance reward reward = r*(1-(nowDis/startDis))")]
    public float facingTargetReward = 10.0f;

    [Space(10)]
    [Tooltip("Goto Win reward")]
    public float goWinRewardDefault = 999f;
    [Tooltip("Attack Win reward")]
    public float attackWinRewardDefault = 999f;
    [Tooltip("Defence Win reward")]
    public float defenceWinRewardDefault = 999f;
    [Tooltip("free Win reward")]
    public float freeWinRewardDefault = 999f;

    [Header("Static Rewards")]
    [Tooltip("Nothing happened reward")]
    public float nonReward = -1f;
    [Tooltip("Episode Lose reward")]
    public float loseReward = -999f;
    [Tooltip("Agent Do shoot action reward")]
    public float shootReward = -0.5f;
    [Tooltip("Hit Not target Enemy reward")]
    public float hitNonTargetReward = -5f;
    [Tooltip("Not Target Enemy down reward")]
    public float killNonTargetReward = -5f;
    [Tooltip("Agent Do shoot action but gun is not read")]
    public float shootWithoutReadyReward = -1.15f;
    [Tooltip("Kill bonus reward stack to nothing happend reward")]
    public float killBonusReward = 0.0f;
    [Tooltip("Facing to enemy's reward")]
    public float facingReward = 5f;
    [Tooltip("Shoot at target area but didn't hit enemy")]
    public float shootTargetAreaReward = 10f;

    [Header("Penalty Rewards")]
    [Tooltip("move Penalty Reward")]
    public float movePenalty = 0.1f;
    [Tooltip("spiiiiiiin Panalty Reward")]
    public float spinPenalty = 0.08f;
    [Tooltip("while move mouse a little bit's penalty")]
    public float mousePenalty = 0.06f;

    public SceneBlocksSet scenePrefabSet;

    [NonSerialized] public int gameMode; // 0 = trainning mode, 1 = play mode
    [NonSerialized] public float attackProb = 0f;
    [NonSerialized] public float gotoProb = 0f;
    [NonSerialized] public float defenceProb = 0f;

    public Dictionary<Targets, List<float>> levelProbs = new Dictionary<Targets, List<float>>();

    protected override void Awake()
    {
        base.Awake();
        scenePrefabSet.InitializeSceneBlocksSet();
        InitializeLevelProbs();
    }

    private void Start()
    {
        Instance.KeepThroughSceneChange();
    }

    // Initialize Common Parameters
    private void InitializeLevelProbs()
    {
        for(int i = 0; i< scenePrefabSet.targetLevels.Length; i++)
        {
            Targets nowTarget = scenePrefabSet.targets[i];
            levelProbs[nowTarget] = new List<float>();
            float levelNum = scenePrefabSet.GetLevelNumber(nowTarget);
            float averageProbability = 1f / levelNum;
            float lastLevelProbability = 1f - averageProbability * (levelNum - 1);
            for (int j = 0; j < levelNum-1; j++)
            {
                levelProbs[nowTarget].Add(averageProbability);
            }
            levelProbs[nowTarget].Add(lastLevelProbability);
        }
    }
}