"use client";

import React, { useState, useRef, useEffect } from "react";
import Image from "next/image";
import BoldIcon from "@/components/ui/BoldIcon";
import { cn } from "@/lib/utils";
import { useTranslation } from "react-i18next";

interface MediaFile {
  src: string;
  type?: "image" | "video";
}

interface SwipeImageSliderProps {
  mediaFiles: MediaFile[];
  setImageLoading?: React.Dispatch<React.SetStateAction<boolean>>;
}

const SwipeImageSlider: React.FC<SwipeImageSliderProps> = ({
  mediaFiles,
  setImageLoading,
}) => {
  const { t } = useTranslation("common");
  const [currentIndex, setCurrentIndex] = useState(0);
  const [isDragging, setIsDragging] = useState(false);
  const startX = useRef<number | null>(null);
  const sliderRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    setCurrentIndex(0);
  }, [mediaFiles.length]);

  const goToPrev = () => {
    setCurrentIndex((prev) => (prev > 0 ? prev - 1 : mediaFiles.length - 1));
  };

  const goToNext = () => {
    setCurrentIndex((prev) => (prev < mediaFiles.length - 1 ? prev + 1 : 0));
  };

  const handleStart = (clientX: number) => {
    startX.current = clientX;
    setIsDragging(true);
  };

  const handleEnd = (clientX: number) => {
    if (!startX.current || !isDragging) return;

    const diff = clientX - startX.current;
    if (Math.abs(diff) > 50) {
      if (diff > 0) {
        goToPrev();
      } else {
        goToNext();
      }
    }

    startX.current = null;
    setIsDragging(false);
  };

  const handleMouseDown = (e: React.MouseEvent) => handleStart(e.clientX);
  const handleMouseUp = (e: React.MouseEvent) => handleEnd(e.clientX);
  const handleTouchStart = (e: React.TouchEvent) =>
    handleStart(e.touches[0].clientX);
  const handleTouchEnd = (e: React.TouchEvent) =>
    handleEnd(e.changedTouches[0].clientX);

  if (!mediaFiles || mediaFiles.length === 0) {
    return (
      <div className="flex h-64 w-full items-center justify-center rounded-2xl bg-neutral-200 dark:bg-neutral-800">
        <p className="text-neutral-500">{t("models.noImage")}</p>
      </div>
    );
  }

  const navButtonClass =
    "absolute top-1/2 z-20 flex h-10 w-10 -translate-y-1/2 items-center justify-center transition-transform active:scale-90 drop-shadow-[0_1px_4px_rgba(0,0,0,0.45)]";

  return (
    <div className="group relative w-full select-none">
      <div
        ref={sliderRef}
        className="flex flex-row-reverse overflow-hidden rounded-2xl bg-neutral-100 dark:bg-neutral-900"
        onMouseDown={handleMouseDown}
        onMouseUp={handleMouseUp}
        onMouseLeave={() => setIsDragging(false)}
        onTouchStart={handleTouchStart}
        onTouchEnd={handleTouchEnd}
        style={{ cursor: isDragging ? "grabbing" : "grab" }}
      >
        <div
          className="flex flex-row-reverse transition-transform duration-500 ease-out"
          style={{
            transform: `translateX(-${currentIndex * 100}%)`,
            width: `${mediaFiles.length * 100}%`,
          }}
        >
          {mediaFiles.map((file, idx) => (
            <div
              key={idx}
              className="flex w-full shrink-0 items-center justify-center p-2"
              style={{ width: "100%" }}
            >
              {file.type === "video" ? (
                <video
                  src={file.src}
                  controls
                  className="max-h-[60vh] w-auto rounded-xl shadow-lg"
                  onLoadedData={() => setImageLoading?.(false)}
                />
              ) : (
                <Image
                  src={file.src}
                  alt={`media-${idx}`}
                  width={1000}
                  height={1000}
                  priority={idx === 0}
                  loading={idx === 0 ? "eager" : "lazy"}
                  className="min-h-[30vh] w-full rounded-xl object-contain shadow-lg transition-opacity duration-300"
                  onLoadingComplete={() => setImageLoading?.(false)}
                  unoptimized
                />
              )}
            </div>
          ))}
        </div>
      </div>

      {mediaFiles.length > 1 && (
        <>
          <button
            type="button"
            onClick={goToPrev}
            className={cn(
              navButtonClass,
              "left-3 opacity-100 sm:opacity-0 sm:group-hover:opacity-100"
            )}
            aria-label={t("models.prevImage")}
          >
            <BoldIcon
              name="arrow-circle-left"
              size={36}
              tinted
              className="text-white"
            />
          </button>
          <button
            type="button"
            onClick={goToNext}
            className={cn(
              navButtonClass,
              "right-3 opacity-100 sm:opacity-0 sm:group-hover:opacity-100"
            )}
            aria-label={t("models.nextImage")}
          >
            <BoldIcon
              name="arrow-circle-right"
              size={36}
              tinted
              className="text-white"
            />
          </button>
        </>
      )}

      {mediaFiles.length > 1 && (
        <div className="absolute bottom-3 left-1/2 flex -translate-x-1/2 flex-row-reverse gap-1">
          {mediaFiles.map((_, idx) => (
            <button
              key={idx}
              type="button"
              onClick={() => setCurrentIndex(idx)}
              className={`h-1.5 rounded-full transition-all duration-300 ${
                idx === currentIndex
                  ? "w-6 bg-white"
                  : "w-1.5 bg-white/50 hover:bg-white/80"
              }`}
              aria-label={t("models.goToSlide", { n: idx + 1 })}
            />
          ))}
        </div>
      )}
    </div>
  );
};

export default SwipeImageSlider;
