"use client";

import React, {
  useCallback,
  useEffect,
  useLayoutEffect,
  useRef,
  useState,
} from "react";
import Image from "next/image";
import Link from "next/link";
import toast from "react-hot-toast";
import { StoryFeedUser, StoryTextOverlay } from "@/api/fetchStories";
import { markStoryViewed, updateStoryOverlays } from "@/api/fetchStories";
import { buildStorageUrl } from "@/components/main/BaseUrl";
import BoldIcon from "@/components/ui/BoldIcon";
import StoryEditor from "@/components/stories/StoryEditor";

const IMAGE_DURATION_MS = 5000;

type StoryViewerProps = {
  feed: StoryFeedUser[];
  initialUserIndex: number;
  onClose: () => void;
  token: string;
  viewerId?: string | null;
};

export default function StoryViewer({
  feed,
  initialUserIndex,
  onClose,
  token,
  viewerId,
}: StoryViewerProps) {
  const [userIndex, setUserIndex] = useState(initialUserIndex);
  const [storyIndex, setStoryIndex] = useState(0);
  const [progress, setProgress] = useState(0);
  const [paused, setPaused] = useState(false);
  const [editing, setEditing] = useState(false);
  const [draftOverlays, setDraftOverlays] = useState<StoryTextOverlay[]>([]);
  const [savingEdit, setSavingEdit] = useState(false);
  const [overlayOverrides, setOverlayOverrides] = useState<
    Record<string, StoryTextOverlay[]>
  >({});
  const [mediaWidth, setMediaWidth] = useState(0);
  const mediaBoxRef = useRef<HTMLDivElement | null>(null);
  const videoRef = useRef<HTMLVideoElement | null>(null);
  const timerRef = useRef<number | null>(null);
  const startRef = useRef<number>(0);
  const elapsedRef = useRef(0);

  const currentUser = feed[userIndex];
  const currentStory = currentUser?.stories[storyIndex];

  const goNext = useCallback(() => {
    if (!currentUser) return;
    if (storyIndex < currentUser.stories.length - 1) {
      setStoryIndex((i) => i + 1);
      setProgress(0);
      elapsedRef.current = 0;
      return;
    }
    if (userIndex < feed.length - 1) {
      setUserIndex((i) => i + 1);
      setStoryIndex(0);
      setProgress(0);
      elapsedRef.current = 0;
      return;
    }
    onClose();
  }, [currentUser, storyIndex, userIndex, feed.length, onClose]);

  const goPrev = useCallback(() => {
    if (storyIndex > 0) {
      setStoryIndex((i) => i - 1);
      setProgress(0);
      elapsedRef.current = 0;
      return;
    }
    if (userIndex > 0) {
      const prevUser = feed[userIndex - 1];
      setUserIndex((i) => i - 1);
      setStoryIndex(Math.max(0, prevUser.stories.length - 1));
      setProgress(0);
      elapsedRef.current = 0;
    }
  }, [storyIndex, userIndex, feed]);

  useEffect(() => {
    if (!currentStory?._id) return;
    markStoryViewed(currentStory._id, token);
  }, [currentStory?._id, token]);

  useLayoutEffect(() => {
    const el = mediaBoxRef.current;
    if (!el) return;
    const update = () => setMediaWidth(el.clientWidth);
    update();
    const ro = new ResizeObserver(update);
    ro.observe(el);
    return () => ro.disconnect();
  }, []);

  useEffect(() => {
    if (!currentStory || paused || editing) return;

    if (currentStory.media_type === "video") {
      const video = videoRef.current;
      if (!video) return;
      video.currentTime = 0;
      video.play().catch(() => {});
      const onTimeUpdate = () => {
        if (video.duration) {
          setProgress(video.currentTime / video.duration);
        }
      };
      const onEnded = () => goNext();
      video.addEventListener("timeupdate", onTimeUpdate);
      video.addEventListener("ended", onEnded);
      return () => {
        video.removeEventListener("timeupdate", onTimeUpdate);
        video.removeEventListener("ended", onEnded);
      };
    }

    startRef.current = Date.now();
    const tick = () => {
      const elapsed = elapsedRef.current + (Date.now() - startRef.current);
      const p = Math.min(elapsed / IMAGE_DURATION_MS, 1);
      setProgress(p);
      if (p >= 1) {
        goNext();
        return;
      }
      timerRef.current = window.requestAnimationFrame(tick);
    };
    timerRef.current = window.requestAnimationFrame(tick);
    return () => {
      if (timerRef.current) cancelAnimationFrame(timerRef.current);
    };
  }, [currentStory, paused, editing, goNext]);

  useEffect(() => {
    elapsedRef.current = 0;
    setProgress(0);
  }, [userIndex, storyIndex]);

  const handlePointerDown = () => {
    setPaused(true);
    if (videoRef.current) videoRef.current.pause();
    elapsedRef.current += Date.now() - startRef.current;
  };

  const handlePointerUp = () => {
    setPaused(false);
    startRef.current = Date.now();
    if (videoRef.current && currentStory?.media_type === "video") {
      videoRef.current.play().catch(() => {});
    }
  };

  if (!currentUser || !currentStory) return null;

  const mediaSrc = currentStory.media_path.startsWith("http")
    ? currentStory.media_path
    : buildStorageUrl(currentStory.media_path);

  const currentOverlays =
    overlayOverrides[currentStory._id] ?? currentStory.overlays ?? [];
  const isOwnStory = Boolean(viewerId && currentUser.user._id === viewerId);

  const openEditor = () => {
    setDraftOverlays(currentOverlays.map((o) => ({ ...o })));
    setEditing(true);
    setPaused(true);
    if (videoRef.current) videoRef.current.pause();
  };

  const closeEditor = () => {
    setEditing(false);
    setPaused(false);
    startRef.current = Date.now();
  };

  const saveEditor = async () => {
    setSavingEdit(true);
    try {
      await updateStoryOverlays(currentStory._id, draftOverlays, token);
      setOverlayOverrides((prev) => ({
        ...prev,
        [currentStory._id]: draftOverlays,
      }));
      toast.success("استوری ویرایش شد");
      closeEditor();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "خطا در ویرایش استوری");
    } finally {
      setSavingEdit(false);
    }
  };

  const displayName =
    currentUser.user.user_name ||
    [currentUser.user.first_name, currentUser.user.last_name]
      .filter(Boolean)
      .join(" ");

  return (
    <div className="fixed inset-0 z-[1000] flex items-center justify-center bg-black">
      {/* Progress bars */}
      <div className="absolute left-0 right-0 top-0 z-20 flex gap-1 px-2 pt-[calc(0.5rem+env(safe-area-inset-top))]">
        {currentUser.stories.map((_, idx) => (
          <div
            key={idx}
            className="h-[2px] flex-1 overflow-hidden rounded-full bg-white/30"
          >
            <div
              className="h-full bg-white transition-all duration-100 ease-linear"
              style={{
                width:
                  idx < storyIndex
                    ? "100%"
                    : idx === storyIndex
                      ? `${progress * 100}%`
                      : "0%",
              }}
            />
          </div>
        ))}
      </div>

      {/* Header */}
      <div className="absolute left-0 right-0 top-[calc(1.25rem+env(safe-area-inset-top))] z-20 flex items-center justify-between px-3">
        <Link
          href={`/users/${currentUser.user.user_name}`}
          className="flex items-center gap-2"
        >
          <div className="relative h-8 w-8 overflow-hidden rounded-full ring-1 ring-white/40">
            <Image
              src={
                currentUser.user.profile_image
                  ? buildStorageUrl(currentUser.user.profile_image)
                  : "/images/fake-avatar.png"
              }
              alt=""
              fill
              className="object-cover"
              unoptimized
            />
          </div>
          <span className="text-sm font-semibold text-white drop-shadow">
            {displayName}
          </span>
          <span className="text-xs text-white/70">
            {formatStoryTime(currentStory.createdAt)}
          </span>
        </Link>
        <div className="flex items-center gap-1">
          {isOwnStory && (
            <button
              type="button"
              onClick={openEditor}
              className="flex h-9 items-center gap-1 rounded-full bg-white/15 px-3 text-xs font-semibold text-white backdrop-blur"
              aria-label="ویرایش استوری"
            >
              <BoldIcon name="edit" size={16} tinted className="text-white" />
              ویرایش
            </button>
          )}
          <button
            type="button"
            onClick={onClose}
            className="flex h-9 w-9 items-center justify-center text-white"
            aria-label="بستن"
          >
            <BoldIcon name="close-circle" size={24} tinted className="text-white" />
          </button>
        </div>
      </div>

      {/* Media */}
      <div ref={mediaBoxRef} className="relative h-full w-full max-w-lg">
        {currentStory.media_type === "video" ? (
          <video
            ref={videoRef}
            src={mediaSrc}
            className="h-full w-full object-contain"
            playsInline
            muted={false}
          />
        ) : (
          <Image
            src={mediaSrc}
            alt=""
            fill
            className="object-contain"
            priority
            unoptimized
          />
        )}

        {/* Text overlays */}
        {currentOverlays.map((o, idx) => (
          <div
            key={idx}
            style={{
              position: "absolute",
              left: `${o.x * 100}%`,
              top: `${o.y * 100}%`,
              transform: `translate(-50%, -50%) rotate(${o.rotation ?? 0}deg)`,
              color: o.color,
              fontSize: `${Math.max(10, o.font_size * (mediaWidth || 380))}px`,
              lineHeight: 1.2,
              fontWeight: 700,
              textAlign: (o.align ?? "center") as React.CSSProperties["textAlign"],
              background: o.background || "transparent",
              padding: o.background ? "0.15em 0.35em" : 0,
              borderRadius: o.background ? "0.35em" : 0,
              maxWidth: "90%",
              whiteSpace: "pre-wrap",
              wordBreak: "break-word",
              pointerEvents: "none",
              textShadow: o.background ? "none" : "0 1px 3px rgba(0,0,0,0.55)",
            }}
          >
            {o.text}
          </div>
        ))}
      </div>

      {/* Tap zones */}
      <button
        type="button"
        className="absolute left-0 top-0 z-10 h-full w-[35%]"
        aria-label="قبلی"
        onClick={goPrev}
        onPointerDown={handlePointerDown}
        onPointerUp={handlePointerUp}
        onPointerLeave={handlePointerUp}
      />
      <button
        type="button"
        className="absolute right-0 top-0 z-10 h-full w-[65%]"
        aria-label="بعدی"
        onClick={goNext}
        onPointerDown={handlePointerDown}
        onPointerUp={handlePointerUp}
        onPointerLeave={handlePointerUp}
      />

      {/* Edit overlays modal */}
      {editing && (
        <div className="absolute inset-0 z-30 flex flex-col overflow-y-auto bg-black/95 pb-6 pt-[calc(0.75rem+env(safe-area-inset-top))]">
          <div className="flex items-center justify-between px-4 pb-2">
            <button
              type="button"
              onClick={closeEditor}
              className="text-sm text-white/70"
            >
              انصراف
            </button>
            <span className="text-sm font-semibold text-white">ویرایش استوری</span>
            <button
              type="button"
              onClick={saveEditor}
              disabled={savingEdit}
              className="text-sm font-semibold text-[#0095f6] disabled:opacity-40"
            >
              {savingEdit ? "…" : "ذخیره"}
            </button>
          </div>
          <StoryEditor
            mediaUrl={mediaSrc}
            mediaType={currentStory.media_type}
            overlays={draftOverlays}
            onChange={setDraftOverlays}
          />
        </div>
      )}
    </div>
  );
}

function formatStoryTime(value?: string): string {
  if (!value) return "";
  const diff = Date.now() - Date.parse(value);
  const hours = Math.floor(diff / (1000 * 60 * 60));
  if (hours < 1) return "اکنون";
  if (hours < 24) return `${hours} س`;
  return "دیروز";
}
