﻿using System;
using System.Collections;
using System.Collections.Generic;
using AsmodeeDigital.Common.Plugin.Manager.Event;
using AsmodeeDigital.Common.Plugin.Utils;
using AsmodeeDigital.CrossPromo.Plugin.Domain;
using UnityEngine;

namespace AsmodeeDigital.CrossPromo.Plugin.Manager
{
    public class AnalyticsManager : MonoBehaviour
    {
        private const string _debugModuleName = "AnalyticsManager";

        #region Events
        public event Action<AnalyticsItem> AnalyticsEvent;
        #endregion

        public static AnalyticsManager Instance;
        private static Dictionary<string, object> _headersDic = new Dictionary<string, object>();

        public enum FirstParties
        {
            Steam,
            AppStore,
            GooglePlay,
            Asmodee
        }

        public enum Environments
        {
            dev,  // on a developper machine
            test, // on a test release (alpha, beta, ...)
            prod  // on a final public release
        }

        public string Context
        {
            get
            {
                return _context;
            }
            set
            {
                _context = value;
                _screenCountContext = 1;
            }
        }

        private float _elapsedTime = float.MinValue;
        private string _screen = "not_applicable";
        private string _context = null;
        private uint _screenCount = 1;
        private uint _screenCountContext = 1;

        private void OnEnable()
        {
            Instance = this;
            _elapsedTime = Time.unscaledTime;
        }

        private static string GetHeaderName(Headers header)
        {
            return Enum.GetName(typeof(Headers), header);
        }

        public static void SetPlayfabId(string id)
        {
            _headersDic[GetHeaderName(Headers.playfab_id)] = id;
        }

        public static void SetFirstParty(FirstParties firstParty)
        {
            _headersDic[GetHeaderName(Headers.first_party)] = firstParty;
        }

        public static void SetEnvironnement(Environments env)
        {
            _headersDic[GetHeaderName(Headers.environment)] = env;
        }

        public static void SetTimeSession(float timeSession)
        {
            _headersDic[GetHeaderName(Headers.time_session)] = (float)Math.Round(timeSession, 3);
        }

        public static void SetTimeSessionGameplay(float timeSessionGameplay)
        {
            _headersDic[GetHeaderName(Headers.time_session_gameplay)] = (float)Math.Round(timeSessionGameplay, 3);
        }

        public static void SetIsTrial(bool isTrial)
        {
            _headersDic[GetHeaderName(Headers.is_trial)] = isTrial;
        }

        public static void SetScreenResolution(int w, int h)
        {
            _headersDic[GetHeaderName(Headers.screen_resolution)] = string.Format("{0}x{1}", w, h);
        }

        private enum Headers
        {
            playfab_id,
            first_party,
            environment,
            time_session,
            time_session_gameplay,
            is_trial,
            screen_resolution
        }

        public void NavigateOnScreen(string navigationAction, Product product)
        {
            SetCurrentScreen(_screen, navigationAction, product);
        }

        public void SetCurrentScreen(string currentScreen, string navigationAction, Product product = null)
        {
            AnalyticsScreenDisplayItem item = new AnalyticsScreenDisplayItem(_headersDic);

            item.ScreenPrevious = _screen;
            _screen = currentScreen;
            item.ScreenCurrent = currentScreen;
            item.ScreenPreviousNavAction = navigationAction;
            item.ScreenCount = _screenCount++;
            item.Product = product;

            if (Context != null)
            {
                item.Context = Context;
                item.ScreenCountContext = _screenCountContext++;
            }

            item.TimeScreenPreviousSec = (float)Math.Round(Time.unscaledTime - _elapsedTime, 3);
            _elapsedTime = Time.unscaledTime;
            AsmoLogger.Debug(_debugModuleName, item.MetricName + " Event", new Hashtable(item.ToDictionary()));

            if (AnalyticsEvent != null)
            {
                EventManager.Instance.QueueEvent<AnalyticsItem>(AnalyticsEvent, item);
            }
        }

        public void TrackAdDisplay(AnalyticsAdDisplayItem.AdTypes adType, bool isSkippable, bool isSkipped, float duration)
        {
            AnalyticsAdDisplayItem item = new AnalyticsAdDisplayItem(_headersDic);

            item.AdType = adType;
            item.IsSkippable = isSkippable;
            item.IsSkipped = isSkipped;
            item.Time = duration;

            AsmoLogger.Debug(_debugModuleName, item.MetricName + " Event", new Hashtable(item.ToDictionary()));

            if (AnalyticsEvent != null)
            {
                EventManager.Instance.QueueEvent<AnalyticsItem>(AnalyticsEvent, item);
            }
        }
    }
}
