const instance = axios.create({
  baseURL: 'https://headless.tebex.io/api',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
});

async function checkTebexStoreBasket(tebexPublicKey, basketIdent) {
  if (basketIdent === null) return null;
  
  try {
    let basket = await instance.get(`/accounts/${tebexPublicKey}/baskets/${basketIdent}`);
    basket = basket.data;
    if (basket?.data === null || basket?.data === undefined) return null;
    if (basket.data?.complete) {
      let newBasket = await createTebexStoreBasket(tebexPublicKey, basket.data?.username);
      newBasket = newBasket.data;
      if (newBasket === null) return null;
      
      return newBasket;
    }
    
    return basket.data;
  } catch (e) {
    // Clear basket ident
    Cookies.remove('tebexStoreBasketIdent');
    window.location.reload();
    
    return null;
  }
}

async function createTebexStoreBasket(tebexPublicKey, username) {
  try {
    if (username === null || username === undefined || username === "") return null;
    
    let createBasketResponse = await instance.post(`/accounts/${tebexPublicKey}/baskets`, {
      username: username,
      complete_url: tebexCompleteUrl,
      cancel_url: tebexCancelUrl,
      complete_auto_redirect: true
    });
    createBasketResponse = createBasketResponse.data;
    
    if (createBasketResponse?.data === null || createBasketResponse?.data === undefined || createBasketResponse?.data?.ident === null || createBasketResponse?.data?.ident === undefined) {
      return null;
    }
    
    const basketIdent = createBasketResponse.data.ident;
    
    // Save to cookie
    Cookies.set('tebexStoreBasketIdent', basketIdent);
    
    return createBasketResponse.data;
  } catch (e) {
    console.log(e);
    return null;
  }
}

function tebexStore(tebexPublicKey, tierTables = null, categoryID = null, productID = null, type = 'modal') {
  return {
    tebexPublicKey: tebexPublicKey,
    basketIdent: null,
    username: null,
    isStoreLoading: true,
    isCategoriesLoading: true,
    isCategoryLoading: true,
    isProductLoading: true,
    isHomepage: true,
    isProductPage: false,
    store: null,
    categoryListing: [],
    categories: [],
    products: [],
    categoryData: null,
    productData: null,
    tierTables: tierTables,
    tierTable: null,
    cartCount: 0,
    init() {
      if (categoryID !== null) this.isHomepage = false;
      if (productID !== null) this.isProductPage = true;
      
      // Get basket ident from cookie
      if (Cookies.get('tebexStoreBasketIdent') !== undefined) {
        this.basketIdent = Cookies.get('tebexStoreBasketIdent');
      }
      
      // Fetch basket if basketIdent is not null
      checkTebexStoreBasket(this.tebexPublicKey, this.basketIdent).then(basket => {
        if (basket !== null) {
          this.basketIdent = basket.ident;
          this.username = basket.username;
          this.cartCount = basket.packages.length;
        }
      })
      
      if (categoryID !== null) {
        this.changeCategory(categoryID);
      }
      
      // Fetch Product if productID is not null
      if (productID !== null) {
        this.fetchProduct(productID);
      }
      
      // Fetch Categories
      this.fetchCategories();
      
      // Fetch Store Data
      this.fetchStore();
      
      if (!this.isHomepage && this.tierTables !== null && this.tierTables.length > 0 && this.tierTables.find(t => t.categoryID == categoryID) !== undefined) {
        this.tierTable = this.tierTables.find(t => t.categoryID == categoryID);
      }
    },
    logout() {
      this.basketIdent = null;
      this.username = null;
      this.cartCount = 0;
      Cookies.remove('tebexStoreBasketIdent');
      window.location.href = "/store";
    },
    fetchStore() {
      this.isStoreLoading = true;
      instance.get(`/accounts/${this.tebexPublicKey}`).then(r => r.data).then(r => {
        this.store = r.data;
        this.isStoreLoading = false;
      });
    },
    fetchCategories() {
      this.isCategoriesLoading = true;
      
      let url = `/accounts/${this.tebexPublicKey}/categories`;
      if (this.basketIdent !== null && this.basketIdent !== undefined && this.basketIdent !== "") {
        url += `?basketIdent=${this.basketIdent}`;
      }
      
      instance.get(url).then(r => r.data).then(r => {
        this.isCategoriesLoading = false;
        this.categories = r.data;
        
        // Create category listing
        let categoryListing = [];
        this.categories.forEach(category => {
          if (category.parent === null) {
            if (categoryListing.find(c => c.id === category.id) === undefined) {
              categoryListing.push({
                ...category,
                subcategories: []
              });
            }
          } else {
            const parent = categoryListing.find(c => c.id === category.parent.id);
            if (parent === undefined) {
              categoryListing.push({
                ...category.parent,
                subcategories: [category]
              });
            } else {
              if (parent.subcategories === undefined) parent.subcategories = [];
              parent.subcategories.push(category);
            }
          }
        });
        this.categoryListing = categoryListing;
      });
    },
    changeCategory(categoryID) {
      this.isHomepage = false;
      this.tierTable = null;
      const categoryDataBackup = this.categoryData;
      this.categoryData = {
        id: categoryID
      };
      if (categoryID !== null) {
        if (!this.isHomepage && this.tierTables !== null && this.tierTables.length > 0 && this.tierTables.find(t => t.categoryID == categoryID) !== undefined) {
          this.tierTable = this.tierTables.find(t => t.categoryID == categoryID);
        }

        this.isCategoryLoading = true;
        let url = `/accounts/${this.tebexPublicKey}/categories/${categoryID}?includePackages=1`;
        if (this.basketIdent !== null && this.basketIdent !== undefined && this.basketIdent !== "") {
          url += `&basketIdent=${this.basketIdent}`;
        }
        
        instance.get(url).then(r => r.data).then(r => {
          if (r.data === null) {
            this.categoryData = categoryDataBackup;
            this.isCategoryLoading = false;
            return;
          }
          this.categoryData = r.data;
          
          if (this.categoryData !== null) {
            history.pushState({}, null, `/store/${this.categoryData.id}`);
            this.products = this.categoryData.packages;
          }

          const tiersData = this.tierTable.tiers.map(id => Number(id));
          const sortedTiers = this.products.map(product => product.id).filter(id => tiersData.includes(id));
          this.tierTable.tiers = sortedTiers.map(id => String(id));
          
          this.isCategoryLoading = false;
        }).catch(e => {
          this.categoryData = categoryDataBackup;
          this.isCategoryLoading = false;
        });
      }
    },
    fetchProduct(productID) {
      this.isProductLoading = true;
      let url = `/accounts/${this.tebexPublicKey}/packages/${productID}`;
      if (this.basketIdent !== null && this.basketIdent !== undefined && this.basketIdent !== "") {
        url += `?basketIdent=${this.basketIdent}`;
      }
      instance.get(url).then(r => r.data).then(r => {
        this.productData = r.data;
        this.isProductLoading = false;
      }).catch(e => {
        this.productData = null;
        this.isProductLoading = false;
      });
    },
    showProduct(product) {
      this.productData = product;
      if (type === 'page') {
        // scroll top
        window.scrollTo(0, 0);
        
        this.isProductPage = true;
        history.pushState({}, null, `/store/products/${product.id}`);
      }
    }
  }
}

function tebexStoreCart(tebexPublicKey) {
  return {
    tebexPublicKey: tebexPublicKey,
    username: null,
    isLoading: true,
    isCouponLoading: false,
    basketIdent: null,
    basket: null,
    packages: [],
    coupons: [],
    giftCards: [],
    total: null,
    currency: null,
    checkoutLink: null,
    productData: null,
    code: "",
    cartCount: 0,
    init() {
      // Get basket ident from cookie
      if (Cookies.get('tebexStoreBasketIdent') !== undefined) {
        this.basketIdent = Cookies.get('tebexStoreBasketIdent');
      }
      
      // Fetch basket
      this.fetchBasket();
    },
    fetchBasket() {
      this.isLoading = true;
      
      if (this.basketIdent === null || this.basketIdent === undefined || this.basketIdent === "") {
        this.isLoading = false;
        return;
      }
      
      checkTebexStoreBasket(this.tebexPublicKey, this.basketIdent).then(basket => {
        this.isLoading = false;
        if (basket !== null) {
          this.setValues(basket);
        }
      });
    },
    redeemCode() {
      const giftCardRegex = /^(\d{4}\s?){4}$/;
      const isGiftCard = giftCardRegex.test(this.code);
      
      this.isCouponLoading = true;
      if (isGiftCard) {
        this.applyGiftCard(this.code);
      } else {
        this.applyCoupon(this.code);
      }
    },
    applyCoupon(code) {
      instance.post(`/accounts/${this.tebexPublicKey}/baskets/${this.basketIdent}/coupons`, {
        coupon_code: code
      }).then(r => r.data).then(r => {
        console.log(r);
        if (r?.success) {
          window.location.reload();
        }
      }).catch(e => {
        this.$refs.couponMessage.innerHTML = e.response.data?.detail;
        this.isCouponLoading = false;
      });
    },
    applyGiftCard(code) {
      instance.post(`/accounts/${this.tebexPublicKey}/baskets/${this.basketIdent}/giftcards`, {
        card_number: code
      }).then(r => r.data).then(r => {
        console.log(r);
        if (r?.success) {
          window.location.reload();
        }
      }).catch(e => {
        this.$refs.couponMessage.innerHTML = e.response.data?.detail;
        this.isCouponLoading = false;
      });
    },
    removeCoupon(code) {
      instance.post(`/accounts/${this.tebexPublicKey}/baskets/${this.basketIdent}/coupons/remove`, {
        coupon_code: code
      }).then(r => r.data).then(r => {
        if (r?.success) {
          window.location.reload();
        }
      });
    },
    removeGiftCard(code) {
      instance.post(`/accounts/${this.tebexPublicKey}/baskets/${this.basketIdent}/giftcards/remove`, {
        card_number: code
      }).then(r => r.data).then(r => {
        if (r?.success) {
          window.location.reload();
        }
      });
    },
    checkout() {
      Tebex.checkout.init({
        ident: this.basketIdent,
        theme: "auto"
      });
      Tebex.checkout.launch();
    },
    logout() {
      this.basketIdent = null;
      this.username = null;
      this.cartCount = 0;
      Cookies.remove('tebexStoreBasketIdent');
      window.location.href = "/store";
    },
    setValues(basket) {
      //console.log(basket)
      this.basketIdent = basket.ident;
      this.username = basket.username;
      this.basket = basket;
      this.packages = basket.packages;
      this.coupons = basket.coupons;
      this.giftCards = basket.giftcards;
      this.total = basket.total_price;
      this.currency = basket.currency;
      this.checkoutLink = basket.links.checkout;
      this.cartCount = basket.packages.length;
      
      this.$nextTick(function() {
        var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
        var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
          return new bootstrap.Tooltip(tooltipTriggerEl)
        })
      });
    }
  }
}

function tebexStoreCartItem(product) {
  return {
    product: product,
    quantity: product.in_basket.quantity,
    isQuantityLoading: false,
    isRemoving: false,
    isProductLoading: false,
    increaseQuantity() {
      this.updateQuantity(this.quantity + 1);
    },
    decreaseQuantity() {
      this.updateQuantity(this.quantity - 1);
    },
    updateQuantity(quantity) {
      if (quantity < 1) return;
      
      this.isQuantityLoading = true;
      instance.put(`/baskets/${this.basketIdent}/packages/${product.id}`, {
        quantity: quantity
      }).then(r => r.data).then(r => {
        this.setValues(r.data);
        this.quantity = quantity;
        this.isQuantityLoading = false;
      }).catch(e => {
        swal.fire({
          title: e.response.data.title,
          text: e.response.data.detail,
          type: "error",
          confirmButtonColor: "#02b875",
          confirmButtonText: lang.alert_btn_ok
        });
        this.isQuantityLoading = false;
      });
    },
    removeItem() {
      this.isRemoving = true;
      instance.post(`/baskets/${this.basketIdent}/packages/remove`, {
        package_id: product.id
      }).then(r => r.data).then(r => {
        this.setValues(r.data);
        this.isRemoving = false;
      }).catch(e => {
        swal.fire({
          title: e.response.data.title,
          text: e.response.data.detail,
          type: "error",
          confirmButtonColor: "#02b875",
          confirmButtonText: lang.alert_btn_ok
        });
      });
    },
    openModal(productID) {
      this.isProductLoading = true;
      instance.get(`/accounts/${this.tebexPublicKey}/packages/${productID}?basketIdent=${this.basketIdent}`).then(r => r.data).then(r => {
        this.productData = r.data;
        this.isProductLoading = false;
      });
    },
  }
}

function tebexStoreProductUI(product, type = 'modal') {
  return {
    modal: null,
    type: type,
    product: product,
    showGift: false,
    giftTarget: null,
    buttonLoading: false,
    init() {
      if (this.type === 'modal') {
        this.modal = $("#buyModal");
        this.modal.modal("show");
        this.modal.on("hidden.bs.modal", () => {
          this.productData = null;
        });
      }
    },
    toggleGift() {
      this.showGift = !this.showGift;
    },
    addToCart() {
      if (this.basketIdent === null) {
        window.location.href = '/store/login?addCart=' + this.product.id;
        return;
      }
      
      this.buttonLoading = true;
      instance.post(`/baskets/${this.basketIdent}/packages`, {
        package_id: this.product.id,
        type: this.product.type === "both" ? 'single' : this.product.type,
        //target_username: this.giftTarget
      }).then(r => {
        this.buttonLoading = false;
        if (this.giftTarget !== null && r?.status === 400) {
          swal.fire({
            title: lang.alert_title_error,
            text: lang.player_not_found,
            type: "error",
            confirmButtonColor: "#02b875",
            confirmButtonText: lang.alert_btn_ok
          }).then(function() {
            if (this.type === 'modal') {
              this.modal.modal("hide");
            }
          });
        }
        else {
          window.location = '/cart';
        }
      }).catch(e => {
        this.buttonLoading = false;
        swal.fire({
          title: e.response.data.title,
          text: e.response.data.detail,
          type: "error",
          confirmButtonColor: "#02b875",
          confirmButtonText: lang.alert_btn_ok
        }).then(function() {
          if (this.type === 'modal') {
            this.modal.modal("hide");
          }
        });
      });
    }
  }
}

function tebexStoreLogin(tebexPublicKey, product = null) {
  return {
    product: product,
    usernameModel: '',
    isLoading: false,
    giftTarget: null,
    login() {
      if (this.usernameModel === null || this.usernameModel === "") return null;
      
      this.isLoading = true;
      
      // Create Basket
      instance.post(`/accounts/${tebexPublicKey}/baskets`, {
        username: this.usernameModel,
        complete_url: tebexCompleteUrl,
        cancel_url: tebexCancelUrl,
        complete_auto_redirect: true
      }).then(createBasketResponse => {
        if (createBasketResponse.data?.data === null || createBasketResponse.data?.data === undefined || createBasketResponse.data?.data?.ident === null || createBasketResponse.data?.data?.ident === undefined) {
          swal.fire({
            title: lang.alert_title_error,
            text: "An error occurred while creating the basket.",
            type: "error",
            confirmButtonColor: "#02b875",
            confirmButtonText: lang.alert_btn_ok
          });
          this.isLoading = false;
          return;
        }
        const basketIdent = createBasketResponse.data.data.ident;
        
        // Save to cookie
        Cookies.set('tebexStoreBasketIdent', basketIdent);
        
        // If product is not null, add product to cart
        if (this.product !== null) {
          // Fetch product
          instance.get('/accounts/' + tebexPublicKey + '/packages/' + product).then(productResponse => {
            this.product = productResponse.data.data;
            
            // Add product to cart
            instance.post(`/baskets/${basketIdent}/packages`, {
              package_id: this.product.id,
              type: this.product.type === "both" ? 'single' : this.product.type,
              //target_username: this.giftTarget
            }).then(basketResponse => {
              if (this.giftTarget !== null && basketResponse?.status === 400) {
                swal.fire({
                  title: lang.alert_title_error,
                  text: lang.player_not_found,
                  type: "error",
                  confirmButtonColor: "#02b875",
                  confirmButtonText: lang.alert_btn_ok
                }).then(function() {
                  window.location.href = "/store";
                });
              }
              else {
                // Everything is successful, redirect to cart
                window.location.href = '/cart';
              }
            }).catch(e => {
              console.log(e)
              swal.fire({
                title: e.response.data.title,
                text: e.response.data.detail,
                type: "error",
                confirmButtonColor: "#02b875",
                confirmButtonText: lang.alert_btn_ok
              }).then(function() {
                window.location.href = "/store";
              });
            });
          }).catch(e => {
            console.log(e)
            swal.fire({
              title: e.response.data.title,
              text: e.response.data.detail,
              type: "error",
              confirmButtonColor: "#02b875",
              confirmButtonText: lang.alert_btn_ok
            }).then(function() {
              window.location.href = "/store";
            });
          });
        } else {
          window.location.href = "/store";
        }
      }).catch(e => {
        console.log(e)
        swal.fire({
          title: e.response.data.title,
          text: e.response.data.detail,
          type: "error",
          confirmButtonColor: "#02b875",
          confirmButtonText: lang.alert_btn_ok
        });
        this.isLoading = false;
      });
    }
  }
}

function tebexStoreExternalLogin(tebexPublicKey, callbackUrl, product = null) {
  return {
    product: product,
    isLoading: false,
    giftTarget: null,
    login() {
      this.isLoading = true;
      
      // Create Basket
      instance.post(`/accounts/${tebexPublicKey}/baskets`, {
        complete_url: tebexCompleteUrl,
        cancel_url: tebexCancelUrl,
        complete_auto_redirect: true
      }).then(createBasketResponse => {
        if (createBasketResponse.data?.data === null || createBasketResponse.data?.data === undefined || createBasketResponse.data?.data?.ident === null || createBasketResponse.data?.data?.ident === undefined) {
          swal.fire({
            title: lang.alert_title_error,
            text: "An error occurred while creating the basket.",
            type: "error",
            confirmButtonColor: "#02b875",
            confirmButtonText: lang.alert_btn_ok
          });
          this.isLoading = false;
          return;
        }
        const basketIdent = createBasketResponse.data.data.ident;
        
        // Gert Auth Link
        let redirectUrl = `${callbackUrl}?basket=${basketIdent}`;
        if (this.product !== null) {
         redirectUrl += `&package=${this.product}`;
        }
        redirectUrl = encodeURIComponent(redirectUrl);
        
        instance.get(`/accounts/${tebexPublicKey}/baskets/${basketIdent}/auth?returnUrl=${redirectUrl}`).then(authLResponse => {
          window.location.href = authLResponse.data[0].url;
        }).catch(e => {
          console.log(e)
          swal.fire({
            title: e.response.data.title,
            text: e.response.data.detail,
            type: "error",
            confirmButtonColor: "#02b875",
            confirmButtonText: lang.alert_btn_ok
          });
          this.isLoading = false;
        });
      }).catch(e => {
        console.log(e)
        swal.fire({
          title: e.response.data.title,
          text: e.response.data.detail,
          type: "error",
          confirmButtonColor: "#02b875",
          confirmButtonText: lang.alert_btn_ok
        });
        this.isLoading = false;
      });
    }
  }
}

function tebexStoreMoney(price, currency) {
  return price.toFixed(2) + " " + currency;
}