<template>
  <div class="product">
    <div class="container">
      <div class="product__wrapper">
        <div class="product__block">
          <div class="product__images">
            <div class="product__images-gallery">
              <div
                  v-for="(image, idx) in images"
                  :key="idx"
                  @click="selectImage(image)"
                  :class="[{ active: image === selectedImage }]"
              >
                <nuxt-img
                    :src="image"
                    :alt="product?.name"
                    format="webp"
                    densities="x1"
                />
              </div>
            </div>
            <nuxt-img
                :src="selectedImage"
                :alt="product?.name"
                class="product__images-main"
                format="webp"
                densities="x1"
            />
          </div>
          <div class="product__main">
            <p class="product__main-brand">{{ product?.brand.name }}</p>
            <h1 class="product__title">{{ product?.name }}</h1>
            <el-rate
                class="product__main-rate"
                :model-value="product?.rating"
                allow-half
                disabled
            />
            <p class="product__main-price">{{ product?.price }} $</p>
            <p class="product__main-stock">{{ t('cards.product.stock') }} {{ product?.quantity }}</p>
            <div class="product__main-description" v-html="product?.description" />
            <div class="tools" v-if="isProductInCart">
              <button
                  class="tools__item tools__item-button"
                  @click="overwriteOrder({
                    type: 'remove',
                    productUuid: product.uuid,
                    productName: product.name
                  })"
              >
                -
              </button>
              <span class="tools__item tools__item-count" v-text="'X' + productInCartQuantity" />
              <button
                  class="tools__item tools__item-button"
                  @click="overwriteOrder({
                    type: 'add',
                    productUuid: product.uuid,
                    productName: product.name
                  })"
              >
                +
              </button>
            </div>
            <ui-button
                v-else
                class="product__main-button"
                @click="overwriteOrder({
                  type: 'add',
                  productUuid: product.uuid,
                  productName: product.name
                })"
                :type="'button'"
                :isLoading="addLoading"
            >
              {{ t('buttons.addToCart') }}
            </ui-button>
            <div class="product__main-buttons">
              <ui-button
                  @click="overwriteWishlist({
                    type: (isProductInWishlist ? 'remove' : 'add'),
                    productUuid: product.uuid,
                    productName: product.name,
                })"
                  :type="'button'"
                  :style="'secondary'"
              >
                <icon name="mdi:cards-heart-outline" size="16" />
                {{ isProductInWishlist ? t('buttons.removeFromWishlist') : t('buttons.addToWishlist') }}
              </ui-button>
              <ui-button
                  :type="'button'"
                  :style="'secondary'"
                  @click="buyProduct(product.uuid)"
                  :isLoading="buyLoading"
              >
                {{ t('buttons.buyNow') }}
              </ui-button>
            </div>
          </div>
        </div>
      </div>
      <client-only>
        <div class="characteristics" id="characteristics" v-if="attributes.length">
          <h6 class="characteristics__title">{{ t('product.characteristics') }}</h6>
          <div class="characteristics__list">
            <div
                class="characteristics__column"
                v-for="group in attributes"
                :key="group.uuid"
            >
              <h6 class="characteristics__column-title">{{ group.name }}</h6>
              <p
                  class="characteristics__item"
                  v-for="item in group.items"
                  :key="item.uuid"
              >
                <span class="characteristics__item-label"><span>{{ item.name }}</span></span>
                <span class="characteristics__item-value">{{ item.valuesStr }}</span>
              </p>
            </div>
          </div>
        </div>
      </client-only>
      <div class="similar">
        <h6 class="similar__title">{{ t('product.similar') }}</h6>
        <div class="similar__inner">
          <div class="similar__button prev" ref="prevButton">
            <icon name="material-symbols:arrow-back-ios-new-rounded" size="30" />
          </div>
          <client-only>
            <swiper
                class="similar__swiper"
                :modules="[Navigation]"
                :spaceBetween="30"
                :breakpoints="{
                200: {
                  slidesPerView: 4
                }
              }"
                :navigation="{ prevEl: '.prev', nextEl: '.next' }"
            >
              <swiper-slide
                  v-for="prod in products"
                  :key="prod.node.uuid"
              >
                <cards-product
                    :product="prod.node"
                />
              </swiper-slide>
            </swiper>
          </client-only>
          <div class="similar__button next" ref="nextButton">
            <icon name="material-symbols:arrow-back-ios-new-rounded" size="30" />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {useProductBySlug, useProducts, useProductBuy} from '@composables/products';
import {usePageTitle} from '@composables/utils';
import {useScrollTo} from '@composables/scrollTo';
import { Swiper, SwiperSlide } from 'swiper/vue';
import {Navigation} from 'swiper/modules';
import {useWishlistOverwrite} from '@composables/wishlist';
import {useOrderOverwrite} from '@composables/orders';
import {useDefaultSeo} from '@composables/seo';

const route = useRoute();
const {t, locale} = useI18n();
const wishlistStore = useWishlistStore();
const cartStore = useCartStore();
const userStore = useUserStore();
const { $appHelpers } = useNuxtApp();

const { setPageTitle } = usePageTitle();
const { scrollTo } = useScrollTo();
const { buyProduct, loading: buyLoading } = useProductBuy();

const slug = useRouteParams<string>('slug');

const { overwriteWishlist } = useWishlistOverwrite();
const { addLoading, removeLoading, overwriteOrder } = useOrderOverwrite();
const { product, seoMeta } = await useProductBySlug(slug.value);

const cookieWishlist = useCookie($appHelpers.COOKIES_WISHLIST_KEY, {
  default: () => [],
  path: '/',
});
const cookieCart = useCookie($appHelpers.COOKIES_CART_KEY, {
  default: () => [],
  path: '/',
});

const isAuthenticated = computed(() => userStore.isAuthenticated);

const meta = useDefaultSeo(seoMeta.value || null);

if (meta) {
  useSeoMeta({
    title: meta.title || $appHelpers.APP_NAME,
    description: meta.description || meta.title || $appHelpers.APP_NAME,
    ogTitle: meta.og.title || undefined,
    ogDescription: meta.og.description || meta.title || $appHelpers.APP_NAME,
    ogType: meta.og.type || undefined,
    ogUrl: meta.og.url || undefined,
    ogImage: meta.og.image || undefined,
    twitterCard: meta.twitter.card || undefined,
    twitterTitle: meta.twitter.title || undefined,
    twitterDescription: meta.twitter.description || undefined,
    robots: meta.robots,
  });

  useHead({
    link: [
      meta.canonical ? { rel: 'canonical', href: meta.canonical } : {},
    ].filter(Boolean) as any,
    meta: [{ property: 'og:locale', content: locale.value }],
    script: meta.jsonLd.map((obj: any) => ({
      type: 'application/ld+json',
      innerHTML: JSON.stringify(obj),
    })),
    __dangerouslyDisableSanitizersByTagID: Object.fromEntries(
        meta.jsonLd.map((_, i: number) => [`ldjson-${i}`, ['innerHTML']])
    ),
  });
}

const { products } = useProducts({ categoriesSlugs: product.value?.category.slug });

const isProductInWishlist = computed(() => {
  if (isAuthenticated.value) {
    return !!wishlistStore.wishlist?.products?.edges.find(
        (el) => el?.node?.uuid === product.value.uuid
    );
  } else {
    return (cookieWishlist.value ?? []).includes(product.value.uuid);
  }
});

const isProductInCart = computed(() => {
  if (isAuthenticated.value) {
    return !!cartStore.currentOrder?.orderProducts?.edges.find(
        (prod) => prod.node.product.uuid === product.value?.uuid
    );
  } else {
    return (cookieCart.value ?? []).some(
        (item) => item.product.uuid === product.value?.uuid
    );
  }
});

const productInCartQuantity = computed(() => {
  if (isAuthenticated.value) {
    const productEdge = cartStore.currentOrder?.orderProducts?.edges.find(
        (prod) => prod.node.product.uuid === product.value.uuid
    );
    return productEdge?.node.quantity ?? 0;
  } else {
    const cartItem = (cookieCart.value ?? []).find(
        (item) => item.product === product.value.uuid
    );
    return cartItem?.quantity ?? 0;
  }
});

const images = computed<string[]>(() =>
  product.value
    ? product.value.images.edges.map(e => e.node.image)
    : []
);

const attributes = computed(() => {
  const edges = product.value?.attributeGroups.edges ?? [];

  const mainIndex = edges.findIndex(e => e.node.name === 'Основные характеристики');
  const ordered = mainIndex >= 0
    ? [edges[mainIndex], ...edges.slice(0, mainIndex), ...edges.slice(mainIndex + 1)]
    : edges;

  return ordered.map(groupEdge => {
    const { node } = groupEdge
    return {
      uuid: node.uuid,
      name: node.name,
      items: node.attributes.map(attr => ({
        uuid: attr.uuid,
        name: attr.name,
        valuesStr: attr.values.map(v => v.value).join(', ')
      }))
    };
  });
});

const selectedImage = ref<string>(images.value[0] ?? '');
const selectImage = (image: string) => {
  selectedImage.value = image;
};

const prevButton = ref<HTMLElement | null>(null);
const nextButton = ref<HTMLElement | null>(null);

setPageTitle(product.value?.name ?? 'Product');

watch(
  () => route.params.slug,
  async (newSlug) => {
    if (typeof newSlug === 'string') {
      const { product } = await useProductBySlug(newSlug);
      setPageTitle(product.value?.name ?? 'Product');
    }
  }
);
</script>

<style scoped lang="scss">
.product {
  background-color: $main;
  padding-block: 50px 100px;

  &__title {
    font-family: "Playfair Display", sans-serif;
    color: $primary_dark;
    font-size: 36px;
    font-weight: 600;
  }

  &__block {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 50px;
  }

  &__images {
    display: flex;
    align-items: flex-start;
    gap: 26px;

    &-gallery {
      display: flex;
      flex-direction: column;
      gap: 10px;

      & div {
        cursor: pointer;
        width: 75px;
        height: 75px;
        padding: 5px;
        border-radius: $less_border_radius;
        background-color: $main;
        border: 2px solid $main;

        @include hover {
          box-shadow: 0 0 10px 1px $primary;

          &.active {
            box-shadow: 0 0 0 0 transparent;
          }
        }

        &.active {
          border: 2px solid $primary;
        }

        & img {
          width: 100%;
          height: 100%;
          object-fit: contain;
          border-radius: $less_border_radius;
        }
      }
    }

    &-main {
      width: 550px;
      border-radius: $less_border_radius;
      object-fit: contain;
    }
  }

  &__main {
    display: flex;
    flex-direction: column;
    gap: 10px;

    &-brand {
      color: $primary_dark;
      font-size: 14px;
      font-weight: 500;
      letter-spacing: -0.15px;
    }

    &-rate {
      margin-block: 10px 14px;
    }

    &-price {
      color: $primary_dark;
      font-size: 30px;
      font-weight: 600;
      letter-spacing: -0.5px;
    }

    &-quantity {
      color: $primary_dark;
      font-size: 14px;
      font-weight: 500;
      letter-spacing: -0.15px;
    }

    &-description {
      color: $secondary;
      font-size: 16px;
      font-weight: 400;
      letter-spacing: -0.5px;
    }

    &-buttons {
      display: flex;
      align-items: center;
      justify-content: space-between;

      & .button {
        width: 49%;
      }
    }

    &-button {
      margin-top: 25px;
    }
  }

  &__info {
    width: 400px;
    flex-shrink: 0;
    border-radius: $less_border_radius;
    background-color: $primary;
    padding: 5px;

    &-inner {
      border-radius: $less_border_radius;
      border: 2px solid $main;
      padding: 25px;
      display: flex;
      flex-direction: column;
      gap: 25px;
    }

    &-top {
      display: flex;
      align-items: flex-start;
      justify-content: space-between;

      & p {
        color: $main;
        font-size: 16px;
        font-weight: 500;
      }

      & img {
        width: 75px;
        border-radius: $less_border_radius;
      }
    }

    &-price {
      width: fit-content;
      background-color: $primary_dark;
      border-radius: $less_border_radius;
      border: 1px solid $main;
      padding: 7px 20px;

      font-size: 40px;
      font-weight: 700;
      color: $main;
    }

    &-bottom {
      width: 100%;
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 10px;
      flex-shrink: 0;
    }

    &-button {
      width: unset !important;
      padding-inline: 25px !important;
      background-color: $main !important;
      color: $primary !important;

      font-size: 20px !important;

      @include hover {
        background-color: $main_hover !important;
      }
    }

    &-wishlist {
      cursor: pointer;
      width: 41px;
      height: 41px;
      flex-shrink: 0;
      background-color: $main;
      border-radius: $less_border_radius;
      display: grid;
      place-items: center;

      font-size: 22px;
      color: $primary;

      @include hover {
        background-color: $main_hover;
      }
    }
  }
}

.tools {
  width: 100%;
  border-radius: $less_border_radius;
  background-color: $primary;
  display: grid;
  grid-template-columns: 1fr 2fr 1fr;
  height: 40px;

  &__item {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;

    &-count {
      border-left: 1px solid $primary;
      border-right: 1px solid $primary;

      color: $main;
      font-size: 16px;
      font-weight: 600;
    }

    &-button {
      cursor: pointer;
      background-color: $primary;
      border-radius: $less_border_radius 0 0 $less_border_radius;

      color: $main;
      font-size: 18px;
      font-weight: 500;

      @include hover {
        background-color: $primary_hover;
        color: $main;
      }

      &:last-child {
        border-radius: 0 $less_border_radius $less_border_radius 0;
      }
    }
  }
}

.characteristics {
  margin-top: 100px;
  display: flex;
  flex-direction: column;
  gap: 25px;
  padding: 45px 25px;
  border-radius: $default_border_radius;
  border: 1px solid $border;

  &__title {
    font-family: "Playfair Display", sans-serif;
    color: $primary_dark;
    font-size: 30px;
    font-weight: 600;
    letter-spacing: -0.5px;
  }

  &__list {
    margin-top: 20px;
    display: grid;
    grid-template-columns: repeat(auto-fit,minmax(30%, 30%));
    gap: 40px;
  }

  &__column {
    display: flex;
    flex-direction: column;
    gap: 8px;

    &-title {
      margin-bottom: 5px;
      color: $primary_dark;
      font-weight: 700;
      font-size: 16px;
    }
  }

  &__item {
    display: grid;
    grid-template-columns: repeat(2,1fr);
    width: 100%;
    gap: 5px;
    font-size: 14px;

    &-label {
      position: relative;
      font-weight: 500;

      & span {
        position: relative;
        z-index: 1;
        background-color: $main;
        padding-bottom: 1px;

        color: $text;
        font-size: 16px;
        font-weight: 400;
        letter-spacing: -0.5px;
      }

      &::after {
        border-bottom: 1px dashed $primary;
        content: "";
        min-width: 100%;
        position: absolute;
        right: 0;
        top: 1em;
      }
    }

    &-value {
      color: $primary_dark;
      font-size: 16px;
      font-weight: 500;
      letter-spacing: -0.5px;

      & span {
        &:first-child {
          & span {
            &:first-child {
              display: none;
            }
          }
        }
      }
    }
  }
}

.similar {
  margin-top: 100px;
  background-color: $main;
  display: flex;
  flex-direction: column;
  gap: 25px;
  padding: 45px 25px;
  border-radius: $default_border_radius;
  border: 1px solid $border;

  &__title {
    font-family: "Playfair Display", sans-serif;
    color: $primary_dark;
    font-size: 30px;
    font-weight: 600;
    letter-spacing: -0.5px;
  }
  
  &__inner {
    display: flex;
    align-items: stretch;
  }

  &__swiper {
    width: 100%;
    padding-block: 25px;
    padding-inline: 25px;
  }

  &__button {
    cursor: pointer;
    height: fit-content;
    margin-block: auto;
    flex-shrink: 0;
    display: grid;
    place-items: center;
    padding-inline: 10px;
    aspect-ratio: 1;
    border-radius: 50%;
    background-color: transparent;

    @include hover {
      background-color: $link_secondary;
    }

    & span {
      color: $primary;
    }

    &.next {
      & span {
        transform: rotate(180deg);
      }
    }
  }
}
</style>