using System;
using System.Threading.Tasks;
using UnityEngine;
using Arkadium;
using Arkadium.Interop;

namespace Arkadium.Examples
{
    /// <summary>
    /// Example demonstrating the new provider pattern for better separation of concerns
    /// </summary>
    public class ProviderExample : MonoBehaviour
    {
        private ArkadiumWalletV2 _wallet;
        private ArkadiumTournaments _tournaments;

        void Start()
        {
            _wallet = new ArkadiumWalletV2();
            _tournaments = new ArkadiumTournaments();

            // Example 1: Using default provider (auto-selected based on environment)
            _ = DemonstrateDefaultProvider();

            // Example 2: Using custom provider for testing
            _ = DemonstrateCustomProvider();
        }

        /// <summary>
        /// Example using the default provider (auto-selected)
        /// </summary>
        private async Task DemonstrateDefaultProvider()
        {
            Debug.Log("=== Default Provider Example ===");

            try
            {
                // The provider is automatically selected:
                // - MockWebGLInteropProvider in Unity Editor
                // - WebGLInteropProvider in WebGL builds

                var isSupported = await _wallet.IsGemsSupportedAsync();
                Debug.Log($"Gems supported (default provider): {isSupported}");

                var gems = await _wallet.GetGemsAsync();
                Debug.Log($"Gems count (default provider): {gems}");

                var tournaments = await _tournaments.GetTournamentsAsync();
                Debug.Log($"Tournaments found (default provider): {tournaments.Length}");
            }
            catch (Exception ex)
            {
                Debug.LogError($"Error in default provider example: {ex.Message}");
            }
        }

        /// <summary>
        /// Example using a custom provider for testing
        /// </summary>
        private async Task DemonstrateCustomProvider()
        {
            Debug.Log("=== Custom Provider Example ===");

            try
            {
                // Create a custom mock provider for testing
                var customProvider = new CustomTestProvider();

                // Set it as the current provider
                WebGLInteropFactory.SetProvider(customProvider);

                // Now all calls will use the custom provider
                var isSupported = await _wallet.IsGemsSupportedAsync();
                Debug.Log($"Gems supported (custom provider): {isSupported}");

                var gems = await _wallet.GetGemsAsync();
                Debug.Log($"Gems count (custom provider): {gems}");

                // Reset to default provider
                WebGLInteropFactory.ResetProvider();

                // Now back to default behavior
                var defaultGems = await _wallet.GetGemsAsync();
                Debug.Log($"Gems count (back to default): {defaultGems}");
            }
            catch (Exception ex)
            {
                Debug.LogError($"Error in custom provider example: {ex.Message}");
            }
        }

        /// <summary>
        /// Example showing how to test different scenarios
        /// </summary>
        public async void OnTestDifferentScenarios()
        {
            Debug.Log("=== Testing Different Scenarios ===");

            // Test scenario 1: User has no gems
            var noGemsProvider = new CustomTestProvider();
            noGemsProvider.SetMockGems(0);
            WebGLInteropFactory.SetProvider(noGemsProvider);

            var gems = await _wallet.GetGemsAsync();
            Debug.Log($"Scenario 1 - No gems: {gems}");

            // Test scenario 2: User has lots of gems
            var richProvider = new CustomTestProvider();
            richProvider.SetMockGems(50000);
            WebGLInteropFactory.SetProvider(richProvider);

            gems = await _wallet.GetGemsAsync();
            Debug.Log($"Scenario 2 - Rich user: {gems}");

            // Reset to default
            WebGLInteropFactory.ResetProvider();
        }

        // UI Button handlers
        public void OnTestDefaultProvider()
        {
            _ = DemonstrateDefaultProvider();
        }

        public void OnTestCustomProvider()
        {
            _ = DemonstrateCustomProvider();
        }
    }

    /// <summary>
    /// Custom test provider for demonstrating different scenarios
    /// </summary>
    public class CustomTestProvider : IWebGLInteropProvider
    {
        private int _mockGems = 1000;
        private bool _mockGemsSupported = true;

        public void SetMockGems(int gems)
        {
            _mockGems = gems;
        }

        public void SetMockGemsSupported(bool supported)
        {
            _mockGemsSupported = supported;
        }

        public async Task<T> InvokeAsync<T>(string methodName, object parameters = null)
        {
            await Task.Delay(10); // Simulate async behavior

            if (methodName == "wallet.isGemsSupported")
                return (T)(object)_mockGemsSupported;

            if (methodName == "wallet.getGems")
                return (T)(object)_mockGems;

            if (methodName == "wallet.consumeGems")
                return (T)(object)(_mockGems > 0);

            // Default fallback
            Debug.LogWarning($"[CustomProvider] Unknown method: {methodName}");
            return default(T);
        }

        public void InvokeVoid(string methodName, object parameters = null)
        {
            Debug.Log($"[CustomProvider] InvokeVoid: {methodName} with params: {JsonUtility.ToJson(parameters)}");
        }
    }
}