import 'dayjs/locale/ru';

import React, { useRef, useState } from 'react';

import { observer } from 'mobx-react';
import { GrMicrophone } from 'react-icons/gr';
import { IoSend } from 'react-icons/io5';
import { LiaEdit } from 'react-icons/lia';
import {
  LuPaperclip,
  LuPlus,
  LuSmile,
  LuZap,
} from 'react-icons/lu';
import { MdClose } from 'react-icons/md';

import { rpc } from '../../../api/request';
import { FileDocumentFileType } from '../../../api/types';
import {
  fastAnswerPopupRootRef,
} from '../../../components/FastAnswerPopupRoot';
import { recordingSheetRef } from '../../../components/RecordingSheetRoot';
import { toast } from '../../../components/ToastRoot';
import { usePresentation } from '../../../presentation/PresentationContext';
import sendSound from '../../../send.mp3';
import {
  channelStore,
  MAX_MESSAGE_TEXT_LENGTH,
} from '../../../stores/channelStore';
import store from '../../../stores/store';
import IconButton from '../../../ui/IconButton';
import { Menu, MenuItem } from '../../../ui/Menu';
import Popover from '../../../ui/Popover';
import { emojis } from '../emojis';
import MessageReplayItem from './MessageReplayItem';

const MAX_ATTACH_FILE_MB = 5;
const sendAudio = new Audio(sendSound);

const RichMessagebar = observer(() => {
  const {
    id: presentationId,
    components: { RichMessagebarRoot, RichMessagebarComposerWrap },
  } = usePresentation();

  const selectChannelID = channelStore.channel?._id ?? '';
  const textAreaRef = useRef<HTMLTextAreaElement>(null);
  const attachInputRef = useRef<HTMLInputElement>(null);
  const fastAnswersBtnRef = useRef<HTMLButtonElement>(null);
  const emojiBtnRef = useRef<HTMLButtonElement>(null);
  const suppressNextSendClickRef = useRef(false);

  const [fastAnswersOpen, setFastAnswersOpen] = useState(false);
  const [emojiOpen, setEmojiOpen] = useState(false);

  const openAttachmentPicker = () => {
    if (channelStore.sending || !selectChannelID) return;
    attachInputRef.current?.click();
  };

  const onAttachFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const input = e.currentTarget;
    const file = input.files?.[0] ?? null;
    input.value = '';
    if (!file || channelStore.sending || !selectChannelID) return;

    const maxBytes = MAX_ATTACH_FILE_MB * 1024 * 1024;
    if (file.size > maxBytes) {
      toast(`Файл слишком большой. Максимум ${MAX_ATTACH_FILE_MB}MB.`);
      return;
    }

    const formData = new FormData();
    formData.append('file', file);
    channelStore.setSending(true);

    rpc
      .channelDocumentUpload(formData)
      .then((json: any) => {
        if (!json || !selectChannelID) {
          channelStore.setSending(false);
          return;
        }
        channelStore.sendMessage({
          attachments: [json as FileDocumentFileType],
          channel: selectChannelID,
        });
      })
      .catch(() => channelStore.setSending(false));
  };

  const handleSend = (params: { text?: string; voice?: { _id: string } }) => {
    if (!selectChannelID) return;
    channelStore.sendMessage({ ...params, channel: selectChannelID }).then(() => {
      sendAudio.play().catch(() => {});
      if (params.text && textAreaRef.current) {
        textAreaRef.current.style.height = 'auto';
      }
    });
  };

  const handleSendClick = () => {
    if (channelStore.sending) return;
    if (!channelStore.messageText) {
      recordingSheetRef.current?.open({
        onClose: () => {},
        onSend: (audioBlob) => {
          const formData = new FormData();
          formData.append('file', audioBlob, 'audio.webm');
          channelStore.setSending(true);
          rpc
            .channelVoiceUpload(formData)
            .then((json) => {
              if (json?._id && selectChannelID) {
                handleSend({ voice: { _id: json._id } });
              } else {
                channelStore.setSending(false);
              }
            })
            .catch(() => channelStore.setSending(false));
        },
      });
    } else {
      handleSend({ text: channelStore.messageText });
    }
  };

  const keepFocused = (e: React.MouseEvent | React.TouchEvent) => {
    if (!channelStore.messageText.trim()) return;
    e.preventDefault();
    textAreaRef.current?.focus();
  };

  const handleSendTouchEnd = (e: React.TouchEvent) => {
    if (!channelStore.messageText.trim()) return;
    e.preventDefault();
    suppressNextSendClickRef.current = true;
    handleSendClick();
  };

  const handleSendClickPointer = () => {
    if (suppressNextSendClickRef.current) {
      suppressNextSendClickRef.current = false;
      return;
    }
    handleSendClick();
  };

  const hasText = !!channelStore.messageText.trim();

  return (
    <RichMessagebarRoot>
      {/* Статус отправки не показываем плашкой — он отражается часами/
          галочками прямо в bubble (см. MessageItem). */}
      {channelStore.replyMsg && (
        <div className="flex items-start gap-2 px-3 pt-2">
          <div className="flex-1 min-w-0">
            <MessageReplayItem
              variant="compose"
              onClick={() => {}}
              msg={channelStore.replyMsg}
            />
          </div>
          <IconButton
            size="sm"
            onClick={() => {
              if (channelStore.sending) return;
              channelStore.setReplyMsg(null);
            }}
          >
            <MdClose />
          </IconButton>
        </div>
      )}

      <div className="flex items-end gap-1 px-2 py-2">
        {store.mode == 'full' && (
          <IconButton
            ref={fastAnswersBtnRef}
            onClick={() => setFastAnswersOpen(true)}
            title="Быстрые ответы"
          >
            <LuZap />
          </IconButton>
        )}

        <div className="relative">
          <input
            ref={attachInputRef}
            type="file"
            className="fixed left-[-9999px] top-0 h-px w-px opacity-0"
            tabIndex={-1}
            disabled={channelStore.sending || !selectChannelID}
            onChange={onAttachFileChange}
          />
          <IconButton
            onClick={openAttachmentPicker}
            disabled={channelStore.sending || !selectChannelID}
            title="Прикрепить"
          >
            <LuPaperclip />
          </IconButton>
        </div>

        <RichMessagebarComposerWrap>
          <textarea
            id="text-area-messagebar"
            ref={textAreaRef}
            value={channelStore.messageText}
            className={`
              flex-1 min-w-0 bg-transparent outline-none border-none
              resize-none overflow-hidden
              px-3 ${presentationId === 'instagram' ? 'py-2' : 'py-2.5'} text-[16px] md:text-[15px]
              text-[var(--tg-text-primary)]
              placeholder:text-[var(--tg-text-secondary)]
              max-h-[160px]
            `}
            rows={1}
            maxLength={MAX_MESSAGE_TEXT_LENGTH}
            onChange={(e) => {
              if (channelStore.sending) return;
              const target = e.currentTarget;
              target.style.height = 'auto';
              target.style.height = `${Math.min(target.scrollHeight, 160)}px`;
              let value = e.target?.value;
              if (value.trim() === '') value = '';
              channelStore.setMessageText(value);
            }}
            onKeyDown={(e) => {
              if (e.key === 'Enter' && !e.shiftKey && !store.isMobile()) {
                e.preventDefault();
                if (hasText) handleSendClick();
              }
            }}
            placeholder="Сообщение..."
          />
          <IconButton
            ref={emojiBtnRef}
            onClick={() => setEmojiOpen(true)}
            size="sm"
            className={presentationId === 'instagram' ? 'shrink-0' : 'mb-1 shrink-0'}
            title="Эмодзи"
          >
            <LuSmile />
          </IconButton>
        </RichMessagebarComposerWrap>

        <button
          type="button"
          onMouseDown={keepFocused}
          onTouchStart={keepFocused}
          onTouchEnd={handleSendTouchEnd}
          onClick={handleSendClickPointer}
          className={`
            relative w-10 h-10 rounded-full inline-flex items-center justify-center
            transition-all duration-200 tg-press
            ${
              hasText
                ? 'bg-[var(--tg-accent)] text-white'
                : 'text-[var(--tg-text-secondary)] hover:bg-[var(--tg-bg-secondary)]'
            }
          `}
        >
          <span
            className={`absolute inset-0 flex items-center justify-center transition-all duration-150 ${
              hasText ? 'opacity-0 scale-50' : 'opacity-100 scale-100'
            }`}
          >
            <GrMicrophone
              size={20}
              className={
                presentationId === 'instagram'
                  ? 'translate-y-[2px]'
                  : undefined
              }
            />
          </span>
          <span
            className={`absolute inset-0 flex items-center justify-center transition-all duration-150 ${
              hasText ? 'opacity-100 scale-100' : 'opacity-0 scale-50'
            }`}
          >
            <IoSend size={18} className="-ml-0.5" />
          </span>
        </button>
      </div>

      {/* Emoji popover */}
      <Popover
        opened={emojiOpen}
        onClose={() => setEmojiOpen(false)}
        target={emojiBtnRef.current}
        width={320}
      >
        <div className="p-2 grid grid-cols-7 gap-1 max-h-[300px] overflow-y-auto tg-scroll">
          {emojis.map((val, i) => (
            <button
              type="button"
              key={i}
              onClick={() => {
                channelStore.setMessageText(channelStore.messageText + val);
              }}
              className="
                h-9 w-9 inline-flex items-center justify-center
                rounded-lg hover:bg-[var(--tg-bg-secondary)]
                text-[22px] tg-press
              "
            >
              {val}
            </button>
          ))}
        </div>
      </Popover>

      {/* Fast answers menu */}
      <Popover
        opened={fastAnswersOpen}
        onClose={() => setFastAnswersOpen(false)}
        target={fastAnswersBtnRef.current}
        width={320}
      >
        <Menu>
          {store.fastAnswers.map((fa) => (
            <MenuItem
              key={fa._id ?? fa.name}
              title={fa.name}
              onClick={() => {
                if (fa.text) channelStore.setMessageText(fa.text);
                setFastAnswersOpen(false);
              }}
              after={
                <button
                  type="button"
                  onClick={(e) => {
                    e.stopPropagation();
                    setFastAnswersOpen(false);
                    fastAnswerPopupRootRef.current?.open(fa);
                  }}
                  className="p-1 rounded-md hover:bg-[var(--tg-bg-secondary)]
                    text-[var(--tg-accent)]"
                >
                  <LiaEdit size={18} />
                </button>
              }
            />
          ))}

          <MenuItem
            icon={<LuPlus />}
            title="Добавить быстрый ответ"
            onClick={() => {
              fastAnswerPopupRootRef.current?.open();
              setFastAnswersOpen(false);
            }}
          />
        </Menu>
      </Popover>
    </RichMessagebarRoot>
  );
});

export default RichMessagebar;
