using System;
using UnityEngine;
using UnityEngine.Serialization;
using Utility;

public class TimeManager : MonoBehaviourSingleton<TimeManager>
{
    [SerializeField]
    private int _daysUntilRelease = 30;

    [SerializeField]
    private double _secondsPerDay = 48;

    [FormerlySerializedAs("_dayTime")] [SerializeField]
    private double _totalTime = 0.0;

    [SerializeField] private Light _sun; 
    
    private DateTime _startDate;
    private DateTime _deadline;
    
    public int DaysLeft => _daysUntilRelease;
    
    public DayOfWeek CurrentDayOfWeek => CurrentDate.DayOfWeek;

    public TimeSpan TimeOfDay => CurrentDate.TimeOfDay;

    /// <summary>
    /// Das Datum zu dem das Spiel begonnen hat.
    /// </summary>
    public DateTime StartDate => _startDate;
    
    /// <summary>
    /// Das aktuelle Datum und Uhrzeit im Spiel.
    /// </summary>
    public DateTime CurrentDate => _startDate.AddDays(_totalTime);
    
    /// <summary>
    /// Die Deadline des Spiels.
    /// </summary>
    public DateTime Deadline => _deadline;

    /// <summary>
    /// Gibt true zurück, wenn die Deadline verpasst wurde.
    /// </summary>
    public bool MissedDeadline => CurrentDate > Deadline;
    
    public void Init()
    {
        _startDate = new DateTime(2024, 4, 2, 12, 0, 0);
        _deadline = _startDate.AddDays(_daysUntilRelease);
    }

    /// <summary>
    /// Berechnet die (real life) Sekunden, die die Entwickler bei 100% Effizienz benötigen um das Spiel bei gegebener Schwierigkeit zu entwickeln.
    /// </summary>
    public double CalculateActualDeveloperTime(Difficulty difficulty, int developerCount)
    {
        DifficultySettings settings = difficulty.GetSettings();
        
        return (_daysUntilRelease * _secondsPerDay * developerCount) / settings.DaysUntilReleaseFactor;
    }
    
    void Update()
    {
        if (GameManager.Instance.IsGameRunning)
        {
            UpdateTime();
            UpdateSun();
        }
    }
    
    void UpdateTime()
    {
        _totalTime += Time.deltaTime / _secondsPerDay;
        
        if (_totalTime >= 1.0)
        {
            _totalTime -= 1.0;
            _daysUntilRelease--;
        }
    }

    private void UpdateSun()
    {
        float currentTime = (float)TimeOfDay.TotalDays;
        
        _sun.transform.rotation = Quaternion.Euler(new Vector3(Mathf.LerpAngle(-90, 60, (float)Math.Sin(currentTime * Math.PI)), (float)(currentTime * 360.0), 0));
    }
}