﻿using System;
using System.Collections;
using System.Collections.Generic;
#if UNITY_IOS && !UNITY_EDITOR
using System.Runtime.InteropServices;
#endif
using UnityEngine;

public class WortiseRewarded
{
    #if UNITY_ANDROID && !UNITY_EDITOR
    private static AndroidJavaObject activity
    {
        get
        {
            return WortiseSdk.activity;
        }
    }
    
    private AndroidJavaObject rewardedAd;
    #endif

    #if UNITY_IOS && !UNITY_EDITOR
    public static Dictionary<int, WortiseRewarded> instances = new Dictionary<int, WortiseRewarded>();

    private static int lastId = 1;

    private int id;
    #endif
            
    public bool IsAvailable
    {
        get
        {
            #if UNITY_ANDROID && !UNITY_EDITOR
            return rewardedAd.Call<bool>("isAvailable");
            #elif UNITY_IOS && !UNITY_EDITOR
            return Wortise_Rewarded_IsAvailable(id);
            #else
            return false;
            #endif
        }
    }
    
    public bool IsDestroyed
    {
        get
        {
            #if UNITY_ANDROID && !UNITY_EDITOR
            return rewardedAd.Call<bool>("isDestroyed");
            #elif UNITY_IOS && !UNITY_EDITOR
            return Wortise_Rewarded_IsDestroyed(id);
            #else
            return false;
            #endif
        }
    }

    public bool IsShowing
    {
        get
        {
            #if UNITY_ANDROID && !UNITY_EDITOR
            return rewardedAd.Call<bool>("isShowing");
            #elif UNITY_IOS && !UNITY_EDITOR
            return Wortise_Rewarded_IsShowing(id);
            #else
            return false;
            #endif
        }
    }
    
    public event Action OnClicked;
    public event Action<WortiseReward> OnCompleted;
    public event Action OnDismissed;
    public event Action OnFailedToLoad;
    public event Action OnFailedToShow;
    public event Action OnImpression;
    public event Action OnLoaded;
    public event Action<WortiseRevenueData> OnRevenuePaid;
    public event Action OnShown;

    
    public WortiseRewarded(string adUnitId)
    {
        #if UNITY_ANDROID && !UNITY_EDITOR
        rewardedAd = new AndroidJavaObject("com.wortise.ads.rewarded.RewardedAd", activity, adUnitId);
        rewardedAd.Call("setListener", new RewardedAdListener(this));
        #elif UNITY_IOS && !UNITY_EDITOR
        id = lastId++;

        instances.Add(id, this);

        Wortise_Rewarded_Create(id, adUnitId);
        #endif
    }

    public void Destroy()
    {
        #if UNITY_ANDROID && !UNITY_EDITOR
        rewardedAd.Call("destroy");
        #elif UNITY_IOS && !UNITY_EDITOR
        Wortise_Rewarded_Destroy(id);

        instances.Remove(id);
        #endif
    }
    
    public void LoadAd()
    {
        #if UNITY_ANDROID && !UNITY_EDITOR
        rewardedAd.Call("loadAd");
        #elif UNITY_IOS && !UNITY_EDITOR
        Wortise_Rewarded_LoadAd(id);
        #endif
    }
    
    public void ShowAd()
    {
        #if UNITY_ANDROID && !UNITY_EDITOR
        if (activity != null)
        {
            rewardedAd.Call("showAd", activity);
        }
        #elif UNITY_IOS && !UNITY_EDITOR
        Wortise_Rewarded_ShowAd(id);
        #endif
    }


    internal void OnAdClicked()
    {
        WortiseSdk.RaiseAction(OnClicked);
    }

    internal void OnAdCompleted(WortiseReward reward)
    {
        WortiseSdk.RaiseAction(() =>
        {
            OnCompleted?.Invoke(reward);
        });
    }

    internal void OnAdDismissed()
    {
        WortiseSdk.RaiseAction(OnDismissed);
    }

    internal void OnAdFailedToLoad()
    {
        WortiseSdk.RaiseAction(OnFailedToLoad);
    }

    internal void OnAdFailedToShow()
    {
        WortiseSdk.RaiseAction(OnFailedToShow);
    }

    internal void OnAdImpression()
    {
        WortiseSdk.RaiseAction(OnImpression);
    }

    internal void OnAdLoaded()
    {
        WortiseSdk.RaiseAction(OnLoaded);
    }

    internal void OnAdRevenuePaid(WortiseRevenueData data)
    {
        WortiseSdk.RaiseAction(() =>
        {
            OnRevenuePaid?.Invoke(data);
        });
    }

    internal void OnAdShown()
    {
        WortiseSdk.RaiseAction(OnShown);
    }
    
    
    #if UNITY_ANDROID && !UNITY_EDITOR
    class RewardedAdListener : AndroidJavaProxy
    {
        private WortiseRewarded rewardedAd;


        public RewardedAdListener(WortiseRewarded rewardedAd) : base("com.wortise.ads.rewarded.RewardedAd$Listener")
        {
            this.rewardedAd = rewardedAd;
        }
        
        public void onRewardedClicked(AndroidJavaObject ad)
        {
            rewardedAd.OnAdClicked();
        }

        public void onRewardedCompleted(AndroidJavaObject ad, AndroidJavaObject reward)
        {
            if (reward == null)
            {
                return;
            }

            WortiseReward r = WortiseReward.FromAndroidJavaObject(reward);

            rewardedAd.OnAdCompleted(r);
        }

        public void onRewardedDismissed(AndroidJavaObject ad)
        {
            rewardedAd.OnAdDismissed();
        }

        public void onRewardedFailedToLoad(AndroidJavaObject ad, AndroidJavaObject error)
        {
            rewardedAd.OnAdFailedToLoad();
        }

        public void onRewardedFailedToShow(AndroidJavaObject ad, AndroidJavaObject error)
        {
            rewardedAd.OnAdFailedToShow();
        }

        public void onRewardedImpression(AndroidJavaObject ad)
        {
            rewardedAd.OnAdImpression();
        }

        public void onRewardedLoaded(AndroidJavaObject ad)
        {
            rewardedAd.OnAdLoaded();
        }

        public void onRewardedRevenuePaid(AndroidJavaObject ad, AndroidJavaObject data)
        {
            WortiseRevenueData revenue = WortiseRevenueData.FromAndroidJavaObject(data);

            if (revenue == null)
            {
                return;
            }

            rewardedAd.OnAdRevenuePaid(revenue);
        }

        public void onRewardedShown(AndroidJavaObject ad)
        {
            rewardedAd.OnAdShown();
        }
    }
    #endif

    #if UNITY_IOS && !UNITY_EDITOR
    [DllImport("__Internal")]
    private static extern void Wortise_Rewarded_Create(int id, String adUnitId);

    [DllImport("__Internal")]
    private static extern void Wortise_Rewarded_Destroy(int id);

    [DllImport("__Internal")]
    private static extern bool Wortise_Rewarded_IsAvailable(int id);

    [DllImport("__Internal")]
    private static extern bool Wortise_Rewarded_IsDestroyed(int id);

    [DllImport("__Internal")]
    private static extern bool Wortise_Rewarded_IsShowing(int id);

    [DllImport("__Internal")]
    private static extern void Wortise_Rewarded_LoadAd(int id);

    [DllImport("__Internal")]
    private static extern void Wortise_Rewarded_ShowAd(int id);
    #endif
}
