import { Button, Col, Collapse, Row, Spin, Table, Tag } from 'antd';
import { FC, useEffect, useState } from 'react';
import format from 'date-fns/format';
import { ColumnsType } from 'antd/lib/table';
import dynamic from 'next/dynamic';
import ChatModeration from '../../../services/moderation-service';
import styles from './ChatModerationDetailsModal.module.scss';
import { formatUAstring } from '../../../utils/format';

const { Panel } = Collapse;

// Lazy loaded components

const DeleteOutlined = dynamic(() => import('@ant-design/icons/DeleteOutlined'), {
  ssr: false,
});

export type ChatModerationDetailsModalProps = {
  userId: string;
  accessToken: string;
};

export interface UserDetails {
  user: User;
  connectedClients: Client[];
  messages: Message[];
}

export interface Client {
  messageCount: number;
  userAgent: string;
  connectedAt: Date;
  geo: string;
  id: number;
}

export interface Message {
  id: string;
  timestamp: Date;
  user: null;
  body: string;
}

export interface User {
  id: string;
  displayName: string;
  displayColor: number;
  createdAt: Date;
  previousNames: string[];
  scopes: string[];
  isBot: boolean;
  authenticated: boolean;
}

const removeMessage = async (messageId: string, accessToken: string) => {
  try {
    ChatModeration.removeMessage(messageId, accessToken);
  } catch (e) {
    console.error(e);
  }
};

const ValueRow = ({ label, value }: { label: string; value: string }) => (
  <Row justify="space-around" align="middle">
    <Col span={12}>{label}</Col>
    <Col span={12}>{value}</Col>
  </Row>
);

const ConnectedClient = ({ client }: { client: Client }) => {
  const { messageCount, connectedAt, geo } = client;
  const connectedAtDate = format(new Date(connectedAt), 'PP pp');

  return (
    <div>
      <ValueRow label="Messages Sent" value={`${messageCount}`} />
      {geo !== 'N/A' && <ValueRow label="Geo" value={geo} />}
      <ValueRow label="Connected At" value={connectedAtDate} />
    </div>
  );
};

const UserColorBlock = ({ color }) => {
  const bg = `var(--theme-color-users-${color})`;
  return (
    <div className={styles.colorBlock} style={{ backgroundColor: bg }}>
      Color {color}
    </div>
  );
};

export const ChatModerationDetailsModal: FC<ChatModerationDetailsModalProps> = ({
  userId,
  accessToken,
}) => {
  const [userDetails, setUserDetails] = useState<UserDetails | null>(null);
  const [loading, setLoading] = useState(true);

  const getDetails = async () => {
    try {
      const response = await (
        await fetch(`/api/moderation/chat/user/${userId}?accessToken=${accessToken}`)
      ).json();
      setUserDetails(response);
      setLoading(false);
    } catch (e) {
      console.error(e);
    }
  };

  useEffect(() => {
    getDetails();
  }, []);

  if (!userDetails) {
    return null;
  }

  const { user, connectedClients, messages } = userDetails;
  const { displayColor, createdAt, previousNames, scopes, isBot, authenticated } = user;

  const totalMessagesSent = connectedClients.reduce((acc, client) => acc + client.messageCount, 0);
  const createdAtDate = format(new Date(createdAt), 'PP pp');

  const chatMessageColumns: ColumnsType<Message> = [
    {
      title: 'Message',
      dataIndex: 'body',
      key: 'body',
    },
    {
      title: 'Sent At',
      dataIndex: 'timestamp',
      key: 'timestamp',
      render: timestamp => format(new Date(timestamp), 'PP pp'),
    },
    {
      title: 'Delete',
      key: 'delete',
      render: (text, record) => (
        <Button
          type="primary"
          ghost
          icon={<DeleteOutlined />}
          onClick={() => removeMessage(record.id, accessToken)}
        />
      ),
    },
  ];
  return (
    <Spin spinning={loading}>
      <UserColorBlock color={displayColor} />
      {scopes?.map(scope => (
        <Tag key={scope}>{scope}</Tag>
      ))}
      {authenticated && <Tag>Authenticated</Tag>}
      {isBot && <Tag>Bot</Tag>}
      <ValueRow label="Messages Sent Across Clients" value={totalMessagesSent.toString()} />
      <ValueRow label="User Created" value={createdAtDate} />
      <ValueRow label="Known As" value={previousNames.join(',')} />
      <Collapse accordion>
        <Panel header="Currently Connected Clients" key="connected-clients">
          <Collapse accordion>
            {connectedClients.map(client => (
              <Panel header={formatUAstring(client.userAgent)} key={client.id}>
                <ConnectedClient client={client} />
              </Panel>
            ))}
          </Collapse>
        </Panel>
        <Collapse accordion>
          <Panel header="Recent Chat Messages" key="chat-messages">
            <Table
              size="small"
              pagination={null}
              columns={chatMessageColumns}
              dataSource={messages}
              rowKey="id"
            />
          </Panel>
        </Collapse>
      </Collapse>
    </Spin>
  );
};
