"use client";

import Image from "next/image";
import { useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import Link from "next/link";
import { User } from "@/types/types";
import { IMAGE_BASE_URL, buildStorageUrl } from "@/components/main/BaseUrl";
import ReadReceipt from "./ReadReceipt";
import VoiceMessagePlayer from "./VoiceMessagePlayer";
import FileMessageBubble from "./FileMessageBubble";
import VideoMessageBubble from "./VideoMessageBubble";
import LocationMessageBubble, {
  parseLocationContent,
} from "./LocationMessageBubble";
import { detectChatFileType } from "@/lib/chat/detectFileType";
import { formatBubbleTime } from "@/lib/chat/formatMessageTime";
import { useLongPress } from "@/hooks/useLongPress";
import { FiCheck } from "react-icons/fi";
import { cn } from "@/lib/utils";

export interface ChatMessage {
  _id: string;
  content: string;
  senderId: string;
  receiverId?: string;
  createdAt: string;
  file?: string;
  fileType?: "image" | "video" | "file" | "voice" | "location";
  status?: "pending" | "sent" | "seen";
  replyTo?: {
    _id: string;
    content: string;
    senderName?: string;
  };
  forwardedFrom?: {
    userId: string;
    userName: string;
    displayName: string;
  };
}

interface ChatMessageCardProps {
  message: ChatMessage;
  userDetail: User | undefined;
  selected?: boolean;
  onBubbleClick?: (message: ChatMessage) => void;
  deleteMode?: boolean;
  selectedForDelete?: boolean;
  onToggleDeleteSelect?: (message: ChatMessage) => void;
}

const LONG_PRESS_MS = 2000;

function parseForwarded(content: string): ChatMessage["forwardedFrom"] | null {
  try {
    const line = content.split("\n")[0];
    const j = JSON.parse(line);
    return j.forwardedFrom ?? null;
  } catch {
    return null;
  }
}

const ChatMessageCard = ({
  message,
  userDetail,
  selected = false,
  onBubbleClick,
  deleteMode = false,
  selectedForDelete = false,
  onToggleDeleteSelect,
}: ChatMessageCardProps) => {
  const isSender = !!(userDetail && message.senderId === userDetail._id);
  const [preview, setPreview] = useState<string | null>(null);
  const canSelectForDelete = deleteMode && isSender && !message._id.startsWith("temp-");

  const { pressing, shouldBlockClick, handlers: longPressHandlers } =
    useLongPress(() => onBubbleClick?.(message), { delay: LONG_PRESS_MS });

  const toggleDeleteSelection = () => {
    if (canSelectForDelete) onToggleDeleteSelect?.(message);
  };

  const openPreview = (url: string) => {
    if (deleteMode) {
      toggleDeleteSelection();
      return;
    }
    if (shouldBlockClick()) return;
    setPreview(url);
  };

  const bubbleHandlers = deleteMode
    ? { onClick: toggleDeleteSelection }
    : longPressHandlers;

  const forwarded =
    message.forwardedFrom || parseForwarded(message.content || "");
  const locationData = parseLocationContent(message.content);
  const hasLocation = message.fileType === "location" || !!locationData;

  if (!message.content && !message.file && !hasLocation) return null;

  const fileUrl = message.file?.startsWith("blob:")
    ? message.file
    : message.file
      ? IMAGE_BASE_URL + message.file
      : "";

  const fileType = hasLocation
    ? "location"
    : detectChatFileType(message.file || "", message.fileType);

  const textContent =
    message.content &&
    !parseLocationContent(message.content) &&
    !forwarded
      ? message.content.replace(/^\{.*\}\n?/, "").trim()
      : message.content?.replace(/^\{.*\}\n?/, "").trim() || "";

  const showTextBubble =
    textContent &&
    fileType !== "file" &&
    fileType !== "location" &&
    (!message.file || (fileType === "image" && textContent));

  const tailClass = isSender ? "bubble-tail-out" : "bubble-tail-in";
  const timeLabel = formatBubbleTime(message.createdAt);

  const TimeInline = () => (
    <span
      className={`message-time-inline ${isSender ? "text-white/70" : "text-neutral-400"}`}
    >
      {timeLabel}
      {isSender && (
        <span className="mr-1 inline-flex align-middle">
          <ReadReceipt status={message.status} />
        </span>
      )}
    </span>
  );

  const TimeBelow = () => (
    <span
      className={`message-time-below mt-0.5 block text-[10px] tabular-nums text-neutral-400 ${isSender ? "text-left" : "text-right"}`}
    >
      {timeLabel}
      {isSender && (
        <span className="mr-1 inline-flex">
          <ReadReceipt status={message.status} />
        </span>
      )}
    </span>
  );

  return (
    <>
      <motion.div
        layout
        initial={{ opacity: 0, y: 8 }}
        animate={{ opacity: 1, y: 0 }}
        className={cn(
          "message-enter relative my-0.5 flex w-full gap-2",
          isSender ? "justify-end" : "justify-start",
          deleteMode && !isSender && "opacity-60"
        )}
        dir="rtl"
      >
        <div
          className={cn(
            "relative flex max-w-[min(88%,340px)] flex-col sm:max-w-[85%]",
            isSender ? "items-end" : "items-start"
          )}
        >
          {forwarded && (
            <Link
              href={`/users/${forwarded.userName}`}
              className="mb-0.5 text-[11px] font-semibold text-[#0095f6]"
              onClick={(e) => e.stopPropagation()}
            >
              {forwarded.displayName}
            </Link>
          )}

          {message.replyTo && (
            <div className="mb-1 max-w-full rounded-lg border-r-2 border-[#0095f6] bg-black/5 px-2 py-1 text-[11px] opacity-90 dark:bg-white/10">
              <span className="font-semibold text-[#0095f6]">
                {message.replyTo.senderName}
              </span>
              <p className="truncate">{message.replyTo.content}</p>
            </div>
          )}

          <div
            {...bubbleHandlers}
            className={cn(
              "gentle-transition relative select-none text-right outline-none touch-manipulation",
              tailClass,
              canSelectForDelete && "cursor-pointer",
              (selected || selectedForDelete) && "rounded-2xl ring-2 ring-[#0095f6]/50",
              !deleteMode && pressing && "scale-[0.98] opacity-90"
            )}
          >
            {fileType === "image" && fileUrl && (
              <div
                className="block overflow-hidden rounded-2xl"
                onClick={(e) => {
                  e.stopPropagation();
                  openPreview(fileUrl);
                }}
              >
                <div className="relative aspect-[3/4] w-44 sm:w-52">
                  <Image fill src={fileUrl} alt="" className="object-cover" sizes="208px" />
                </div>
                <TimeBelow />
              </div>
            )}

            {fileType === "video" && fileUrl && (
              <div
                className="cursor-pointer"
                onClick={(e) => {
                  e.stopPropagation();
                  openPreview(fileUrl);
                }}
              >
                <VideoMessageBubble src={fileUrl} isOutgoing={isSender} />
                <TimeBelow />
              </div>
            )}

            {fileType === "voice" && fileUrl && (
              <div className={isSender ? "chat-bubble-out rounded-2xl p-1" : "chat-bubble-in rounded-2xl p-1"}>
                <VoiceMessagePlayer src={fileUrl} isOutgoing={isSender} />
                <TimeBelow />
              </div>
            )}

            {fileType === "file" && fileUrl && (
              <div>
                <FileMessageBubble
                  url={fileUrl}
                  fileName={textContent || "فایل"}
                  isOutgoing={isSender}
                />
                <TimeBelow />
              </div>
            )}

            {fileType === "location" && locationData && (
              <div>
                <LocationMessageBubble location={locationData} isOutgoing={isSender} />
                <TimeBelow />
              </div>
            )}

            {showTextBubble && !message.file && (
              <div
                className={`chat-text-bubble ${isSender ? "chat-bubble-out" : "chat-bubble-in"} px-3 py-2 text-[15px]`}
              >
                <p className="chat-message-text">{textContent}</p>
                <TimeInline />
              </div>
            )}
          </div>
        </div>

        {canSelectForDelete && (
          <button
            type="button"
            onClick={toggleDeleteSelection}
            className={cn(
              "gentle-transition mt-1 flex h-6 w-6 shrink-0 items-center justify-center rounded-full border-2",
              selectedForDelete
                ? "border-[#0095f6] bg-[#0095f6] text-white"
                : "border-neutral-400 bg-transparent"
            )}
            aria-label={selectedForDelete ? "لغو انتخاب" : "انتخاب پیام"}
          >
            {selectedForDelete && <FiCheck size={14} strokeWidth={3} />}
          </button>
        )}
      </motion.div>

      <AnimatePresence>
        {preview && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/95"
            onClick={() => setPreview(null)}
          >
            <motion.div
              initial={{ scale: 0.9 }}
              animate={{ scale: 1 }}
              className="max-h-[92vh] max-w-[95vw] p-4"
              onClick={(e) => e.stopPropagation()}
            >
              {fileType === "video" ? (
                <video src={preview} controls autoPlay className="max-h-[88vh] rounded-lg" />
              ) : (
                // eslint-disable-next-line @next/next/no-img-element
                <img src={preview} alt="" className="max-h-[88vh] object-contain" />
              )}
            </motion.div>
          </motion.div>
        )}
      </AnimatePresence>
    </>
  );
};

export default ChatMessageCard;
