﻿using AsmodeeDigital.Common.Plugin.Manager.Coroutine;
using AsmodeeDigital.Common.Plugin.Network;
using AsmodeeDigital.CrossPromo.Plugin.Domain;
using AsmodeeDigital.CrossPromo.Plugin.Manager;
using AsmodeeDigital.CrossPromo.Plugin.View;
using System;

namespace AsmodeeDigital.CrossPromo.Plugin.Logic
{
    public class CrossPromoLogic : IDisposable
    {
        #region Events
        public event Action ConnectedEvent;
        public event Action DisconnectedEvent;
        public event Action<Product> ReceivingProductEvent;
        public event Action<GroupProduct> ReceivingGroupProductEvent;
        #endregion

        private RestAPI _restAPI;

        private AuthenticationTokens _authenticationTokens;
        public RestAPIConnectionStatus ConnectionStatus = RestAPIConnectionStatus.NotConnected;

        public CrossPromoLogic(RestAPI restAPI)
        {
            _restAPI = restAPI;
        }

        public void Init()
        {
            _restAPI.ConnectionSuccessEvent += RestAPI_ConnectionSuccessEvent;
            _restAPI.ReceivingProductEvent += RestAPI_ReceivingProductEvent;
            _restAPI.ReceivingGroupProductEvent += RestAPI_ReceivingGroupProductEvent;

            ToggleConnection();
        }

        #region Public method accessed by the view
        public void ToggleConnection()
        {
            switch (ConnectionStatus)
            {
                case RestAPIConnectionStatus.NotConnected:
                case RestAPIConnectionStatus.WaitingConnection:

                    Connect();
                    break;
                case RestAPIConnectionStatus.Connected:
                    Disconnect();
                    break;
                default:
                    break;
            }
        }

        public void Connect()
        {
            ConnectionStatus = RestAPIConnectionStatus.WaitingConnection;
            _restAPI.Connect();
        }

        public void Disconnect()
        {
            ConnectionStatus = RestAPIConnectionStatus.NotConnected;
            _authenticationTokens = null;

            if (DisconnectedEvent != null)
                DisconnectedEvent();
        }

        public void SetAuthenticationToken(AuthenticationTokens authenticationTokens)
        {
            _authenticationTokens = authenticationTokens;
        }

        public void BannerRequest()
        {
            CoroutineManager.StartCoroutine(CrossPromoCacheManager.LoadBanner(_restAPI, _authenticationTokens));
        }

        public void MoreGameRequest(MoreGamesFilters moreGamefilters)
        {
            CoroutineManager.StartCoroutine(CrossPromoCacheManager.LoadMoreGame(_restAPI, _authenticationTokens, CrossPromoView.Instance.NbColumns, moreGamefilters));
        }

        public void InterstitialRequest()
        {
            CoroutineManager.StartCoroutine(CrossPromoCacheManager.LoadInterstitial(_restAPI, _authenticationTokens, CrossPromoView.Instance.NbColumns));
        }
        #endregion

        #region REST API events
        private void RestAPI_ConnectionSuccessEvent(AuthenticationTokens authenticationTokens)
        {
            ConnectionStatus = RestAPIConnectionStatus.Connected;
            _authenticationTokens = authenticationTokens;

            if (ConnectedEvent != null)
                ConnectedEvent();
        }

        private void RestAPI_ReceivingProductEvent(Product product)
        {
            CrossPromoCacheManager.SaveBannerInCache(product, false, false);

            if (ReceivingProductEvent != null)
                ReceivingProductEvent(product);
        }

        private void RestAPI_ReceivingGroupProductEvent(GroupProduct groupProduct)
        {
            CrossPromoCacheManager.SaveGroupProductInCache(groupProduct, false);

            if (ReceivingGroupProductEvent != null)
                ReceivingGroupProductEvent(groupProduct);
        }
        #endregion

        public void Dispose()
        {
            _restAPI.ConnectionSuccessEvent -= RestAPI_ConnectionSuccessEvent;
            _restAPI.ReceivingProductEvent -= RestAPI_ReceivingProductEvent;
            _restAPI.ReceivingGroupProductEvent -= RestAPI_ReceivingGroupProductEvent;
        }

        public enum RestAPIConnectionStatus
        {
            NotConnected,
            WaitingConnection,
            Connected
        }
    }
}
