import React, { ReactNode } from 'react';
import { IconSrc, Icons } from 'folds';
import { MatrixEvent } from 'matrix-js-sdk';
import { IMemberContent, Membership } from '../../types/matrix/room';
import { getMxIdLocalPart } from '../utils/matrix';

export type ParsedResult = {
  icon: IconSrc;
  body: ReactNode;
};

export type MemberEventParser = (mEvent: MatrixEvent) => ParsedResult;

export const useMemberEventParser = (): MemberEventParser => {
  const parseMemberEvent: MemberEventParser = (mEvent) => {
    const content = mEvent.getContent<IMemberContent>();
    const prevContent = mEvent.getPrevContent() as IMemberContent;
    const senderId = mEvent.getSender();
    const userId = mEvent.getStateKey();

    if (!senderId || !userId)
      return {
        icon: Icons.User,
        body: 'Broken membership event',
      };

    const senderName = getMxIdLocalPart(senderId);
    const userName = content.displayname || getMxIdLocalPart(userId);

    if (content.membership !== prevContent.membership) {
      if (content.membership === Membership.Invite) {
        if (prevContent.membership === Membership.Knock) {
          return {
            icon: Icons.ArrowGoRightPlus,
            body: (
              <>
                <b>{senderName}</b>
                {' accepted '}
                <b>{userName}</b>
                {`'s join request `}
                {content.reason}
              </>
            ),
          };
        }

        return {
          icon: Icons.ArrowGoRightPlus,
          body: (
            <>
              <b>{senderName}</b>
              {' invited '}
              <b>{userName}</b> {content.reason}
            </>
          ),
        };
      }

      if (content.membership === Membership.Knock) {
        return {
          icon: Icons.ArrowGoRightPlus,
          body: (
            <>
              <b>{userName}</b>
              {' request to join room '}
              {content.reason}
            </>
          ),
        };
      }

      if (content.membership === Membership.Join) {
        return {
          icon: Icons.ArrowGoRight,
          body: (
            <>
              <b>{userName}</b>
              {' joined the room'}
            </>
          ),
        };
      }

      if (content.membership === Membership.Leave) {
        if (prevContent.membership === Membership.Invite) {
          return {
            icon: Icons.ArrowGoRightCross,
            body:
              senderId === userId ? (
                <>
                  <b>{userName}</b>
                  {' reject the invitation '}
                  {content.reason}
                </>
              ) : (
                <>
                  <b>{senderName}</b>
                  {' reject '}
                  <b>{userName}</b>
                  {`'s join request `}
                  {content.reason}
                </>
              ),
          };
        }

        if (prevContent.membership === Membership.Knock) {
          return {
            icon: Icons.ArrowGoRightCross,
            body:
              senderId === userId ? (
                <>
                  <b>{userName}</b>
                  {' revoked joined request '}
                  {content.reason}
                </>
              ) : (
                <>
                  <b>{senderName}</b>
                  {' revoked '}
                  <b>{userName}</b>
                  {`'s invite `}
                  {content.reason}
                </>
              ),
          };
        }

        if (prevContent.membership === Membership.Ban) {
          return {
            icon: Icons.ArrowGoLeft,
            body: (
              <>
                <b>{senderName}</b>
                {' unbanned '}
                <b>{userName}</b> {content.reason}
              </>
            ),
          };
        }

        return {
          icon: Icons.ArrowGoLeft,
          body:
            senderId === userId ? (
              <>
                <b>{userName}</b>
                {' left the room '}
                {content.reason}
              </>
            ) : (
              <>
                <b>{senderName}</b>
                {' kicked '}
                <b>{userName}</b> {content.reason}
              </>
            ),
        };
      }

      if (content.membership === Membership.Ban) {
        return {
          icon: Icons.ArrowGoLeft,
          body: (
            <>
              <b>{senderName}</b>
              {' banned '}
              <b>{userName}</b> {content.reason}
            </>
          ),
        };
      }
    }

    if (content.displayname !== prevContent.displayname) {
      const prevUserName = prevContent.displayname || userId;

      return {
        icon: Icons.Mention,
        body: content.displayname ? (
          <>
            <b>{prevUserName}</b>
            {' changed display name to '}
            <b>{userName}</b>
          </>
        ) : (
          <>
            <b>{prevUserName}</b>
            {' removed their display name '}
          </>
        ),
      };
    }
    if (content.avatar_url !== prevContent.avatar_url) {
      return {
        icon: Icons.User,
        body: content.displayname ? (
          <>
            <b>{userName}</b>
            {' changed their avatar'}
          </>
        ) : (
          <>
            <b>{userName}</b>
            {' removed their avatar '}
          </>
        ),
      };
    }

    return {
      icon: Icons.User,
      body: 'Broken membership event',
    };
  };

  return parseMemberEvent;
};
