"use client";

import React, { useCallback, useState } from "react";
import Image from "next/image";
import Link from "next/link";
import { AnimatePresence, motion, PanInfo } from "framer-motion";
import { buildStorageUrl } from "@/components/main/BaseUrl";
import BoldIcon from "@/components/ui/BoldIcon";
import useAxios from "@/hooks/useAxios";
import Cookies from "js-cookie";
import { cn } from "@/lib/utils";
import { useTranslation } from "react-i18next";

export type SuggestedFollowUser = {
  _id: string;
  user_name?: string;
  first_name?: string;
  last_name?: string;
  expertise?: string;
  profile_image?: string;
  previewPost?: {
    _id: string;
    type?: string;
    files?: { path: string }[];
    caption?: string;
  };
  is_following?: boolean;
};

interface FollowingSuggestionsCarouselProps {
  users: SuggestedFollowUser[];
  onFollowed?: () => void;
  onDismiss?: () => void;
}

const SWIPE_THRESHOLD = 72;

const slideVariants = {
  enter: (direction: number) => ({
    x: direction > 0 ? "105%" : "-105%",
    opacity: 0.35,
    scale: 0.9,
  }),
  center: {
    x: 0,
    opacity: 1,
    scale: 1,
  },
  exit: (direction: number) => ({
    x: direction > 0 ? "-105%" : "105%",
    opacity: 0.35,
    scale: 0.9,
  }),
};

function getDisplayName(user: SuggestedFollowUser, fallback: string) {
  return (
    [user.first_name, user.last_name].filter(Boolean).join(" ") ||
    user.user_name ||
    fallback
  );
}

function SuggestionCardShell({
  user,
  variant,
  onSkip,
  onFollow,
  busy,
  isFollowing,
  userFallback,
}: {
  user: SuggestedFollowUser;
  variant: "main" | "peek";
  onSkip?: () => void;
  onFollow?: () => void;
  busy?: boolean;
  isFollowing?: boolean;
  userFallback: string;
}) {
  const { t } = useTranslation("common");
  const displayName = getDisplayName(user, userFallback);
  const previewPath = user.previewPost?.files?.[0]?.path;
  const previewUrl = previewPath ? buildStorageUrl(previewPath) : null;
  const profileUrl = user.profile_image
    ? buildStorageUrl(user.profile_image)
    : null;

  const isMain = variant === "main";

  return (
    <div className="relative h-full w-full overflow-hidden rounded-3xl bg-neutral-900 shadow-2xl">
      {previewUrl ? (
        user.previewPost?.type === "video" ? (
          <video
            src={previewUrl}
            className="h-full w-full object-cover"
            muted
            playsInline
            autoPlay={isMain}
            loop
            preload={isMain ? "auto" : "metadata"}
          />
        ) : (
          <Image
            src={previewUrl}
            alt=""
            fill
            className="object-cover"
            sizes={isMain ? "280px" : "120px"}
            unoptimized
          />
        )
      ) : (
        <div className="h-full w-full bg-neutral-800" />
      )}

      <div
        className={cn(
          "absolute inset-0 bg-gradient-to-t from-black/85 via-black/20 to-black/30",
          !isMain && "from-black/70"
        )}
      />

      {isMain && onSkip ? (
        <button
          type="button"
          onClick={(e) => {
            e.stopPropagation();
            onSkip();
          }}
          className="absolute left-3 top-3 flex h-8 w-8 items-center justify-center rounded-full bg-black/40 text-white backdrop-blur-sm"
          aria-label={t("posts.skip")}
        >
          <BoldIcon name="close-circle" size={18} tinted className="text-white" />
        </button>
      ) : null}

      <div
        className={cn(
          "absolute inset-x-0 bottom-0 flex flex-col items-center pt-6",
          isMain ? "px-4 pb-5" : "px-2 pb-3"
        )}
      >
        <div
          className={cn(
            "relative mb-2 overflow-hidden rounded-full ring-2 ring-white/90",
            isMain ? "h-16 w-16" : "h-9 w-9"
          )}
        >
          {profileUrl ? (
            <Image
              src={profileUrl}
              alt=""
              fill
              className="object-cover"
              sizes={isMain ? "64px" : "36px"}
              unoptimized
            />
          ) : (
            <div className="flex h-full w-full items-center justify-center bg-neutral-700 text-white">
              {displayName.charAt(0)}
            </div>
          )}
        </div>

        {isMain ? (
          <>
            <Link href={`/users/${user.user_name}`} className="text-center">
              <p className="text-base font-bold text-white">{displayName}</p>
              {user.user_name ? (
                <p className="text-xs text-white/70">@{user.user_name}</p>
              ) : null}
            </Link>
            {user.expertise ? (
              <p className="mt-1 text-xs text-white/55">{user.expertise}</p>
            ) : null}
            <button
              type="button"
              disabled={busy || isFollowing}
              onClick={onFollow}
              className="mt-4 w-full max-w-[200px] rounded-full bg-[#fe2c55] py-2.5 text-sm font-bold text-white transition active:scale-95 disabled:opacity-60"
            >
              {isFollowing ? t("posts.followed") : t("posts.followAction")}
            </button>
          </>
        ) : (
          <p className="line-clamp-1 text-center text-[10px] font-semibold text-white">
            {displayName}
          </p>
        )}
      </div>
    </div>
  );
}

export default function FollowingSuggestionsCarousel({
  users,
  onFollowed,
  onDismiss,
}: FollowingSuggestionsCarouselProps) {
  const { t } = useTranslation("common");
  const [[index, direction], setSlide] = useState<[number, number]>([0, 0]);
  const [followingIds, setFollowingIds] = useState<Set<string>>(new Set());
  const [busy, setBusy] = useState(false);
  const { request } = useAxios();

  const current = users[index];

  const paginate = useCallback(
    (step: number) => {
      if (users.length <= 1) return;
      setSlide(([i]) => [
        (i + step + users.length) % users.length,
        step > 0 ? 1 : -1,
      ]);
    },
    [users.length]
  );

  const handleDragEnd = (_: unknown, info: PanInfo) => {
    if (info.offset.x < -SWIPE_THRESHOLD) paginate(1);
    else if (info.offset.x > SWIPE_THRESHOLD) paginate(-1);
  };

  const handleFollow = async () => {
    if (!current || busy) return;
    const token = Cookies.get("token");
    if (!token) return;

    setBusy(true);
    try {
      await request(
        "POST",
        "/posts/follow",
        { userId: current._id },
        { noToast: true }
      );
      setFollowingIds((prev) => new Set(prev).add(String(current._id)));
      onFollowed?.();
      window.setTimeout(() => paginate(1), 350);
    } catch {
      /* ignore */
    } finally {
      setBusy(false);
    }
  };

  if (!users.length || !current) {
    return (
      <div className="flex min-h-[100dvh] w-full flex-col items-center justify-center overflow-hidden bg-black px-6 text-center text-white/70">
        <p className="text-base font-semibold text-white">
          {t("posts.notFollowingAnyone")}
        </p>
        <p className="mt-2 text-sm">{t("posts.notFollowingCarouselHint")}</p>
      </div>
    );
  }

  const isFollowing = followingIds.has(String(current._id));
  const prevUser = users.length > 1 ? users[(index - 1 + users.length) % users.length] : null;
  const nextUser = users.length > 1 ? users[(index + 1) % users.length] : null;

  return (
    <div className="fixed inset-0 z-[1] flex min-h-[100dvh] w-full flex-col items-center overflow-hidden bg-black px-3 pb-[env(safe-area-inset-bottom)] pt-[calc(6.75rem+env(safe-area-inset-top))]">
      <div className="relative mb-6 w-full max-w-[420px] text-center">
        {onDismiss ? (
          <button
            type="button"
            onClick={onDismiss}
            className="absolute left-0 top-0 flex h-9 w-9 items-center justify-center rounded-full bg-white/10 text-white backdrop-blur-sm active:scale-95"
            aria-label={t("posts.closeSuggestions")}
          >
            <BoldIcon name="close-circle" size={20} tinted className="text-white" />
          </button>
        ) : null}
        <h2 className="text-lg font-bold text-white">{t("posts.suggestedCreators")}</h2>
        <p className="mt-1 text-sm text-white/60">{t("posts.suggestedCreatorsHint")}</p>
      </div>

      <div
        dir="ltr"
        className="relative mx-auto h-[min(62dvh,500px)] w-full max-w-[420px] overflow-hidden"
      >
        {prevUser ? (
          <button
            type="button"
            onClick={() => paginate(-1)}
            className="absolute left-1 top-1/2 z-10 h-[88%] w-[22%] -translate-y-1/2 overflow-hidden rounded-2xl opacity-55 active:scale-[0.98]"
            aria-label={t("posts.prevSuggestion")}
          >
            <SuggestionCardShell user={prevUser} variant="peek" userFallback={t("common.user")} />
          </button>
        ) : null}

        {nextUser ? (
          <button
            type="button"
            onClick={() => paginate(1)}
            className="absolute right-1 top-1/2 z-10 h-[88%] w-[22%] -translate-y-1/2 overflow-hidden rounded-2xl opacity-55 active:scale-[0.98]"
            aria-label={t("posts.nextSuggestion")}
          >
            <SuggestionCardShell user={nextUser} variant="peek" userFallback={t("common.user")} />
          </button>
        ) : null}

        <AnimatePresence initial={false} custom={direction} mode="popLayout">
          <motion.div
            key={current._id}
            custom={direction}
            variants={slideVariants}
            initial="enter"
            animate="center"
            exit="exit"
            transition={{
              x: { type: "spring", stiffness: 320, damping: 32, mass: 0.85 },
              opacity: { duration: 0.22 },
              scale: { duration: 0.22 },
            }}
            drag={users.length > 1 ? "x" : false}
            dragConstraints={{ left: 0, right: 0 }}
            dragElastic={0.14}
            onDragEnd={handleDragEnd}
            className="absolute left-1/2 top-1/2 z-20 h-[92%] w-[min(58vw,260px)] -translate-x-1/2 -translate-y-1/2"
          >
            <SuggestionCardShell
              user={current}
              variant="main"
              onSkip={() => paginate(1)}
              onFollow={handleFollow}
              busy={busy}
              isFollowing={isFollowing}
              userFallback={t("common.user")}
            />
          </motion.div>
        </AnimatePresence>
      </div>

      {onDismiss ? (
        <button
          type="button"
          onClick={onDismiss}
          className="mt-8 rounded-full border border-white/25 px-5 py-2.5 text-sm font-semibold text-white/85 active:scale-95"
        >
          {t("posts.viewFollowingPosts")}
        </button>
      ) : null}
    </div>
  );
}
