import { Comment, Dropdown, Input, List, Menu } from 'antd';
import produce from 'immer';
import _ from 'lodash';
import React, { useCallback, useEffect, useState } from 'react';

import { useChannel } from '../hooks/useWebSocket';
import { deleteRoom, getRoomList, postCreateRoom } from '../services/chat';
import styles from '../style.module.css';
import dayjs from '../utils/dayjs';
import CreateModal from './ChatModal';
import IconFont from './IconFonts';

type PropType = {
  username: string;
  room_id: string;
  chat?: any;
  onChatSet?: (chat: any) => void;
  to: (room_id?: string) => void;
  user_id: string;
  members: any[];
};

const RoomList: React.FC<PropType> = ({
  username,
  room_id,
  chat,
  onChatSet,
  to,
  user_id,
  members,
}) => {
  const [rooms, setRooms] = useState<any[]>([]);
  const [searchText, setSearchText] = useState<string>('');
  const [visible, setVisible] = useState<boolean>(false);
  const [allowUserIds, setAllowUserIds] = useState<string[]>([]);
  const [indeterminate, setIndeterminate] = React.useState<boolean>(false);
  const [checkAll, setCheckAll] = React.useState<boolean>(false);

  const onCheckAllChange = (e) => {
    setAllowUserIds(e.target.checked ? members.filter((s) => s.user_id !== user_id).map((v) => v.user_id) : []);
    setIndeterminate(false);
    setCheckAll(e.target.checked);
  };

  useEffect(() => {
    getRoomList(username).then((res) => {
      setRooms(res);
    });
  }, [username]);

  useChannel(`chat-room-info-${username}`, username, (obj: Chat.ChannelType) => {
    if (obj) {
      const { data } = obj;
      const newRooms = _.clone(rooms as Chat.RoomInfo[]);
      switch (data.op) {
        case 'create': {
          setRooms(_.concat(newRooms, [data.room]));
          if (chat?.room?.id === data.id && onChatSet) {
            onChatSet(
              produce((draft: any) => {
                draft.room = { ...chat.room, ...data.room };
              })
            );
          }
          break;
        }
        case 'delete': {
          setRooms(_.filter(newRooms, (room) => room.id !== data.id));
          if (chat?.room?.id === data.id && onChatSet) {
            onChatSet(
              produce((draft: any) => {
                draft.room = undefined;
              })
            );
            to();
          }
          break;
        }
        case 'update': {
          const roomIndex = _.findIndex(rooms, ['id', data.id]);
          newRooms[roomIndex] = { ...rooms[roomIndex], ...data.room };
          setRooms(newRooms);
          if (chat?.room?.id === data.id && onChatSet) {
            onChatSet(
              produce((draft: any) => {
                draft.room = { ...chat.room, ...data.room };
              })
            );
          }
          break;
        }
        default:
          break;
      }
    }
  });

  const checked = (v) => {
    return allowUserIds.includes(v.user_id) || user_id === v.user_id;
  };
  const disabled = (v) => {
    return user_id === v.user_id;
  };

  const roomTitle = useCallback(
    (item: Chat.RoomInfo) => {
      return (
        item.name ||
        _.filter(members, (m) => _.includes(item.allow_user_ids, m.user_id))
          .map((m) => m.user_name)
          .join('、')
      );
    },
    [members]
  );

  const lastMessage = useCallback((messages?: Chat.Message[]) => {
    return messages
      ? _.reduce(
        messages,
        (result, v) => {
          if (v.type === 'attachment') {
            return result + (v?.sub_type || '') === 'image' ? '[图片]' : '[文件]';
          }
          return result + v.text;
        },
        ''
      )
      : '暂无消息';
  }, []);

  return (
    <>
      <List<Chat.RoomInfo>
        dataSource={rooms.filter((v) => v.name?.includes(searchText))}
        itemLayout="horizontal"
        header={
          <Input
            placeholder="搜索"
            value={searchText}
            onChange={(e) => setSearchText(e.target.value)}
            allowClear
            suffix={
              <IconFont
                icon="icon-plus"
                className={styles.addRoomIcon}
                onClick={() => {
                  setVisible(true);
                }}
              />
            }
          />
        }
        renderItem={(item) => (
          <Dropdown
            key={item.id}
            overlay={
              <Menu
                style={{ minWidth: 150 }}
                items={[
                  {
                    key: item.id,
                    label: '删除',
                    icon: <IconFont icon="icon-delete" />,
                    onClick: () => {
                      deleteRoom(username, item.id);
                      to();
                    },
                  },
                ]}
              />
            }
            trigger={['contextMenu']}
          >
            <li
              key={item.id}
              className={`cursor-pointer ${room_id === item.id ? styles.activeRoom : styles.inactiveRoom}`}
              onClick={() => {
                to(item.id);
              }}
            >
              <Comment
                author={<div className="w-60 truncate text-sm font-medium text-gray-700">{roomTitle(item)}</div>}
                content={
                  <div className="flex justify-between">
                    <p className="overflow-hidden text-ellipsis whitespace-nowrap text-xs font-light">
                      {lastMessage(item.last_record?.message)}
                    </p>
                    <div className="text-xs text-gray-400">
                      {item.last_record?.message ? dayjs(item.last_record.created_at).fromNow() : ''}
                    </div>
                  </div>
                }
                avatar={
                  <ul className={styles.roomAvatar}>
                    {item.allow_user_ids &&
                      members
                        .filter((v) => item.allow_user_ids.includes(v.user_id) && v.avatar.includes('https'))
                        .slice(0, 9)
                        .map((m) => (
                          <li className={styles.li} key={m.avatar}>
                            <img src={m.avatar} alt="" title="1" height={40} width={40} />
                          </li>
                        ))}
                  </ul>
                }
              />
            </li>
          </Dropdown>
        )}
      />
      <CreateModal
        members={members}
        onCheckAllChange={onCheckAllChange}
        indeterminate={indeterminate}
        checkAll={checkAll}
        allowUserIds={allowUserIds}
        visible={visible}
        setVisible={setVisible}
        setAllowUserIds={setAllowUserIds}
        defaultValue=""
        onOk={(roomName: string) =>
          user_id != null &&
          postCreateRoom(username, roomName, allowUserIds.concat([user_id])).then(() => setVisible(false))
        }
        disabled={(v) => disabled(v)}
        checked={(v) => checked(v)}
        title="创建房间"
        okText="创建"
      />
    </>
  );
};

export default RoomList;
