'use client'

import { useCallback, useEffect, useMemo, useState } from 'react'
import ContentCard from './ui/content-cards'
import './content-card-carousel.css'

interface ContentCardItem {
  src?: string
  button_link?: string
  heading?: string
  button_text?: string
  card_text?: string
}

interface ContentCardCarouselProps {
  cards: ContentCardItem[]
}

function getVisibleCardCount() {
  if (typeof window === 'undefined') return 1
  if (window.matchMedia('(min-width: 1024px)').matches) return 3
  if (window.matchMedia('(min-width: 640px)').matches) return 2
  return 1
}

export default function ContentCardCarousel({ cards }: ContentCardCarouselProps) {
  const [visibleCards, setVisibleCards] = useState(1)
  const [currentIndex, setCurrentIndex] = useState(0)

  const syncVisibleCards = useCallback(() => {
    setVisibleCards(getVisibleCardCount())
  }, [])

  useEffect(() => {
    syncVisibleCards()

    const mediaQueries = [
      window.matchMedia('(min-width: 640px)'),
      window.matchMedia('(min-width: 1024px)'),
    ]

    const onBreakpointChange = () => syncVisibleCards()

    mediaQueries.forEach((mq) => mq.addEventListener('change', onBreakpointChange))
    window.addEventListener('resize', onBreakpointChange)

    return () => {
      mediaQueries.forEach((mq) => mq.removeEventListener('change', onBreakpointChange))
      window.removeEventListener('resize', onBreakpointChange)
    }
  }, [syncVisibleCards])

  const maxIndex = useMemo(() => Math.max(cards.length - visibleCards, 0), [cards.length, visibleCards])

  useEffect(() => {
    setCurrentIndex((previous) => Math.min(previous, maxIndex))
  }, [maxIndex])

  // % of track width — matches flex slide sizes (100% / 50% / 33.333% per breakpoint)
  const trackOffsetPercent = cards.length > 0 ? (currentIndex * 100) / cards.length : 0

  const next = () => {
    if (maxIndex === 0) return
    setCurrentIndex((previous) => (previous >= maxIndex ? 0 : previous + 1))
  }

  const previous = () => {
    if (maxIndex === 0) return
    setCurrentIndex((index) => (index <= 0 ? maxIndex : index - 1))
  }

  return (
    <div className="w-full max-w-full pb-30">
      <h1 className="mb-4 flex justify-center text-5xl font-bold">Our Case Studies</h1>

      <div className="carousel-viewport relative overflow-hidden">
        <div
          className="carousel-track flex items-stretch transition-transform duration-500 ease-in-out"
          style={{ transform: `translate3d(-${trackOffsetPercent}%, 0, 0)` }}
        >
          {cards.map((card, index) => {
            const isEdgeCard =
              visibleCards > 1 && (index === currentIndex || index === currentIndex + visibleCards - 1)

            return (
              <div
                key={`${card.heading ?? 'card'}-${index}`}
                className={`carousel-slide flex shrink-0 justify-center px-2 py-3 transition-opacity duration-500 ${
                  isEdgeCard ? 'opacity-75' : 'opacity-100'
                }`}
              >
                <div className="flex h-full w-full max-w-sm">
                  <ContentCard {...card} />
                </div>
              </div>
            )
          })}
        </div>

        <div className="pointer-events-none absolute inset-y-0 left-0 w-12 bg-gradient-to-r from-white to-transparent dark:from-black" />
        <div className="pointer-events-none absolute inset-y-0 right-0 w-12 bg-gradient-to-l from-white to-transparent dark:from-black" />
      </div>

      <div className="carousel-controls relative z-20 mt-6 flex justify-center gap-4">
        <button
          type="button"
          onClick={previous}
          disabled={maxIndex === 0}
          className="carousel-control-btn"
          aria-label="Show previous content cards"
        >
          &#8592;
        </button>
        <button
          type="button"
          onClick={next}
          disabled={maxIndex === 0}
          className="carousel-control-btn"
          aria-label="Show next content cards"
        >
          &#8594;
        </button>
      </div>
    </div>
  )
}
