using Jovian.Calendar;
using UnityEngine;

namespace Nox.Game {
    public enum DayPhase {
        Midnight,
        Dawn,
        Morning,
        Afternoon,
        Dusk,
        Night
    }

    public class TimeHandler {
        private readonly AdventureSettings adventureSettings;
        private readonly AdventureData adventureData;
        private readonly WorldClock worldClock;

        private float localTime;

        private static readonly (float start, DayPhase phase)[] PhaseThresholds = {
            (0.00f, DayPhase.Midnight),
            (0.05f, DayPhase.Night),
            (0.17f, DayPhase.Dawn),
            (0.25f, DayPhase.Morning),
            (0.50f, DayPhase.Afternoon),
            (0.75f, DayPhase.Dusk),
            (0.90f, DayPhase.Night)
        };

        public TimeHandler(AdventureSettings adventureSettings, AdventureData adventureData, WorldClock worldClock, CalendarSettings calendarSettings) {
            this.adventureSettings = adventureSettings;
            this.adventureData = adventureData;
            this.worldClock = worldClock;
            // restore time from saved data
            var totalMinutes = (adventureData.currentDay * calendarSettings.MinutesPerDay)
                + (int)(adventureData.currentTime * calendarSettings.MinutesPerDay);
            worldClock.AdvanceMinutes(totalMinutes);
            localTime = adventureData.currentTime * adventureSettings.dayLength;
        }

        public void Tick() {
            if(!adventureData.isPartyMoving) {
                return;
            }

            localTime += Time.deltaTime;

            if(localTime >= adventureSettings.dayLength) {
                localTime -= adventureSettings.dayLength;
                adventureData.currentDay++;
            }

            var normalized = localTime / adventureSettings.dayLength;

            worldClock.Tick(normalized);

            adventureData.currentTime = normalized;
            adventureData.currentDayPhase = GetPhase(normalized);
        }

        private static DayPhase GetPhase(float t) {
            var phase = DayPhase.Midnight;
            foreach(var (start, p) in PhaseThresholds) {
                if(t >= start) {
                    phase = p;
                }
                else {
                    break;
                }
            }
            return phase;
        }
    }
}
