import {
  AudioOutlined,
  FileOutlined,
  PictureOutlined,
  SmileOutlined,
} from "@ant-design/icons";
import { Button, Input, Popover, Upload } from "antd";
import { TextAreaRef } from "antd/es/input/TextArea";
import { t } from "i18next";
import { UploadRequestOption } from "rc-upload/lib/interface";
import { forwardRef, ForwardRefRenderFunction, memo, useRef, useState } from "react";

import { IMSDK } from "@/layout/MainContentWrap";
import { useConversationStore } from "@/store";
import { canSendImageTypeList, feedbackToast } from "@/utils/common";

import { useFileMessage } from "./SendActionBar/useFileMessage";
import { useSendMessage } from "./useSendMessage";
import { useVoiceRecorder } from "./useVoiceRecorder";

const EMOJI_LIST = [
  "😀", "😁", "😂", "🤣", "😃", "😄", "😅", "😆",
  "😉", "😊", "😋", "😎", "😍", "😘", "🥰", "😗",
  "🙂", "🤗", "🤔", "😐", "😑", "😶", "🙄", "😏",
  "😮", "😪", "😴", "😌", "😜", "🤤", "🙃", "😇",
  "🥳", "🤠", "😭", "😢", "😤", "😠", "😡", "🤯",
  "👍", "👎", "👌", "✌️", "🤝", "👏", "🙏", "💪",
  "❤️", "💔", "💯", "🎉", "🎊", "🔥", "✨", "🌹",
];

const EmojiPanel = ({ onSelect }: { onSelect: (emoji: string) => void }) => (
  <div className="grid w-72 grid-cols-8 gap-1">
    {EMOJI_LIST.map((emoji) => (
      <div
        key={emoji}
        className="flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg text-xl hover:bg-[var(--primary-active)]"
        onClick={() => onSelect(emoji)}
      >
        {emoji}
      </div>
    ))}
  </div>
);

const ChatFooter: ForwardRefRenderFunction<unknown, unknown> = (_, _ref) => {
  const [text, setText] = useState("");
  const [sending, setSending] = useState(false);
  const [emojiVisible, setEmojiVisible] = useState(false);
  const textareaRef = useRef<TextAreaRef>(null);

  const currentConversation = useConversationStore(
    (state) => state.currentConversation,
  );

  const { getImageMessage, getFileMessage, getSoundMessage } = useFileMessage();
  const { sendMessage } = useSendMessage();

  const sendSound = async (file: File, duration: number) => {
    try {
      const message = await getSoundMessage(file, duration);
      sendMessage({ message });
    } catch (error) {
      feedbackToast({ error });
    }
  };

  const { recording, seconds, start, finish, cancel } = useVoiceRecorder(
    ({ file, duration }) => sendSound(file, duration),
  );

  const sendText = async () => {
    const cleanText = text.trim();
    if (!cleanText || sending) return;
    setSending(true);
    try {
      const message = (await IMSDK.createTextMessage(cleanText)).data;
      setText("");
      sendMessage({ message });
    } catch (error) {
      feedbackToast({ error });
    } finally {
      setSending(false);
    }
  };

  const onKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
    if (e.key === "Enter" && !e.ctrlKey && !e.metaKey && !e.shiftKey) {
      e.preventDefault();
      sendText();
      return;
    }
    if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
      e.preventDefault();
      insertAtCursor("\n");
    }
  };

  const insertAtCursor = (value: string) => {
    const textarea = textareaRef.current?.resizableTextArea?.textArea;
    if (!textarea) {
      setText((prev) => prev + value);
      return;
    }
    const startPos = textarea.selectionStart ?? text.length;
    const endPos = textarea.selectionEnd ?? text.length;
    const next = text.slice(0, startPos) + value + text.slice(endPos);
    setText(next);
    setTimeout(() => {
      textarea.focus();
      const pos = startPos + value.length;
      textarea.setSelectionRange(pos, pos);
    });
  };

  const onEmojiSelect = (emoji: string) => {
    insertAtCursor(emoji);
  };

  const sendFileMessage = async (file: File) => {
    try {
      const message = await getFileMessage(file);
      sendMessage({ message });
    } catch (error) {
      feedbackToast({ error });
    }
  };

  const sendImageMessage = async (options: UploadRequestOption) => {
    const file = options.file as File;
    const ext = file.name.split(".").pop()?.toLowerCase() ?? "";
    if (file.type.startsWith("image/") || canSendImageTypeList.includes(ext)) {
      try {
        const message = await getImageMessage(file);
        sendMessage({ message });
      } catch (error) {
        feedbackToast({ error });
      }
      return;
    }
    sendFileMessage(file);
  };

  const toolIconClass =
    "flex h-7 w-7 cursor-pointer items-center justify-center rounded-lg text-[20px] text-[var(--sub-text)] transition-colors duration-100 ease-out hover:bg-[var(--primary-active)] hover:text-[var(--primary)]";

  return (
    <footer className="relative bg-white">
      <div className="flex flex-col border-t border-t-[var(--gap-text)]">
        {/* 工具栏 */}
        <div className="flex items-center gap-5 px-4 pt-2">
          <Popover
            content={<EmojiPanel onSelect={onEmojiSelect} />}
            title={null}
            arrow={false}
            trigger="click"
            placement="topLeft"
            open={emojiVisible}
            onOpenChange={setEmojiVisible}
          >
            <SmileOutlined className={toolIconClass} rev={undefined} />
          </Popover>
          <Upload
            showUploadList={false}
            customRequest={(options) => sendFileMessage(options.file as File)}
            multiple
            className="flex"
          >
            <FileOutlined className={toolIconClass} rev={undefined} />
          </Upload>
          <Upload
            showUploadList={false}
            customRequest={sendImageMessage}
            accept="image/*"
            multiple
            className="flex"
          >
            <PictureOutlined className={toolIconClass} rev={undefined} />
          </Upload>
          <AudioOutlined
            className={toolIconClass}
            rev={undefined}
            onClick={() => start()}
          />
        </div>

        {/* 录音条 */}
        {recording && (
          <div className="mx-4 mt-2 flex items-center rounded-md bg-[var(--chat-bg)] px-3 py-2">
            <span className="mr-2 h-2 w-2 animate-pulse rounded-full bg-[var(--warn-text)]" />
            <span className="flex-1 text-sm">
              {t("placeholder.microphone")} {seconds}″
            </span>
            <Button size="small" className="mr-2" onClick={cancel}>
              {t("cancel")}
            </Button>
            <Button size="small" type="primary" onClick={finish}>
              {t("placeholder.send")}
            </Button>
          </div>
        )}

        {/* 输入框 */}
        <div className="px-4 pt-2">
          <Input.TextArea
            ref={textareaRef}
            autoSize={{ minRows: 3, maxRows: 6 }}
            placeholder={t("placeholder.sendToName", {
              name: currentConversation?.showName ?? "",
            })}
            value={text}
            onChange={(e) => setText(e.target.value)}
            onKeyDown={onKeyDown}
            bordered={false}
            style={{ resize: "none", boxShadow: "none" }}
          />
        </div>

        {/* 底部提示 + 发送按钮 */}
        <div className="flex items-center justify-end px-4 pb-2">
          <span className="mr-3 text-xs text-[var(--sub-text)]">
            {t("placeholder.enterToSendTip")}
          </span>
          <Button
            type="primary"
            disabled={!text.trim()}
            loading={sending}
            onClick={sendText}
            style={{ height: 32, borderRadius: 8, paddingInline: 24 }}
          >
            {t("placeholder.send")}
          </Button>
        </div>
      </div>
    </footer>
  );
};

export default memo(forwardRef(ChatFooter));
