﻿using UnityEngine;
using UnityEngine.UI;
using TentuPlay.Api;
using System.Collections.Generic;
using System.Linq;
using System;

namespace TentuPlay.CRM
{
    // THIS SCRIPT IS ATTACHED TO TentuPlayAIOffer
    public class TentuPlayAIOffer : MonoBehaviour
    {
        // WARNING: DON'T CHANGE FIELD NAMES
        public TPOfferCalculated thisOffer;
        private string thisPlayerUUID;
        private string thisLanguage;
        public bool is_dont_show_today_checked;

        [SerializeField]
        Toggle DoNotShowToday;

        string purchasable_slug;
        string product_index;
        string purchase_link;

        /// <summary>
        /// returns -1 if error occurred.
        /// </summary>
        /// <param name="my_offer"></param>
        /// <param name="player_id"></param>
        /// <param name="language"></param>
        /// <returns></returns>
        public int PlaceOffer(TPOfferCalculated my_offer, string player_id, string language)
        {
            thisPlayerUUID = player_id;
            thisOffer = my_offer;
            thisLanguage = language;

            /* NOTE FOR DEVELOPERS:
             * This method(PlaceOffer) operates before the AI In-Game Shop message is shown on screen.
             * Before an AI In-Game Shop message generated by TentuPlay AI is shown, it must retrieve the recommended product and related information.
             * PlaceOffer operates through the following 4 stages to retrievel product related information, 
             * and during this process if an error occurs, it will return -1 and must be made so that a message does not appear.
             * 
             * 
             * 1) Retrive the players' store string. 
             * The store string should be identical to that of the 'store' column in the csv file uploaded through TentuPlay console.  
             * The GetRecommendedProduct by using the store string parses the products that matches the player's store from the recommended products. 
             * The default value of store is "ios" in the demo game.
             */
            string store = "ios";

            TPPersonalizedOffer myPerOffer = new TPPersonalizedOffer();
            RecommendedProduct myProduct = null;
            List<RecommendedProduct> recommendedProducts = myPerOffer.GetRecommendedProduct(thisOffer);

            // Similar to LoadOffer() in TentuPlayCRMPlayerController
            foreach (RecommendedProduct recommendedProduct in recommendedProducts)
            {
                if (store == recommendedProduct.store) // Found recommended product for player's store.
                {
                    /* Check if recommended products are on sale.
                     * INFO: start_datetime, end_datetime, product_index, purchase_link, and store in recommendedProduct 
                     *       are identical to that of the each column in the csv file uploaded through TentuPlay console. 
                     */
                    if (recommendedProduct.is_in_sale_now)
                    {
                        // (optional) min_end_datetime is the expire datetime considering both offer expire datetime and product expire datetime.
                        List<DateTime?> cs = new List<DateTime?> { recommendedProduct.end_datetime, my_offer.offer_expires_in };
                        DateTime? min_end_datetime = cs.Where(item => item != null).Min();

                        myProduct = recommendedProduct;
                    }
                    break;
                }
                // Pass if no matching 'store' was found.
            }

            if (myProduct == null) // No product found for the store.
            return -1;

            purchasable_slug = myProduct.purchasable_slug;
            product_index = myProduct.product_index;


            /* 2) Second, the purchase_link of the product that TentuPlay AI recommends must be called.
             * If the csv file uploaded on the TentuPlay console > AI In-Game Shop > Shop/Operation > Setting/Management > Upload Information tab has action links in the purchase_link column,
             * the TentuPlay SDK can retrieve the recommended product’s purchase_link via the GetRecommendedProduct method and recommendedProduct class through the following way.
             */
            purchase_link = myProduct.purchase_link;

            /* If, in the csv file, the purchase_link column was not filled with an action link, 
             * the recommended item's purchase_link must be retrieved via the product's product_index or purchasable_slug.
             * You can retrieve the purchase_link of a product via its product_index or purchasable_slug as in the example below
             */
            // purchase_link = getProductUrl(purchasable_slug); // a custom method to retrieve a product's purchase_link


            /* 3) The Sprite and price of the product recommended by TentuPlay's AI must be retrieved.
             * You can retrieve a product's Sprite and price via the product's product_index or purchasable_slug as in the example below.
            */
            ProductInfoDemo productInfo = GetProductInfoDemo(purchasable_slug); // a custom method to retrieve a product's Sprite, price(string)
            Sprite sprite = productInfo.sprite;
            string price = productInfo.price;

            /*
             * 4) The messages sent via the AI In-Game Shop must be checked for validity before sending.
             * For example, if a product recommended via an AI In-Game Shop message has a number of purchase limit, 
             * it must be checked if a player can purchase the product.
             * If a player has already reached the purchase limit of the recommended product and cannot purchase any more of said product, 
             * it must be set to return -1 and not show a message to the player.
             * 
             * An example you can reference is noted below. 
             * Most game developers will have internal logic to check a message's validity before sending, 
             * and we recommend applying this in-game internal logic to messages being sent by the AI In-Game Shop.
            
                bool val = validateproduct(player_id, product_index); // a custom method to retrieve a product's validity
                if (!val)
                    return -1;
             */

            int r = myPerOffer.SetProduct(gameObject, sprite, price);
            if (r < 0)
                return -1;

            TPStashEvent myStashEvent = new TPStashEvent();
            myStashEvent.StashOfferEvent(player_uuid: player_id, offer_id: thisOffer.offer_id, message_status: messageStatus.Open, message_detail: purchasable_slug);

            myPerOffer.OfferOpened(thisOffer.offer_id, (response) =>
            {
            });

            // Default is false.
            // Or you can set the default value as saved value(thisOffer.checked_dont_show_today)
            is_dont_show_today_checked = false;
            try
            {
                gameObject.GetComponent<MessageController>().Show();
            }
            catch
            {
                return -1;
            }

            return 1;
        }


        public void GoToOfferEvent()
        {
            // Go to purchase_link
            Application.OpenURL(purchase_link);

            // USE THIS CODE WHEN TOGGLE IS 'DO NOT SHOW TODAY'
            if (is_dont_show_today_checked)
                new TPPersonalizedOffer().MarkDoNotShowToday(thisOffer.offer_id);
            else
                new TPPersonalizedOffer().UnmarkDoNotShowToday(thisOffer.offer_id);

            // Use OnCloseOfferEvent() to fully use AI offer.
            OnGoToOfferEvent();

#if USE_DEMO
            // Select(refresh) offer lists when offer is closed.
            // Use this code for ShingGoong demo game.
            TPPersonalizedOffer myPO = new TPPersonalizedOffer();
            foreach (GameObject go in Resources.FindObjectsOfTypeAll(typeof(GameObject)) as GameObject[])
            { 
                if (go.name == "Player")
                    go.GetComponent<TentuPlayCRMPlayerController>().myOffers = myPO.SelectOfferInfo(thisPlayerUUID, "en");
            }
            GameObject.Find("MailBoxOpen_offer").GetComponent<MailBoxOpen_offer>().ListOffers();
#endif
        }

        public void CloseOfferEvent()
        {
            // USE THIS CODE WHEN TOGGLE IS 'DO NOT SHOW TODAY'
            if (is_dont_show_today_checked)
                new TPPersonalizedOffer().MarkDoNotShowToday(thisOffer.offer_id);
            else
                new TPPersonalizedOffer().UnmarkDoNotShowToday(thisOffer.offer_id);

            // Use OnCloseOfferEvent() to fully use AI offer.
            OnCloseOfferEvent();

#if USE_DEMO
            // Select(refresh) offer lists when offer is closed.
            // Use this code for ShingGoong demo game.
            TPPersonalizedOffer myPO = new TPPersonalizedOffer();
            foreach (GameObject go in Resources.FindObjectsOfTypeAll(typeof(GameObject)) as GameObject[])
            { 
                if (go.name == "Player")
                    go.GetComponent<TentuPlayCRMPlayerController>().myOffers = myPO.SelectOfferInfo(thisPlayerUUID, "en");
            }
            GameObject.Find("MailBoxOpen_offer").GetComponent<MailBoxOpen_offer>().ListOffers();
#endif
        }

        public void CheckDoNotShowToday()
        {
            if (DoNotShowToday.isOn)
                is_dont_show_today_checked = true;
            else
                is_dont_show_today_checked = false;
        }

        protected virtual void OnGoToOfferEvent()
        {
            // Log the Offer interact event
            int r = new TPStashEvent().StashOfferEvent(
                player_uuid: thisPlayerUUID, offer_id: thisOffer.offer_id, message_status: messageStatus.Interact, message_detail: purchasable_slug);
            new TPUploadData().UploadData(toCheckInterval: false);

            gameObject.GetComponent<MessageController>().Close();
        }

        protected virtual void OnCloseOfferEvent()
        {
            // Log the Offer close event
            int r = new TPStashEvent().StashOfferEvent(
                player_uuid: thisPlayerUUID, offer_id: thisOffer.offer_id, message_status: messageStatus.Dismiss, message_detail: purchasable_slug);
            new TPUploadData().UploadData(toCheckInterval: false);

            gameObject.GetComponent<MessageController>().Close();
        }

        // THIS IS A SAMPLE METHOD FOR TENTUPLAY DEMO GAME
        private ProductInfoDemo GetProductInfoDemo(string purchasable_slug)
        {
            ProductInfoDemo recommendedProduct = new ProductInfoDemo
            {
                sprite = Resources.Load<Sprite>("Sprites/Item/" + purchasable_slug),
                price = "$0.00"
            };
            return recommendedProduct;
        }
    }

    // THIS IS A SAMPLE CLASS FOR TENTUPLAY DEMO GAME
    public class ProductInfoDemo
    {
        public Sprite sprite;
        public string price;
    }
}
