import { Badge, Card, List, Space, Tag, Tooltip } from "antd";
import { useEffect, useMemo, useState } from "react";
import { connect } from "react-redux";
import { Virtuoso } from "react-virtuoso";
import { createStructuredSelector } from "reselect";
import { setSelectedConversation } from "../../redux/messaging/messaging.actions";
import { selectSelectedConversation } from "../../redux/messaging/messaging.selectors";
import { TimeAgoFormatter } from "../../utils/DateFormatter";
import PhoneFormatter from "../../utils/PhoneFormatter";
import { OwnerNameDisplayFunction } from "../owner-name-display/owner-name-display.component";
import _ from "lodash";
import { ExclamationCircleOutlined } from "@ant-design/icons";
import "./chat-conversation-list.styles.scss";
import { useQuery } from "@apollo/client";
import { GET_PHONE_NUMBER_OPT_OUTS } from "../../graphql/phone-number-opt-out.queries.js";
import { phone } from "phone";
import { useTranslation } from "react-i18next";
import { selectBodyshop } from "../../redux/user/user.selectors";

const mapStateToProps = createStructuredSelector({
  selectedConversation: selectSelectedConversation,
  bodyshop: selectBodyshop
});

const mapDispatchToProps = (dispatch) => ({
  setSelectedConversation: (conversationId) => dispatch(setSelectedConversation(conversationId))
});

function ChatConversationListComponent({ conversationList, selectedConversation, setSelectedConversation, bodyshop }) {
  const { t } = useTranslation();
  const [, forceUpdate] = useState(false);
  const phoneNumbers = conversationList.map((item) => phone(item.phone_num, "CA").phoneNumber.replace(/^\+1/, ""));
  const { data: optOutData } = useQuery(GET_PHONE_NUMBER_OPT_OUTS, {
    variables: {
      bodyshopid: bodyshop.id,
      phone_numbers: phoneNumbers
    },
    skip: !conversationList.length,
    fetchPolicy: "cache-and-network"
  });

  const optOutMap = useMemo(() => {
    const map = new Map();
    optOutData?.phone_number_opt_out?.forEach((optOut) => {
      map.set(optOut.phone_number, true);
    });
    return map;
  }, [optOutData?.phone_number_opt_out]);

  useEffect(() => {
    const interval = setInterval(() => {
      forceUpdate((prev) => !prev);
    }, 60000);
    return () => clearInterval(interval);
  }, []);

  const sortedConversationList = useMemo(() => {
    return _.orderBy(conversationList, ["updated_at"], ["desc"]);
  }, [conversationList]);

  const renderConversation = (index, t) => {
    const item = sortedConversationList[index];
    const normalizedPhone = phone(item.phone_num, "CA").phoneNumber.replace(/^\+1/, "");
    const hasOptOutEntry = optOutMap.has(normalizedPhone);
    const cardContentRight = <TimeAgoFormatter>{item.updated_at}</TimeAgoFormatter>;
    const cardContentLeft =
      item.job_conversations.length > 0
        ? item.job_conversations.map((j, idx) => <Tag key={idx}>{j.job.ro_number}</Tag>)
        : null;
    const names = <>{_.uniq(item.job_conversations.map((j) => OwnerNameDisplayFunction(j.job)))}</>;
    const cardTitle = (
      <>
        {item.label && <Tag color="blue">{item.label}</Tag>}
        {item.job_conversations.length > 0 ? (
          <Space direction="vertical">{names}</Space>
        ) : (
          <Space>
            <PhoneFormatter>{item.phone_num}</PhoneFormatter>
          </Space>
        )}
      </>
    );
    const cardExtra = (
      <>
        <Badge count={item.messages_aggregate.aggregate.count} />
        {hasOptOutEntry && (
          <Tooltip title={t("consent.text_body")}>
            <Tag color="red" icon={<ExclamationCircleOutlined />}>
              {t("messaging.labels.no_consent")}
            </Tag>
          </Tooltip>
        )}
      </>
    );
    const getCardStyle = () =>
      item.id === selectedConversation
        ? { backgroundColor: "var(--card-selected-bg)" }
        : { backgroundColor: index % 2 === 0 ? "var(--card-stripe-even-bg)" : "var(--card-stripe-odd-bg)" };

    return (
      <List.Item
        key={item.id}
        onClick={() => setSelectedConversation(item.id)}
        className={`chat-list-item ${item.id === selectedConversation ? "chat-list-selected-conversation" : ""}`}
      >
        <Card style={getCardStyle()} variant={true} size="small" extra={cardExtra} title={cardTitle}>
          <div
            style={{
              display: "inline-block",
              width: "70%",
              textAlign: "left"
            }}
          >
            {cardContentLeft}
          </div>
          <div
            style={{
              display: "inline-block",
              width: "30%",
              textAlign: "right"
            }}
          >
            {cardContentRight}
          </div>
        </Card>
      </List.Item>
    );
  };

  return (
    <div className="chat-list-container">
      <Virtuoso
        data={sortedConversationList}
        itemContent={(index) => renderConversation(index, t)}
        style={{ height: "100%", width: "100%" }}
      />
    </div>
  );
}

export default connect(mapStateToProps, mapDispatchToProps)(ChatConversationListComponent);
