<script setup lang="ts">
import { useQuery } from '@vue/apollo-composable';
import {
  ClientProductsDocument,
  type ClientProductsQuery,
} from '~/composables/graphql/generated';
import { catalogProductImageSrc } from '~/utils/catalogProductImages';

type ProductNode = ClientProductsQuery['clientProducts'][number];
type ProductTypeCard = {
  key: string;
  typeLabel: string;
};

const productsQuery = useQuery(ClientProductsDocument);
const search = ref('');

const loading = computed(() => productsQuery.loading.value);
const error = computed(() => productsQuery.error.value);

function normalizeText(value: string | null | undefined) {
  return String(value ?? '').replaceAll(/\s+/g, ' ').trim();
}

function slugifyTypeLabel(value: string) {
  return normalizeText(value)
    .toLowerCase()
    .replaceAll(/[^a-z0-9а-яё]+/gi, '-')
    .replaceAll(/-+/g, '-')
    .replaceAll(/^-|-$/g, '');
}

function createProductCover(name: string, sku: string) {
  const coverPresets = [
    ['#d9f5e6', '#9ce8c1', '#6fd09d'],
    ['#eaf9ef', '#b3e8cb', '#76c89f'],
    ['#e8f5ec', '#b2e0c6', '#7dd0a9'],
  ];
  const seed = `${name}${sku}`.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0);
  const [start, middle, finish] = coverPresets[seed % coverPresets.length];
  const firstLetter = name.trim().charAt(0).toUpperCase() || 'P';

  const svg = `
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 220">
      <defs>
        <linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stop-color="${start}" />
          <stop offset="55%" stop-color="${middle}" />
          <stop offset="100%" stop-color="${finish}" />
        </linearGradient>
      </defs>
      <rect width="320" height="220" fill="url(#g)" rx="22" />
      <g opacity="0.15">
        <circle cx="266" cy="45" r="55" fill="#0f7a49" />
        <circle cx="42" cy="198" r="55" fill="#0f7a49" />
      </g>
      <text x="50%" y="56%" text-anchor="middle" fill="#11412c" font-family="Manrope, sans-serif" font-size="84" font-weight="700">${firstLetter}</text>
    </svg>
  `.trim();

  return `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`;
}

function productImageSrc(name: string, sku: string) {
  return catalogProductImageSrc(name) ?? createProductCover(name, sku);
}

const productTypeCards = computed<ProductTypeCard[]>(() => {
  const products = productsQuery.result.value?.clientProducts ?? [];
  const query = search.value.trim().toLowerCase();
  const grouped = new Map<string, ProductNode[]>();

  for (const product of products) {
    const typeLabel = normalizeText(product.productType) || 'Без типа';
    const existing = grouped.get(typeLabel);
    if (existing) {
      existing.push(product);
    } else {
      grouped.set(typeLabel, [product]);
    }
  }

  return [...grouped.entries()]
    .map(([typeLabel]) => ({
      key: slugifyTypeLabel(typeLabel),
      typeLabel,
    }))
    .filter((card) => {
      if (!query) {
        return true;
      }

      return card.typeLabel.toLowerCase().includes(query);
    })
    .sort((a, b) => a.typeLabel.localeCompare(b.typeLabel, 'ru'));
});
</script>

<template>
  <section class="space-y-5">
    <UiSectionSearchHero
      v-model="search"
      title="Каталог"
      search-placeholder="Поиск по типу товара"
    />

    <div v-if="loading" class="alert surface-card border-0">Загрузка каталога...</div>
    <div v-else-if="error" class="alert alert-error">{{ error.message }}</div>

    <div v-else-if="productTypeCards.length" class="grid grid-cols-2 gap-3 md:grid-cols-3 xl:grid-cols-5">
      <NuxtLink
        v-for="card in productTypeCards"
        :key="card.key"
        :to="`/products/${card.key}`"
        class="surface-card block rounded-3xl p-3 transition hover:-translate-y-0.5 hover:shadow-[0_22px_42px_rgba(18,56,36,0.12)]"
      >
        <img
          :src="productImageSrc(card.typeLabel, card.key)"
          :alt="`Превью ${card.typeLabel}`"
          class="aspect-square w-full rounded-[24px] bg-[#f7fbf8] object-contain"
          loading="lazy"
        >

        <div class="mt-3">
          <h2 class="text-base font-bold leading-5 text-[#163624]">{{ card.typeLabel }}</h2>
        </div>
      </NuxtLink>
    </div>

    <div v-else class="alert surface-card border-0">По текущему запросу товары не найдены.</div>
  </section>
</template>
