'use client'

import { useEffect, useState, useRef, useCallback } from 'react'
import Link from 'next/link'
import { useLocale } from 'next-intl'
import api from '@/lib/api'
import { Package, t as tl } from '@/types'
import type { Locale } from '@/types'

const resolveImage = (src?: string) => {
  if (!src) return undefined
  if (src.startsWith('http')) return src
  const base = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:5000/api'
  return `${base.replace(/\/api$/, '')}${src}`
}

const VISIBLE_COUNT = 3
const SCROLL_INTERVAL = 3000
const TRANSITION_MS = 600
const GAP_PX = 8

const ServiceRail = () => {
  const [packages, setPackages] = useState<Package[]>([])
  const [baseIndex, setBaseIndex] = useState(0)
  const [isAnimating, setIsAnimating] = useState(false)
  const [itemH, setItemH] = useState(0)
  const timerRef = useRef<ReturnType<typeof setInterval> | null>(null)
  const trackRef = useRef<HTMLDivElement>(null)
  const firstItemRef = useRef<HTMLAnchorElement>(null)
  const locale = useLocale() as Locale
  const lp = (path: string) => `/${locale}${path}`

  useEffect(() => {
    api.getPackages().then(setPackages).catch(() => { })
  }, [])

  useEffect(() => {
    if (!firstItemRef.current) return
    const measure = () => setItemH(firstItemRef.current?.offsetHeight ?? 0)
    measure()
    const ro = new ResizeObserver(measure)
    ro.observe(firstItemRef.current)
    return () => ro.disconnect()
  }, [packages.length])

  const needsScroll = packages.length > VISIBLE_COUNT

  const advance = useCallback(() => {
    if (!needsScroll) return
    setIsAnimating(true)
  }, [needsScroll])

  useEffect(() => {
    if (!needsScroll) return
    timerRef.current = setInterval(advance, SCROLL_INTERVAL)
    return () => {
      if (timerRef.current) clearInterval(timerRef.current)
    }
  }, [needsScroll, advance])

  const handleTransitionEnd = useCallback((e: React.TransitionEvent) => {
    if (e.target !== trackRef.current) return
    setIsAnimating(false)
    setBaseIndex((prev) => (prev + 1) % packages.length)
  }, [packages.length])

  if (packages.length === 0) return null

  const count = packages.length
  const getVisibleItems = () => {
    const items: { pkg: Package; dataIdx: number }[] = []
    const slots = needsScroll ? VISIBLE_COUNT + 1 : Math.min(VISIBLE_COUNT, count)
    for (let i = 0; i < slots; i++) {
      const idx = (baseIndex + i) % count
      items.push({ pkg: packages[idx], dataIdx: idx })
    }
    return items
  }

  const visibleItems = getVisibleItems()
  const containerH = itemH > 0 ? itemH * VISIBLE_COUNT + GAP_PX * (VISIBLE_COUNT - 1) : undefined
  const translatePx = isAnimating ? -(itemH + GAP_PX) : 0

  return (
    <aside className="sticky top-24 self-start">
      <div
        className="overflow-hidden"
        style={containerH ? { height: containerH } : undefined}
      >
        <div
          ref={trackRef}
          className="flex flex-col will-change-transform"
          onTransitionEnd={handleTransitionEnd}
          style={{
            gap: GAP_PX,
            transform: `translateY(${translatePx}px)`,
            transition: isAnimating ? `transform ${TRANSITION_MS}ms cubic-bezier(0.4, 0, 0.2, 1)` : 'none',
          }}
        >
          {visibleItems.map(({ pkg, dataIdx }, i) => {
            const img = resolveImage(pkg.image)
            const title = tl(pkg.title, locale)
            const isExternal = pkg.link?.startsWith('http')
            const href = pkg.link
              ? isExternal ? pkg.link : lp(pkg.link)
              : '#'

            const card = (
              <div className="relative rounded-sm overflow-hidden aspect-[3/4] bg-gray-100">
                {img ? (
                  // eslint-disable-next-line @next/next/no-img-element
                  <img
                    src={img}
                    alt={title}
                    className="absolute inset-0 w-full h-full object-cover group-hover:scale-[1.03] transition-transform duration-200"
                  />
                ) : (
                  <div className="absolute inset-0 bg-gradient-to-br from-primary-600 to-primary-800" />
                )}
                <div className="absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent" />
                <div className="absolute bottom-0 left-0 right-0 p-3">
                  <h4 className="text-xs font-bold text-white line-clamp-2 leading-snug">
                    {title}
                  </h4>
                </div>
              </div>
            )

            return isExternal ? (
              <a
                key={dataIdx}
                ref={i === 0 ? firstItemRef as React.Ref<HTMLAnchorElement> : undefined}
                href={href}
                target="_blank"
                rel="noopener noreferrer"
                className="group block flex-shrink-0"
              >
                {card}
              </a>
            ) : (
              <Link
                key={dataIdx}
                ref={i === 0 ? firstItemRef : undefined}
                href={href}
                className="group block flex-shrink-0"
              >
                {card}
              </Link>
            )
          })}
        </div>
      </div>
    </aside>
  )
}

export default ServiceRail
