'use client';

import React, { useCallback, useEffect, useMemo, useState } from 'react';
import {
  Carousel,
  CarouselContent,
  CarouselItem,
  type CarouselApi
} from '@/components/ui/carousel';
import { transformPostsToArticleList } from '@/features/posts/_lib/transformers';
import { api } from '@/lib/trpc/client';
import SliderItem from './slider-item';
import { useMapStore } from '@/components/shared/map/map-store';
import { useSearchParams } from 'next/navigation';
import { TopicsEnum } from '@/config/enums';
import {
  initialBounds,
  initialLimit,
  sponsored
} from '../_constants/map-options';
import { useMediaQuery } from '@/hooks/use-media-query';
import { ChevronDown, ChevronUp } from 'lucide-react';
import { cn } from '@/lib/utils';

export default function Slider() {
  const searchParams = useSearchParams();
  const isDesktop = useMediaQuery('(min-width: 1024px)');

  const [sliderApi, setSliderApi] = useState<CarouselApi | null>(null);
  const [limit, setLimit] = useState(initialLimit);
  const [isDisabledNext, setIsDisabledNext] = useState(true);
  const [isDisabledPrev, setIsDisabledPrev] = useState(true);

  const { bounds } = useMapStore();

  const topic = useMemo(() => {
    const filters = searchParams?.get('filters');
    if (!filters) return undefined;
    const filtered = filters.split(',').filter((item) => item !== sponsored);
    return !!filtered.length ? (filtered as TopicsEnum[]) : undefined;
  }, [searchParams]);

  const isSponsored = useMemo(() => {
    const filters = searchParams?.get('filters');
    return !!filters?.includes(sponsored);
  }, [searchParams]);

  const { data: items = [], isFetching: itemsFetching } =
    api.posts.list.useQuery(
      {
        limit,
        topic,
        notTopic: [TopicsEnum.REVIEWS],
        isSponsored,
        bounds: bounds || initialBounds
      },
      {
        select: transformPostsToArticleList,
        placeholderData: (data) => data
      }
    );

  const { data: total = 0, isFetching: countFetching } =
    api.posts.count.useQuery({
      topic,
      notTopic: [TopicsEnum.REVIEWS],
      isSponsored,
      bounds: bounds || initialBounds
    });

  const hasMore = items.length < total;

  const updateButtons = useCallback(() => {
    if (!sliderApi) return;
    setIsDisabledNext(!sliderApi.canScrollNext());
    setIsDisabledPrev(!sliderApi?.canScrollPrev());
  }, [sliderApi]);

  const loadMore = useCallback(() => {
    if (!sliderApi || !hasMore) return;
    const currentSlide = sliderApi.selectedScrollSnap();
    const totalSlides = sliderApi.scrollSnapList().length;

    if (currentSlide >= totalSlides - 2) {
      setLimit((prev) => prev + initialLimit);
    }
  }, [sliderApi, hasMore]);

  useEffect(() => {
    if (!sliderApi) return;
    const updateSlider = () => {
      loadMore();
      updateButtons();
    };
    updateButtons();
    sliderApi.on('select', updateSlider);
    return () => {
      sliderApi.off('select', updateSlider);
    };
  }, [sliderApi, loadMore, updateButtons]);

  if (!isDesktop) {
    return null;
  }

  if (!total && !countFetching && !itemsFetching) {
    return (
      <div className='flex size-full flex-col items-center justify-center'>
        <p className='text-lg font-medium'>Artikler ikke fundet</p>
      </div>
    );
  }

  return (
    <div className='flex size-full flex-col items-center justify-center'>
      <Carousel
        setApi={(e) => setSliderApi(e)}
        opts={{
          align: 'start'
        }}
        orientation='vertical'
      >
        <CarouselContent className='-mt-4 h-176 xl:h-196'>
          {items?.map((item, index) => (
            <CarouselItem key={index} className='basis-62 pt-4'>
              <SliderItem data={item} />
            </CarouselItem>
          ))}
        </CarouselContent>
        {total > 2 && (
          <>
            <button
              className={cn(
                'text-client-red absolute -top-12 left-1/2 z-10 -translate-x-1/2 rounded-full transition hover:-translate-y-0.5',
                isDisabledPrev && 'pointer-events-none opacity-50'
              )}
              onClick={() => sliderApi?.scrollPrev()}
              disabled={isDisabledPrev}
            >
              <svg
                width='36'
                viewBox='0 0 1664 1280'
                xmlns='http://www.w3.org/2000/svg'
                className='size-8'
              >
                <path
                  d='M1619 1075l-166 165q-19 19-45 19t-45-19L832 709l-531 531q-19 19-45 19t-45-19L45 1075q-19-19-19-45.5T45 984l742-741q19-19 45-19t45 19l742 741q19 19 19 45.5t-19 45.5z'
                  fill='currentColor'
                />
              </svg>
            </button>
            <button
              className={cn(
                'text-client-red absolute -bottom-12 left-1/2 z-10 -translate-x-1/2 cursor-pointer transition hover:translate-y-0.5',
                isDisabledNext && 'pointer-events-none opacity-50'
              )}
              onClick={() => sliderApi?.scrollNext()}
              disabled={isDisabledNext}
            >
              <svg
                width='36'
                viewBox='0 0 1664 1312'
                xmlns='http://www.w3.org/2000/svg'
                className='size-8'
              >
                <path
                  d='M1619 552l-742 741q-19 19-45 19t-45-19L45 552q-19-19-19-45.5T45 461l166-165q19-19 45-19t45 19l531 531l531-531q19-19 45-19t45 19l166 165q19 19 19 45.5t-19 45.5z'
                  fill='currentColor'
                />
              </svg>
            </button>
          </>
        )}
      </Carousel>
    </div>
  );
}
