"use strict";

exports.__esModule = true;
exports.default = Thread;

var _react = _interopRequireWildcard(require("react"));

var _styles = require("@mui/material/styles");

var _Card = _interopRequireDefault(require("@mui/material/Card"));

var _core = require("@selfcommunity/core");

var _Message = _interopRequireDefault(require("../Message"));

var _lodash = _interopRequireDefault(require("lodash"));

var _reactIntl = require("react-intl");

var _material = require("@mui/material");

var _ConfirmDialog = _interopRequireDefault(require("../../shared/ConfirmDialog/ConfirmDialog"));

var _MessageEditor = _interopRequireDefault(require("../MessageEditor"));

var _CardContent = _interopRequireDefault(require("@mui/material/CardContent"));

var _Autocomplete = _interopRequireDefault(require("@mui/material/Autocomplete"));

const _excluded = ["id", "receiverId", "autoHide", "className", "openNewMessage"];

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }

const PREFIX = 'SCThread';
const classes = {
  emptyBox: `${PREFIX}-emptyBox`,
  sender: `${PREFIX}-sender`,
  receiver: `${PREFIX}-receiver`,
  center: `${PREFIX}-center`
};
const Root = (0, _styles.styled)(_Card.default, {
  name: PREFIX,
  slot: 'Root',
  overridesResolver: (props, styles) => styles.root
})(({
  theme
}) => ({
  width: '500px',
  maxWidth: '500px',
  display: 'inline-block',
  [`& .${classes.emptyBox}`]: {
    display: 'flex',
    height: '100%',
    background: theme.palette.grey['A200'],
    justifyContent: 'center',
    alignItems: 'center',
    '& .MuiTypography-root': {
      fontSize: '1.5rem'
    }
  },
  [`& .${classes.sender}`]: {
    display: 'flex',
    justifyContent: 'flex-end',
    '& .SCMessage-messageBox': {
      backgroundColor: theme.palette.grey[400]
    }
  },
  [`& .${classes.receiver}`]: {
    display: 'flex',
    justifyContent: 'flex-start',
    '& .SCMessage-messageBox': {
      backgroundColor: theme.palette.grey['A200']
    },
    '& .SCMessage-messageTime': {
      display: 'flex',
      justifyContent: 'flex-start'
    }
  },
  [`& .${classes.center}`]: {
    display: 'flex',
    justifyContent: 'center'
  }
}));

function Thread(props) {
  // PROPS
  const {
    id,
    receiverId,
    autoHide,
    className,
    openNewMessage
  } = props,
        rest = _objectWithoutPropertiesLoose(props, _excluded); //CONTEXT


  const scUserContext = (0, _react.useContext)(_core.SCUserContext); // STATE

  const [loading, setLoading] = (0, _react.useState)(true);
  const [messages, setMessages] = (0, _react.useState)([]);
  const loggedUser = scUserContext.user && scUserContext.user.id;
  const [isHovered, setIsHovered] = (0, _react.useState)({});
  const [openDeleteMessageDialog, setOpenDeleteMessageDialog] = (0, _react.useState)(false);
  const [deletingMsg, setDeletingMsg] = (0, _react.useState)(null);
  const [message, setMessage] = (0, _react.useState)('');
  const [sending, setSending] = (0, _react.useState)(false);
  const [followers, setFollowers] = (0, _react.useState)([]);
  const [recipients, setRecipients] = (0, _react.useState)([]); // INTL

  const intl = (0, _reactIntl.useIntl)(); // UTILS

  const format = item => intl.formatDate(item.created_at, {
    weekday: 'long',
    day: 'numeric',
    month: 'long'
  }); // HANDLERS


  const formatMessages = messages => {
    return _lodash.default.groupBy(messages, format);
  };

  const formattedMessages = (0, _react.useMemo)(() => {
    return formatMessages(messages);
  }, [messages]);

  const handleMessage = m => {
    setMessage(m);
  };

  const handleMouseEnter = index => {
    setIsHovered(prevState => {
      return Object.assign({}, prevState, {
        [index]: true
      });
    });
  };

  const handleMouseLeave = index => {
    setIsHovered(prevState => {
      return Object.assign({}, prevState, {
        [index]: false
      });
    });
  };

  const handleClose = () => {
    setOpenDeleteMessageDialog(false);
  };

  function handleDeleteDialog(msg) {
    setOpenDeleteMessageDialog(true);
    setDeletingMsg(msg);
  }

  const selectRecipients = (event, recipient) => {
    setRecipients(recipient);
  };

  const ids = (0, _react.useMemo)(() => {
    if (recipients !== null) {
      return recipients.map(u => {
        return parseInt(u.id, 10);
      });
    }
  }, [recipients]);
  /**
   * Handles deletion of a single message
   * @param id
   */

  function handleDelete() {
    _core.http.request({
      url: _core.Endpoints.DeleteASingleMessage.url({
        id: deletingMsg.id
      }),
      method: _core.Endpoints.DeleteASingleMessage.method
    }).then(() => {
      const result = messages.filter(m => m.id !== deletingMsg.id);
      setMessages(result);
      handleClose();
    }).catch(error => {
      console.log(error);
    });
  }

  function sendMessage() {
    setSending(true);

    _core.http.request({
      url: _core.Endpoints.SendMessage.url(),
      method: _core.Endpoints.SendMessage.method,
      data: {
        recipients: openNewMessage ? ids : [receiverId],
        message: message
      }
    }).then(res => {
      setMessages(prev => [...prev, res.data]);
      setSending(false);
    }).catch(error => {
      console.log(error);
    });
  }
  /**
   * Fetches user followers
   */


  function fetchFollowers() {
    _core.http.request({
      url: _core.Endpoints.UserFollowers.url({
        id: scUserContext['user'].id
      }),
      method: _core.Endpoints.UserFollowers.method
    }).then(res => {
      const data = res.data;
      setFollowers(data.results);
    }).catch(error => {
      console.log(error);
    });
  }
  /**
   * Fetches thread
   */


  function fetchThread() {
    _core.http.request({
      url: _core.Endpoints.GetAThread.url(),
      method: _core.Endpoints.GetAThread.method,
      params: {
        thread: id
      }
    }).then(res => {
      const data = res.data;
      setMessages(data.results);
      setLoading(false);
    }).catch(error => {
      console.log(error);
    });
  }
  /**
   * On mount, fetches thread
   * if openNewMessage is true, fetches user follwers too.
   */


  (0, _react.useEffect)(() => {
    if (openNewMessage) {
      fetchFollowers();
    }

    fetchThread();
  }, [id, openNewMessage]);
  /**
   * Renders thread component
   * @return {JSX.Element}
   */

  function renderThread() {
    return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, openDeleteMessageDialog && /*#__PURE__*/_react.default.createElement(_ConfirmDialog.default, {
      open: openDeleteMessageDialog,
      title: /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, {
        id: "ui.Message.dialog.msg",
        defaultMessage: "ui.Message.dialog.msg"
      }),
      btnConfirm: /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, {
        id: "ui.Message.dialog.confirm",
        defaultMessage: "ui.Message.dialog.confirm"
      }),
      onConfirm: () => handleDelete(),
      onClose: handleClose
    }), Object.keys(formattedMessages).map((key, index) => /*#__PURE__*/_react.default.createElement("div", {
      key: index
    }, /*#__PURE__*/_react.default.createElement(_material.ListSubheader, {
      className: classes.center
    }, key), formattedMessages[key].map((msg, index) => /*#__PURE__*/_react.default.createElement("div", {
      key: index,
      className: loggedUser === msg.sender_id ? classes.sender : classes.receiver
    }, /*#__PURE__*/_react.default.createElement(_Message.default, {
      elevation: 0,
      message: msg,
      key: msg.id,
      snippetType: false,
      loggedUser: loggedUser,
      onMouseEnter: () => handleMouseEnter(msg.id),
      onMouseLeave: () => handleMouseLeave(msg.id),
      isHovering: isHovered[msg.id],
      onDeleteIconClick: () => handleDeleteDialog(msg)
    }))))), /*#__PURE__*/_react.default.createElement(_MessageEditor.default, {
      send: () => sendMessage(),
      isSending: sending,
      getMessage: handleMessage
    }));
  }
  /**
   * Renders empty box (when there is no thread open)
   * @return {JSX.Element}
   */


  function renderEmptyBox() {
    return /*#__PURE__*/_react.default.createElement(_material.Box, {
      className: classes.emptyBox
    }, openNewMessage ? /*#__PURE__*/_react.default.createElement(_CardContent.default, null, /*#__PURE__*/_react.default.createElement(_material.Grid, {
      container: true,
      spacing: 2
    }, /*#__PURE__*/_react.default.createElement(_material.Grid, {
      item: true,
      xs: 4
    }, /*#__PURE__*/_react.default.createElement("b", null, /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, {
      defaultMessage: "ui.NewMessage.to",
      id: "ui.NewMessage.to"
    }))), /*#__PURE__*/_react.default.createElement(_material.Grid, {
      item: true,
      xs: 8
    }, /*#__PURE__*/_react.default.createElement(_Autocomplete.default, {
      multiple: true,
      freeSolo: true,
      options: followers,
      getOptionLabel: option => option.username,
      renderInput: params => /*#__PURE__*/_react.default.createElement(_material.TextField, _extends({}, params, {
        variant: "standard",
        InputProps: Object.assign({}, params.InputProps, {
          disableUnderline: true
        })
      })),
      onChange: selectRecipients
    }))), /*#__PURE__*/_react.default.createElement(_MessageEditor.default, {
      send: () => sendMessage(),
      isSending: sending,
      getMessage: handleMessage
    })) : /*#__PURE__*/_react.default.createElement(_material.Typography, {
      component: "h3"
    }, /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, {
      id: "ui.Thread.emptyBox.message",
      defaultMessage: "ui.Thread.emptyBox.message"
    })));
  } // Anonymous


  if (!scUserContext.user) {
    return null;
  }
  /**
   * Renders the component (if not hidden by autoHide prop)
   */


  if (!autoHide) {
    return /*#__PURE__*/_react.default.createElement(Root, _extends({}, rest, {
      className: className
    }), id ? renderThread() : renderEmptyBox());
  }

  return null;
}