import { ArrowRight, Image as ImageIcon, Loader2, Reply, SmilePlus, X } from "lucide-react";
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
import { useRef, useState } from "react";
import EmojiPicker from "./EmojiPicker";
import type { MessageList } from "../../../src/api/types/models";
import { useAuthToken } from "../../hooks/use-root-data";
import { getApiBaseUrl } from "../../utils/api-config";
import { toast } from "../../hooks/use-toast";

const MAX_IMAGE_BYTES = 8 * 1024 * 1024;
const ALLOWED_IMAGE_TYPES = ["image/jpeg", "image/jpg", "image/png", "image/webp", "image/heic", "image/heif"];

// Message input component
//
// `canSendImage` toggles the paperclip button — only team members (owner or
// active staff of the thread's seller) can attach images. The buyer side
// leaves it off so customers can only send text.
const MessageInput = ({
  onSend,
  onSendImage,
  canSendImage = false,
  replyToMessage,
  onCancelReply,
  messageText,
  setMessageText,
  isSendingMessage,
  setReplyToMessage,
}: {
  onSend: (text: string) => void;
  onSendImage?: (imageUrl: string) => void;
  canSendImage?: boolean;
  replyToMessage: MessageList | undefined;
  onCancelReply: () => void;
  inputRef: React.RefObject<HTMLInputElement>;
  messageText: string;
  setMessageText: React.Dispatch<React.SetStateAction<string>>;
  isSendingMessage: boolean;
  setReplyToMessage: (message: MessageList | undefined) => void;
}) => {
  const token = useAuthToken();
  const apiBase = getApiBaseUrl();
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [isUploadingImage, setIsUploadingImage] = useState(false);
  const [caretPosition, setCaretPosition] = useState<number | null>(null);
  // Track current textarea height

  const handleSend = () => {
    if (!messageText.trim() || isSendingMessage) return;
    onSend(messageText.trim());
  };

  // Handle emoji selection
  const handleSelectEmoji = (selectedEmoji: string) => {
    if (textareaRef.current) {
      // Get current cursor position
      const cursorPosition =
        caretPosition !== null
          ? caretPosition
          : textareaRef.current.selectionStart;

      // Insert emoji at cursor position
      const newText =
        messageText.substring(0, cursorPosition) +
        selectedEmoji +
        messageText.substring(cursorPosition);

      setMessageText(newText);

      // After state update, set cursor position after the inserted emoji
      setTimeout(() => {
        if (textareaRef.current) {
          const newPosition = cursorPosition + selectedEmoji.length;
          textareaRef.current.focus();
          textareaRef.current.setSelectionRange(newPosition, newPosition);
        }
      }, 0);
    } else {
      // Fallback if ref not available
      setMessageText((prev) => prev + selectedEmoji);
    }
  };

  // Store caret position on selection change
  const handleTextareaSelect = () => {
    if (textareaRef.current) {
      setCaretPosition(textareaRef.current.selectionStart);
    }
  };

  // Auto-growing textarea ref
  const textareaRef = useRef<HTMLTextAreaElement>(null);

  // Handle text change and update height
  const handleTextChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
    setMessageText(e.target.value);
  };

  const handlePickImage = () => {
    if (!canSendImage || isUploadingImage) return;
    fileInputRef.current?.click();
  };

  const handleFileSelected = async (
    e: React.ChangeEvent<HTMLInputElement>,
  ) => {
    const file = e.target.files?.[0];
    // Reset the input so the same file can be re-picked after cancel.
    if (e.target) e.target.value = "";
    if (!file || !canSendImage || !onSendImage) return;

    if (!ALLOWED_IMAGE_TYPES.includes(file.type)) {
      toast({
        title: "فرمت پشتیبانی نمی‌شود",
        description: "فقط تصاویر JPG / PNG / WebP / HEIC مجاز است.",
        variant: "destructive",
      });
      return;
    }
    if (file.size > MAX_IMAGE_BYTES) {
      toast({
        title: "حجم زیاد",
        description: "حداکثر حجم تصویر ۸ مگابایت است.",
        variant: "destructive",
      });
      return;
    }

    setIsUploadingImage(true);
    try {
      const form = new FormData();
      form.append("file", file);
      form.append("usage", "chat");
      const headers: Record<string, string> = {};
      if (token) headers["Authorization"] = `Bearer ${token}`;
      const res = await fetch(`${apiBase}/api/media/v1/upload/`, {
        method: "POST",
        headers,
        body: form,
      });
      if (!res.ok) throw new Error(`upload failed: ${res.status}`);
      const data = await res.json();
      const url: string | undefined = data.originalUrl || data.original_url;
      if (!url) throw new Error("no url in upload response");
      onSendImage(url);
    } catch (err) {
      console.error("chat image upload failed:", err);
      toast({
        title: "خطا در ارسال تصویر",
        description: "لطفاً دوباره تلاش کنید.",
        variant: "destructive",
      });
    } finally {
      setIsUploadingImage(false);
    }
  };

  return (
    <>
      {/* Reply indicator */}
      {replyToMessage && (
        <div className="max-w-md mx-auto bg-GRAY1 p-2 mb-2 rounded-lg flex items-center">
          <div className="flex-1 text-GRAY overflow-hidden">
            <p className="text-R12">در پاسخ به:</p>
            <p className="text-R14 truncate">{replyToMessage.content}</p>
          </div>
          <button onClick={() => setReplyToMessage(undefined)} className="ml-2">
            <X className="h-5 w-5 text-GRAY" />
          </button>
        </div>
      )}
      <div className="max-w-md mx-auto fixed px-2 bottom-0 pt-2 pb-[calc(0.5rem_+_env(safe-area-inset-bottom))] w-full bg-WHITE">
        {replyToMessage && (
          <div className="bg-GRAY3 rounded-lg p-2 flex justify-between items-center mb-2">
            <div className="flex items-center">
              <Reply className="w-4 h-4 mr-2" />
              <span className="text-sm truncate max-w-[250px]">
                {replyToMessage.content}
              </span>
            </div>
            <button
              onClick={onCancelReply}
              className="text-GRAY hover:text-BLACK2"
              aria-label="حذف پاسخ"
            >
              <X className="w-4 h-4" />
            </button>
          </div>
        )}

        <div className="relative rounded-[12px] bg-WHITE3 flex items-end">
          <Popover>
            <PopoverTrigger asChild>
              <button
                className="absolute right-3 bottom-3 w-6 h-6 flex items-center justify-center"
                aria-label="انتخاب ایموجی"
              >
                <SmilePlus className="text-GRAY hover:text-BLACK" size={20} />
              </button>
            </PopoverTrigger>
            <PopoverContent
              align="start"
              side="top"
              className="w-[280px] p-0"
              sideOffset={5}
            >
              <EmojiPicker onSelectEmoji={handleSelectEmoji} />
            </PopoverContent>
          </Popover>

          {canSendImage && (
            <>
              <input
                ref={fileInputRef}
                type="file"
                accept={ALLOWED_IMAGE_TYPES.join(",")}
                onChange={handleFileSelected}
                className="hidden"
              />
              <button
                type="button"
                onClick={handlePickImage}
                disabled={isUploadingImage}
                className="absolute right-10 bottom-3 w-6 h-6 flex items-center justify-center disabled:opacity-50"
                aria-label="ارسال تصویر"
              >
                {isUploadingImage ? (
                  <Loader2 className="w-5 h-5 animate-spin text-GRAY" />
                ) : (
                  <ImageIcon className="w-5 h-5 text-GRAY hover:text-BLACK" />
                )}
              </button>
            </>
          )}

          <textarea
            ref={textareaRef}
            value={messageText}
            onChange={handleTextChange}
            onSelect={handleTextareaSelect}
            placeholder={
              replyToMessage
                ? "پاسخ خود را بنویسید..."
                : "پیام خود را بنویسید..."
            }
            className="hide-scrollbar overflow-y-auto h-12 flex w-full rounded-[12px] border border-input bg-transparent px-3 pr-10 py-2 text-base shadow-sm resize-none outline-none transition-height duration-100"
            style={{
              paddingRight: canSendImage ? "72px" : "40px",
              paddingLeft: "48px",
              direction: "rtl",
            }}
            // Enter inserts a newline. Send is via the button only — matches
            // seller request: multi-line messages are common when replying to
            // a customer with details, and accidental Enter-sends were noisy.
          />
          <button
            onClick={handleSend}
            disabled={!messageText.trim()}
            className="absolute left-3 bottom-2 p-2 bg-BLUE2 text-WHITE rounded-full flex items-center justify-center disabled:opacity-50"
            aria-label="ارسال پیام"
          >
            {isSendingMessage ? (
              <Loader2 className="w-4 h-4 animate-spin" />
            ) : (
              <ArrowRight className="w-4 h-4 transform rotate-180" />
            )}
          </button>
        </div>
      </div>
    </>
  );
};
export default MessageInput;
