/* eslint-disable react-hooks/rules-of-hooks */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { MessageStatus } from "../../types/type";
import { useChatContext } from "../../providers/ChatProvider";
import { FileType } from "../common/FilePreview";
import { getChatConfig } from "../../Chat.config";
import { Path } from "../../lib/api/endpoint";
import { MoreHorizontal, Pencil, Trash2 } from "lucide-react";
import { useEditMessageMutation } from "../../hooks/mutations/useEditMessage";
import { useDeleteMessageMutation } from "../../hooks/mutations/useDeleteMessage";
import { useEffect, useRef, useState } from "react";
import BookingCard from "./BookingCard";

interface MessageProps {
  message: {
    _id?: string;
    sender: {
      senderId: string;
      role: string;
    };
    message: string;
    status: MessageStatus;
    createdAt: any;
    updatedAt: any;
    media?: {
      type: FileType;
      url: string;
      name: string;
      size: number;
      uploadProgress?: number;
      uploadError: string | null;
    }[];
    isUploading?: boolean;
    isEdited?: boolean;
    isDeleted?: boolean;
    onEdit?: (messageId: string, newMessage: string) => void;
    onDelete?: (messageId: string) => void;
    type?: "user" | "system" | "system-completion";
    meta?: {
      bookingDetails?: {
        bookingId: string;
        status: string; // e.g., "confirmed", "pending", "cancelled"
        serviceId: string;
        serviceName: string;
        date: string;
        time: string;
        price: number;
        // Add other booking details as needed
      };
      reviewLink?: string;
    };
  };
}

const Message = ({ message }: MessageProps) => {
  const { userId } = useChatContext();
  const { apiUrl, cdnUrl, role: role1 } = getChatConfig();

  if (message.type === "system") {
    const booking = message.meta?.bookingDetails;
    const status = booking?.status || "Pending"; // Default to Pending
    const role = role1; // "provider" or "customer"

    const handleConfirm = () => {
      console.log("Booking confirmed!");
      window.location.href = `/booking/all#${message.meta?.bookingDetails?.bookingId}`;
      // Update booking status to Confirmed
    };

    const handleInProgress = () => {
      console.log("Booking started (In Progress)");
      window.location.href = `/booking/all#${message.meta?.bookingDetails?.bookingId}`;
      // Update booking status to InProgress
    };

    const handleComplete = () => {
      console.log("Booking completed!");
      window.location.href = `/booking/all#${message.meta?.bookingDetails?.bookingId}`;
      // Update booking status to Completed
    };

    const handleReview = () => {
      if (role === "customer") {
        console.log("Navigate to review page for customer → provider");
        window.location.href = `/customer/customer-booking?bookingId=${message.meta?.bookingDetails?.bookingId}`;
      } else if (role === "provider") {
        console.log("Navigate to review page for provider → customer");
        window.location.href = `/booking/all#${message.meta?.bookingDetails?.bookingId}`;
      }
    };

    return (
      <div className="system-message">
        <BookingCard
          data={{ ...booking, status }}
          actions={
            <>
              {role === "provider" && status === "Pending" && (
                <button
                  className="chat-btn chat-btn--primary chat-btn--sm"
                  onClick={handleConfirm}
                >
                  Confirm Booking
                </button>
              )}

              {role === "provider" && status === "Confirmed" && (
                <button
                  className="chat-btn chat-btn--primary chat-btn--sm"
                  onClick={handleInProgress}
                >
                  Start Service
                </button>
              )}

              {role === "provider" && status === "InProgress" && (
                <button
                  className="chat-btn chat-btn--primary chat-btn--sm"
                  onClick={handleComplete}
                >
                  Mark as Completed
                </button>
              )}

              {status === "Completed" && role !== "provider" && (
                <button
                  className="chat-btn chat-btn--primary chat-btn--sm"
                  onClick={handleReview}
                >
                  Leave a Review
                </button>
              )}
            </>
          }
        />
      </div>
    );
  }

  if (message.type === "system-completion") {
    return (
      <div className="system-message">
        <BookingCard
          data={{ status: "Completed" }}
          actions={
            <a
              className="chat-btn chat-btn--primary chat-btn--sm"
              href={message.meta?.reviewLink || "#"}
            >
              Leave a Review
            </a>
          }
        />
      </div>
    );
  }

  const fromMe = message.sender?.senderId === userId;
  const timestamp = fromMe ? "timestamp_outgoing" : "timestamp_incomeing";
  const alignItems = fromMe ? "outgoing" : "incoming";
  const [localStatus, setLocalStatus] = useState(message.status);

  const [showOptions, setShowOptions] = useState(false);
  const [showDeleteOption, setShowDeleteOption] = useState(false);
  const editInputRef = useRef<HTMLInputElement>(null);
  const optionsRef = useRef<HTMLDivElement>(null);
  const { mutate: editMessage } = useEditMessageMutation();
  const [editedMessage, setEditedMessage] = useState("");
  const [isEditingMode, setIsEditingMode] = useState(false);
  const { mutate: deleteMessage, isPending: isDeleting } =
    useDeleteMessageMutation();

  useEffect(() => {
    setLocalStatus(message.status);
  }, [message.status]);

  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (
        optionsRef.current &&
        !optionsRef.current.contains(e.target as Node)
      ) {
        setShowOptions(false);
        setShowDeleteOption(false);
      }
    };

    if (showOptions || showDeleteOption) {
      document.addEventListener("mousedown", handleClickOutside);
    }

    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, [showOptions, showDeleteOption]);

  // const handleDownload = (url: string, name: string) => {
  //   saveAs(url, name);
  // };

  const [downloadingIndex, setDownloadingIndex] = useState<number | null>(null);
  const [downloadProgress, setDownloadProgress] = useState<number>(0);
  const [downloadController, setDownloadController] =
    useState<AbortController | null>(null);

  const getStatusIcon = () => {
    if (!fromMe) return null;

    if (message.isUploading || message.status === "sending") {
      return <span className="message-status uploading">🔄</span>;
    }

    if (message.status === "failed") {
      return <span className="message-status failed">❌</span>;
    }

    switch (localStatus) {
      case "sending":
        return <span className="message-status sending">🔄</span>;
      case "sent":
        return (
          <span className="message-status sent">
            <svg
              viewBox="0 0 12 11"
              height="11"
              width="16"
              preserveAspectRatio="xMidYMid meet"
              fill="none"
            >
              <title>msg-check</title>
              <path
                d="M11.1549 0.652832C11.0745 0.585124 10.9729 0.55127 10.8502 0.55127C10.7021 0.55127 10.5751 0.610514 10.4693 0.729004L4.28038 8.36523L1.87461 6.09277C1.8323 6.04622 1.78151 6.01025 1.72227 5.98486C1.66303 5.95947 1.60166 5.94678 1.53819 5.94678C1.407 5.94678 1.29275 5.99544 1.19541 6.09277L0.884379 6.40381C0.79128 6.49268 0.744731 6.60482 0.744731 6.74023C0.744731 6.87565 0.79128 6.98991 0.884379 7.08301L3.88047 10.0791C4.02859 10.2145 4.19574 10.2822 4.38194 10.2822C4.48773 10.2822 4.58929 10.259 4.68663 10.2124C4.78396 10.1659 4.86436 10.1003 4.92784 10.0156L11.5738 1.59863C11.6458 1.5013 11.6817 1.40186 11.6817 1.30029C11.6817 1.14372 11.6183 1.01888 11.4913 0.925781L11.1549 0.652832Z"
                fill="currentcolor"
              ></path>
            </svg>
          </span>
        );
      case "delivered":
        return (
          <span className="message-status delivered">
            <svg
              viewBox="0 0 16 11"
              height="11"
              width="16"
              preserveAspectRatio="xMidYMid meet"
              fill="none"
            >
              <title>msg-dblcheck</title>
              <path
                d="M11.0714 0.652832C10.991 0.585124 10.8894 0.55127 10.7667 0.55127C10.6186 0.55127 10.4916 0.610514 10.3858 0.729004L4.19688 8.36523L1.79112 6.09277C1.7488 6.04622 1.69802 6.01025 1.63877 5.98486C1.57953 5.95947 1.51817 5.94678 1.45469 5.94678C1.32351 5.94678 1.20925 5.99544 1.11192 6.09277L0.800883 6.40381C0.707784 6.49268 0.661235 6.60482 0.661235 6.74023C0.661235 6.87565 0.707784 6.98991 0.800883 7.08301L3.79698 10.0791C3.94509 10.2145 4.11224 10.2822 4.29844 10.2822C4.40424 10.2822 4.5058 10.259 4.60313 10.2124C4.70046 10.1659 4.78086 10.1003 4.84434 10.0156L11.4903 1.59863C11.5623 1.5013 11.5982 1.40186 11.5982 1.30029C11.5982 1.14372 11.5348 1.01888 11.4078 0.925781L11.0714 0.652832ZM8.6212 8.32715C8.43077 8.20866 8.2488 8.09017 8.0753 7.97168C7.99489 7.89128 7.8891 7.85107 7.75791 7.85107C7.6098 7.85107 7.4892 7.90397 7.3961 8.00977L7.10411 8.33984C7.01947 8.43717 6.97715 8.54508 6.97715 8.66357C6.97715 8.79476 7.0237 8.90902 7.1168 9.00635L8.1959 10.0791C8.33132 10.2145 8.49636 10.2822 8.69102 10.2822C8.79681 10.2822 8.89838 10.259 8.99571 10.2124C9.09304 10.1659 9.17556 10.1003 9.24327 10.0156L15.8639 1.62402C15.9358 1.53939 15.9718 1.43994 15.9718 1.32568C15.9718 1.1818 15.9125 1.05697 15.794 0.951172L15.4386 0.678223C15.3582 0.610514 15.2587 0.57666 15.1402 0.57666C14.9964 0.57666 14.8715 0.635905 14.7657 0.754395L8.6212 8.32715Z"
                fill="currentColor"
              ></path>
            </svg>
          </span>
        );
      case "read":
        return (
          <span className="message-status read">
            <svg
              viewBox="0 0 16 11"
              height="11"
              width="16"
              preserveAspectRatio="xMidYMid meet"
              fill="none"
            >
              <title>msg-dblcheck</title>
              <path
                d="M11.0714 0.652832C10.991 0.585124 10.8894 0.55127 10.7667 0.55127C10.6186 0.55127 10.4916 0.610514 10.3858 0.729004L4.19688 8.36523L1.79112 6.09277C1.7488 6.04622 1.69802 6.01025 1.63877 5.98486C1.57953 5.95947 1.51817 5.94678 1.45469 5.94678C1.32351 5.94678 1.20925 5.99544 1.11192 6.09277L0.800883 6.40381C0.707784 6.49268 0.661235 6.60482 0.661235 6.74023C0.661235 6.87565 0.707784 6.98991 0.800883 7.08301L3.79698 10.0791C3.94509 10.2145 4.11224 10.2822 4.29844 10.2822C4.40424 10.2822 4.5058 10.259 4.60313 10.2124C4.70046 10.1659 4.78086 10.1003 4.84434 10.0156L11.4903 1.59863C11.5623 1.5013 11.5982 1.40186 11.5982 1.30029C11.5982 1.14372 11.5348 1.01888 11.4078 0.925781L11.0714 0.652832ZM8.6212 8.32715C8.43077 8.20866 8.2488 8.09017 8.0753 7.97168C7.99489 7.89128 7.8891 7.85107 7.75791 7.85107C7.6098 7.85107 7.4892 7.90397 7.3961 8.00977L7.10411 8.33984C7.01947 8.43717 6.97715 8.54508 6.97715 8.66357C6.97715 8.79476 7.0237 8.90902 7.1168 9.00635L8.1959 10.0791C8.33132 10.2145 8.49636 10.2822 8.69102 10.2822C8.79681 10.2822 8.89838 10.259 8.99571 10.2124C9.09304 10.1659 9.17556 10.1003 9.24327 10.0156L15.8639 1.62402C15.9358 1.53939 15.9718 1.43994 15.9718 1.32568C15.9718 1.1818 15.9125 1.05697 15.794 0.951172L15.4386 0.678223C15.3582 0.610514 15.2587 0.57666 15.1402 0.57666C14.9964 0.57666 14.8715 0.635905 14.7657 0.754395L8.6212 8.32715Z"
                fill="currentColor"
              ></path>
            </svg>
          </span>
        );
      case "edited":
        return <span className="message-status edited">Edited</span>;
      case "deleted":
        return <span className="message-status deleted">Deleted</span>;
      default:
        return null;
    }
  };

  const cancelDownload = () => {
    if (downloadController) {
      downloadController.abort();
      setDownloadingIndex(null);
      setDownloadProgress(0);
      setDownloadController(null);
    }
  };

  const handleDownload = async (url: string, name: string, index: number) => {
    setDownloadingIndex(index);
    setDownloadProgress(0);

    const controller = new AbortController();
    setDownloadController(controller);

    try {
      try {
        const response = await fetch(
          `${apiUrl}${Path.apiProxy}?url=${encodeURIComponent(
            url
          )}&name=${encodeURIComponent(name)}`
        );

        if (!response.ok) throw new Error("Network response was not ok");

        const contentLength = response.headers.get("content-length");
        const total = contentLength ? Number.parseInt(contentLength, 10) : 0;

        const reader = response.body?.getReader();
        if (!reader) throw new Error("Failed to get response reader");

        let receivedLength = 0;
        const chunks: Uint8Array[] = [];

        while (true) {
          const { done, value } = await reader.read();
          if (done) break;

          chunks.push(value);
          receivedLength += value.length;

          if (total) {
            const progress = Math.round((receivedLength / total) * 100);
            setDownloadProgress(progress);
          }
        }

        const chunksAll = new Uint8Array(receivedLength);
        let position = 0;
        for (const chunk of chunks) {
          chunksAll.set(chunk, position);
          position += chunk.length;
        }

        const blob = new Blob([chunksAll]);
        const link = document.createElement("a");
        link.href = URL.createObjectURL(blob);
        link.download = name;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        URL.revokeObjectURL(link.href);
      } catch (directDownloadError) {
        console.log(
          "Direct download failed, trying alternative method",
          directDownloadError
        );

        // Fallback: Open in new tab if download fails
        window.open(url, "_blank");
      }
    } catch (error) {
      if ((error as Error).name === "AbortError") {
        console.log("Download was cancelled");
      } else {
        console.error("Download failed:", error);
        // Final fallback - create a temporary link
        const link = document.createElement("a");
        link.href = url;
        link.target = "_blank";
        link.rel = "noopener noreferrer";
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      }
    } finally {
      setDownloadingIndex(null);
      setDownloadProgress(0);
      setDownloadController(null);
    }
  };

  const renderMedia = () => {
    if (!message.media || message.media.length === 0) return null;

    return (
      <div
        className={`media-grid ${
          message.media.length > 1 ? "multi-media" : "single-media"
        }`}
      >
        {message.media.map((media, index) => (
          <div key={index} className="media-item">
            {/* Progress indicator */}
            {message.isUploading &&
              media.uploadProgress !== undefined &&
              media.uploadProgress < 100 && (
                <>
                  <div className="circular-progress-container">
                    <div className="media-preview-background">
                      <img
                        src={`${cdnUrl}${media.url}`}
                        alt={media.name}
                        className="blurred-preview"
                      />
                    </div>
                    <div className="circular-progress">
                      <svg
                        className="circular-progress-svg"
                        viewBox="0 0 36 36"
                      >
                        <path
                          className="circular-progress-track"
                          d="M18 2.0845
                      a 15.9155 15.9155 0 0 1 0 31.831
                      a 15.9155 15.9155 0 0 1 0 -31.831"
                        />
                        <path
                          className="circular-progress-bar"
                          strokeDasharray={`${media.uploadProgress}, 100`}
                          d="M18 2.0845
                      a 15.9155 15.9155 0 0 1 0 31.831
                      a 15.9155 15.9155 0 0 1 0 -31.831"
                        />
                      </svg>
                      <span className="circular-progress-text">
                        {media.uploadProgress}%
                      </span>
                    </div>
                  </div>
                </>
              )}

            {/* Error state */}
            {media.uploadError && (
              <div className="upload-error">
                <span>⚠️ Upload failed</span>
              </div>
            )}

            {/* Actual media (shown when upload complete) */}
            {(!message.isUploading || media.uploadProgress === 100) &&
              !media.uploadError && (
                <>
                  {media.type === "image" ? (
                    <img
                      src={`${cdnUrl}${media.url}`}
                      alt={media.name}
                      className="media-content"
                      onClick={() =>
                        window.open(`${cdnUrl}${media.url}`, "_blank")
                      }
                    />
                  ) : media.type === "video" ? (
                    <video controls className="media-content">
                      <source
                        src={`${cdnUrl}${media.url}`}
                        type={`video/${`${cdnUrl}${media.url}`.split(".").pop()}`}
                      />
                    </video>
                  ) : (
                    <div className="document-preview">
                      <div className="file-icon">
                        {media.type === "document" && "📄"}
                      </div>
                      <div className="file-info"
                       onClick={() =>
                        window.open(`${cdnUrl}${media.url}`, "_blank")
                      }>
                        <span className="file-name">{media.name}</span>
                        <span className="file-size">
                          {(media.size / 1024).toFixed(1)} KB
                        </span>
                      </div>
                    </div>
                  )}
                  <button
                    className="download-btn"
                    onClick={(e) => {
                      e.stopPropagation();
                      if (downloadingIndex === index) {
                        cancelDownload();
                      } else {
                        handleDownload(
                          `${cdnUrl}${media.url}`,
                          media.name,
                          index
                        );
                      }
                    }}
                    title={downloadingIndex === index ? "Cancel" : "Download"}
                  >
                    {downloadingIndex === index ? (
                      <div className="download-progress-container">
                        <div
                          className="download-progress"
                          style={{ width: `${downloadProgress}%` }}
                        />
                        <span className="cancel-download">✕</span>
                      </div>
                    ) : (
                      "⬇️"
                    )}
                  </button>
                </>
              )}
          </div>
        ))}
      </div>
    );
  };

  const handleEditClick = (message: string) => {
    setEditedMessage(message);
    setIsEditingMode(true);
    setShowOptions(false);
    setTimeout(() => {
      editInputRef.current?.focus();
    }, 0);
  };

  const handleSaveEdit = () => {
    if (message._id && editedMessage.trim() !== message.message) {
      editMessage(
        {
          messageId: message._id ?? "",
          userId: userId, // Using userId from useChatContext
          newMessage: editedMessage.trim(),
        },
        {
          onSuccess: () => {
            setIsEditingMode(false);
            setShowOptions(false);
            setEditedMessage(""); // Clear the input after saving
            // Any additional success handling
          },
          onError: (error) => {
            // Handle error specifically for this edit
            console.error("Edit failed:", error);
          },
        }
      );
    } else {
      setIsEditingMode(false);
      setShowOptions(false);
    }
  };

  const handleCancelEdit = () => {
    setEditedMessage(message.message);
    setIsEditingMode(false);
    setShowOptions(false);
  };

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === "Enter") {
      handleSaveEdit();
    } else if (e.key === "Escape") {
      handleCancelEdit();
    }
  };

  const handleDeleteClick = () => {
    if (message._id) {
      deleteMessage(
        {
          messageId: message._id,
          userId: userId,
        },
        {
          onSuccess: () => {
            setShowDeleteOption(false);
            setShowOptions(false);
          },
          onError: (error) => {
            console.error("Delete failed:", error);
          },
        }
      );
    }
  };

  const isMessageOlderThanOneDay = (createdAt: string | Date) => {
    const messageDate = new Date(createdAt);
    const now = new Date();
    const oneDayInMs = 24 * 60 * 60 * 1000;
    return now.getTime() - messageDate.getTime() > oneDayInMs;
  };

    const formatLastMessageTime = (dateString: string) => {
    // Validate date input
    if (!dateString) {
      return "";
    }

    const date = new Date(dateString);
    
    // Check if date is valid
    if (isNaN(date.getTime())) {
      return "";
    }

    const now = new Date();

    const isToday = date.toDateString() === now.toDateString();

    const yesterday = new Date();
    yesterday.setDate(now.getDate() - 1);

    const isYesterday = date.toDateString() === yesterday.toDateString();

    if (isToday) {
      return date.toLocaleTimeString([], {
        hour: "2-digit",
        minute: "2-digit",
      });
    }

    if (isYesterday) {
      return "Yesterday";
    }

    // MM/DD format
    return date.toLocaleDateString("en-US", {
      month: "2-digit",
      day: "2-digit",
    });
  };

  const messageTime =
  message.status === "deleted" || message.status === "edited"
    ? message.updatedAt
    : message.createdAt;

  const hasMedia = message.media && message.media.length > 0;

  return (
    <div className="chat-container">
      <div className={`message-row ${alignItems}`}>
        <div
          className="bubble-container"
          ref={optionsRef}
          onMouseEnter={() => fromMe && !hasMedia && setShowOptions(true)}
          onMouseLeave={() =>
            fromMe && !showDeleteOption && setShowOptions(false)
          }
        >
          {message.status === "deleted" ? (
            <div className="chat-bubble compact-bubble deleted-message">
              <div className="message-text text-gray-900 dark:text-gray-100">
                This message was deleted
              </div>
            </div>
          ) : (
            (message.message ||
              (message.media && message.media.length > 0)) && (
              <div className="chat-bubble compact-bubble">
                {renderMedia()}
                {isEditingMode ? (
                  <div className="edit-message-container">
                    <input
                      ref={editInputRef}
                      type="text"
                      value={editedMessage}
                      onChange={(e) => setEditedMessage(e.target.value)}
                      onKeyDown={handleKeyDown}
                      className="edit-message-input"
                    />
                    <div className="edit-actions">
                      <button className="save-edit" onClick={handleSaveEdit}>
                        Save
                      </button>
                      <button
                        className="cancel-edit"
                        onClick={handleCancelEdit}
                      >
                        Cancel
                      </button>
                    </div>
                  </div>
                ) : (
                  message.message && (
                    <div className="message-text text-gray-900 dark:text-gray-100">
                      {message.message}
                    </div>
                  )
                )}

                {/* Message options for outgoing messages */}
                {fromMe &&
                  showOptions &&
                  !isEditingMode &&
                  !message.isDeleted &&
                  !hasMedia &&
                  !isMessageOlderThanOneDay(message.createdAt) && (
                    <div className="message-options">
                      <button
                        className="message-option-btn edit-btn"
                        onClick={() => handleEditClick(message.message)}
                        title="Edit"
                      >
                        <Pencil size={16} />
                      </button>
                      <div className="more-options-container">
                        <button
                          className="message-option-btn more-btn"
                          onClick={() => setShowDeleteOption(!showDeleteOption)}
                          title="More options"
                        >
                          <MoreHorizontal size={16} />
                        </button>

                        {showDeleteOption && (
                          <div className="delete-option">
                            <button
                              className="delete-btn"
                              onClick={handleDeleteClick}
                            >
                              <Trash2 size={16} />
                              <span>
                                {isDeleting ? "Deleting..." : "Delete"}
                              </span>
                            </button>
                          </div>
                        )}
                      </div>
                    </div>
                  )}
              </div>
            )
          )}
          <div className={`${timestamp}`}>
            {formatLastMessageTime(messageTime)}
            <span className="status-icon">{getStatusIcon()}</span>
          </div>
        </div>
      </div>
    </div>
  );
};

export default Message;
