import { SearchOutlined, PlusOutlined } from "@ant-design/icons";
import { Button, Input, Spin } from "antd";
import { t } from "i18next";
import { useMemo, useRef, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { Virtuoso, VirtuosoHandle } from "react-virtuoso";

import FlexibleSider from "@/components/FlexibleSider";
import AddColleague from "@/pages/common/AddColleague";
import { useConversationStore, useUserStore } from "@/store";

import ConversationItemComp from "./ConversationItem";

// 断网时顶部的深色提示横条
const OfflineBar = () => (
  <div>
    <div className="flex h-9 items-center bg-[#3a3f47] px-3 text-xs text-white">
      <svg
        width="14"
        height="14"
        viewBox="0 0 24 24"
        fill="none"
        className="mr-1.5 shrink-0"
      >
        <circle cx="12" cy="12" r="9" stroke="#fff" strokeWidth="2" />
        <path
          d="M12 7.5v5.5"
          stroke="#fff"
          strokeWidth="2"
          strokeLinecap="round"
        />
        <circle cx="12" cy="16.5" r="1.2" fill="#fff" />
      </svg>
      {t("states.offline")}
    </div>
    <div className="px-3 py-2 text-xs text-[var(--sub-text)]">
      {t("states.offlineTip")}
    </div>
  </div>
);

const EmptyIcon = () => (
  <svg width="56" height="56" viewBox="0 0 24 24" fill="none">
    <path
      d="M12 3C6.98 3 3 6.58 3 11.1c0 2.5 1.28 4.73 3.28 6.24-.1.84-.46 1.87-1.02 2.66-.15.21.02.5.27.44 1.53-.34 2.92-1.03 3.9-1.73.82.18 1.68.29 2.57.29 5.02 0 9-3.58 9-8.1S17.02 3 12 3Z"
      fill="#dcdfe6"
    />
    <circle cx="8.5" cy="11" r="1.1" fill="#fff" />
    <circle cx="12" cy="11" r="1.1" fill="#fff" />
    <circle cx="15.5" cy="11" r="1.1" fill="#fff" />
  </svg>
);

const ConversationSider = () => {
  const { conversationID } = useParams();
  const navigate = useNavigate();
  const conversationList = useConversationStore((state) => state.conversationList);
  const getConversationListByReq = useConversationStore(
    (state) => state.getConversationListByReq,
  );
  const syncState = useUserStore((state) => state.syncState);
  const connectState = useUserStore((state) => state.connectState);
  const [keyword, setKeyword] = useState("");
  const [addColleagueOpen, setAddColleagueOpen] = useState(false);
  const virtuoso = useRef<VirtuosoHandle>(null);
  const hasmore = useRef(true);
  const loading = useRef(false);

  const filteredList = useMemo(() => {
    const word = keyword.trim();
    if (!word) return conversationList;
    return conversationList.filter((conversation) =>
      conversation.showName?.toLowerCase().includes(word.toLowerCase()),
    );
  }, [conversationList, keyword]);

  const endReached = async () => {
    if (!hasmore.current || loading.current || keyword.trim()) return;
    loading.current = true;
    hasmore.current = await getConversationListByReq(true);
    loading.current = false;
  };

  const renderBody = () => {
    if (syncState === "loading" && conversationList.length === 0) {
      return (
        <div className="flex flex-1 flex-col items-center justify-center">
          <Spin />
          <div className="mt-4 text-sm">{t("states.loading")}</div>
          <div className="mt-1 text-xs text-[var(--sub-text)]">
            {t("states.loadingTip")}
          </div>
        </div>
      );
    }
    if (syncState === "failed" && conversationList.length === 0) {
      return (
        <div className="flex flex-1 flex-col items-center justify-center">
          <EmptyIcon />
          <div className="mt-4 text-sm">{t("states.loadFailed")}</div>
          <div className="mt-1 text-xs text-[var(--sub-text)]">
            {t("states.loadFailedTip")}
          </div>
          <Button
            className="mt-4"
            onClick={() => getConversationListByReq(false)}
          >
            {t("retry")}
          </Button>
        </div>
      );
    }
    if (conversationList.length === 0) {
      return (
        <div className="flex flex-1 flex-col items-center justify-center">
          <EmptyIcon />
          <div className="mt-4 text-sm">{t("states.noMessage")}</div>
          <div className="mt-1 text-xs text-[var(--sub-text)]">
            {t("states.noMessageTip")}
          </div>
          <Button
            className="mt-4"
            type="primary"
            onClick={() => navigate("/contact")}
          >
            {t("states.findColleague")}
          </Button>
        </div>
      );
    }
    return (
      <Virtuoso
        className="flex-1"
        data={filteredList}
        ref={virtuoso}
        endReached={endReached}
        computeItemKey={(_, item) => item.conversationID}
        itemContent={(_, conversation) => (
          <ConversationItemComp
            isActive={conversationID === conversation.conversationID}
            conversation={conversation}
          />
        )}
      />
    );
  };

  return (
    <FlexibleSider
      needHidden={Boolean(conversationID)}
      wrapClassName="flex flex-col border-r border-[var(--gap-text)] bg-white"
    >
      {connectState === "failed" && <OfflineBar />}
      <div className="app-drag px-4 pt-4">
        <div className="pb-3 text-base font-bold">{t("placeholder.chat")}</div>
        <div className="flex items-center gap-1.5">
          <Input
            className="app-no-drag mb-2 rounded-md border-none !bg-[var(--search-bg)]"
            prefix={<SearchOutlined className="text-[var(--sub-text)]" rev={undefined} />}
            placeholder={t("placeholder.search")}
            allowClear
            value={keyword}
            onChange={(e) => setKeyword(e.target.value)}
          />
          <div
            className="app-no-drag flex h-9 w-9 shrink-0 cursor-pointer items-center justify-center rounded-lg text-[20px] text-[var(--sub-text)] transition-colors duration-100 hover:bg-[var(--primary-active)] hover:text-[var(--primary)]"
            title={t("placeholder.addColleague")}
            onClick={() => setAddColleagueOpen(true)}
          >
            <PlusOutlined rev={undefined} />
          </div>
        </div>
      </div>
      {renderBody()}
      <AddColleague open={addColleagueOpen} onClose={() => setAddColleagueOpen(false)} />
    </FlexibleSider>
  );
};

export default ConversationSider;
