"use client";

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

type MediaItem = { src: string };

type ReelsImageCarouselProps = {
  mediaFiles: MediaItem[];
  isActive: boolean;
  priority?: boolean;
  onLoadingComplete?: () => void;
};

const GESTURE_LOCK_PX = 10;

export default function ReelsImageCarousel({
  mediaFiles,
  isActive,
  priority = false,
  onLoadingComplete,
}: ReelsImageCarouselProps) {
  const { t } = useTranslation("common");
  const scrollRef = useRef<HTMLDivElement>(null);
  const gestureRef = useRef<{
    startX: number;
    startY: number;
    locked: "h" | "v" | null;
  }>({ startX: 0, startY: 0, locked: null });
  const [index, setIndex] = useState(0);
  const count = mediaFiles.length;
  const hasMany = count > 1;

  const syncIndexFromScroll = useCallback(() => {
    const el = scrollRef.current;
    if (!el) return;
    const width = el.clientWidth;
    if (!width) return;
    const next = Math.min(
      count - 1,
      Math.max(0, Math.round(el.scrollLeft / width))
    );
    setIndex(next);
  }, [count]);

  const scrollToIndex = useCallback(
    (next: number, behavior: ScrollBehavior = "smooth") => {
      const el = scrollRef.current;
      if (!el || !hasMany) return;
      const width = el.clientWidth;
      if (!width) return;
      const clamped = Math.min(count - 1, Math.max(0, next));
      el.scrollTo({ left: clamped * width, behavior });
      setIndex(clamped);
    },
    [count, hasMany]
  );

  useEffect(() => {
    scrollToIndex(0, "auto");
  }, [mediaFiles, scrollToIndex]);

  useEffect(() => {
    if (!isActive) {
      scrollToIndex(0, "auto");
    }
  }, [isActive, scrollToIndex]);

  useEffect(() => {
    const el = scrollRef.current;
    if (!el) return;

    el.addEventListener("scroll", syncIndexFromScroll, { passive: true });
    el.addEventListener("scrollend", syncIndexFromScroll);

    return () => {
      el.removeEventListener("scroll", syncIndexFromScroll);
      el.removeEventListener("scrollend", syncIndexFromScroll);
    };
  }, [syncIndexFromScroll]);

  useEffect(() => {
    const el = scrollRef.current;
    if (!el || !hasMany) return;

    const onTouchStart = (e: TouchEvent) => {
      const touch = e.touches[0];
      if (!touch) return;
      gestureRef.current = {
        startX: touch.clientX,
        startY: touch.clientY,
        locked: null,
      };
    };

    const onTouchMove = (e: TouchEvent) => {
      const touch = e.touches[0];
      if (!touch) return;
      const g = gestureRef.current;
      const dx = touch.clientX - g.startX;
      const dy = touch.clientY - g.startY;

      if (!g.locked) {
        if (
          Math.abs(dx) < GESTURE_LOCK_PX &&
          Math.abs(dy) < GESTURE_LOCK_PX
        ) {
          return;
        }
        g.locked = Math.abs(dx) > Math.abs(dy) ? "h" : "v";
      }

      if (g.locked === "h") {
        e.preventDefault();
      }
    };

    el.addEventListener("touchstart", onTouchStart, { passive: true });
    el.addEventListener("touchmove", onTouchMove, { passive: false });

    return () => {
      el.removeEventListener("touchstart", onTouchStart);
      el.removeEventListener("touchmove", onTouchMove);
    };
  }, [hasMany]);

  const goPrev = (e?: React.SyntheticEvent) => {
    e?.stopPropagation();
    scrollToIndex(index - 1);
  };

  const goNext = (e?: React.SyntheticEvent) => {
    e?.stopPropagation();
    scrollToIndex(index + 1);
  };

  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)] disabled:opacity-40";

  if (count === 0) return null;

  if (!hasMany) {
    return (
      <div
        className="relative h-full w-full overflow-hidden"
        dir="ltr"
        onClick={(e) => e.stopPropagation()}
      >
        <Image
          src={mediaFiles[0].src}
          alt=""
          fill
          className="object-contain select-none"
          priority={priority}
          draggable={false}
          onLoad={() => onLoadingComplete?.()}
          unoptimized
        />
      </div>
    );
  }

  return (
    <div
      className="relative h-full w-full overflow-hidden"
      dir="ltr"
      onClick={(e) => e.stopPropagation()}
    >
      <div
        ref={scrollRef}
        className="reels-horizontal-scroll flex h-full w-full overflow-x-auto"
      >
        {mediaFiles.map((file, idx) => (
          <div
            key={`${file.src}-${idx}`}
            className="relative h-full min-w-full shrink-0"
          >
            <Image
              src={file.src}
              alt=""
              fill
              className="object-contain select-none"
              priority={priority && Math.abs(idx - index) <= 1}
              loading={
                priority && Math.abs(idx - index) <= 1 ? "eager" : "lazy"
              }
              draggable={false}
              onLoad={() => {
                if (idx === index) onLoadingComplete?.();
              }}
              unoptimized
            />
          </div>
        ))}
      </div>

      <button
        type="button"
        onClick={goPrev}
        disabled={index <= 0}
        className={cn(navButtonClass, "left-3")}
        aria-label={t("posts.prevImage")}
      >
        <BoldIcon
          name="arrow-circle-left"
          size={36}
          tinted
          className="text-white"
        />
      </button>
      <button
        type="button"
        onClick={goNext}
        disabled={index >= count - 1}
        className={cn(navButtonClass, "right-3")}
        aria-label={t("posts.nextImage")}
      >
        <BoldIcon
          name="arrow-circle-right"
          size={36}
          tinted
          className="text-white"
        />
      </button>
      <div className="pointer-events-none absolute top-[calc(4.5rem+env(safe-area-inset-top))] right-4 z-20 rounded-full bg-black/45 px-3 py-1 text-xs text-white backdrop-blur-sm">
        {index + 1} / {count}
      </div>
    </div>
  );
}
