import moment from 'moment';
import { database } from 'src/watermelondb';
import Message from 'src/watermelondb/models/Message';
import { addMessageDirtyAction, makeChatKey } from './message.sync';

type CreateOptimisticParams = {
  chatUid?: number;
  groupToken?: string;
  currentUserId: number;
  text?: string;
  uiAttachment?: any | null;
  sendAttachment?: any | null;
  replyMessage?: any | null;
  shouldAddDirty?: boolean;
};

export async function createOptimisticMessage({
  chatUid,
  groupToken,
  currentUserId,
  text = '',
  uiAttachment = null,
  sendAttachment = null,
  replyMessage = null,
  shouldAddDirty = true
}: CreateOptimisticParams) {
  const tempId = Date.now() * -1;
  const chatKey = makeChatKey({ chatUid, groupChatToken: groupToken });
  const compositeId = `${chatKey}:${tempId}`;

  const col = database.get<Message>('messages');

  await database.write(async () => {
    const batch: any[] = [];

    batch.push(
      col.prepareCreate((r) => {
        r.chatKey = chatKey;
        r.isGroup = chatUid ? false : true;

        r.messageId = tempId;
        r.compositeId = compositeId;

        r.sentAt = moment().utc().format('YYYY-MM-DD HH:mm:ss');
        r.receivedAt = null;
        r.readAt = null;

        r.senderId = currentUserId;
        r.recipientId = chatUid!;

        r.text = text;
        r.status = 1;
        r.isSending = true;

        r.reactions = '{}';
        r.edits = '{}';

        r.attachment = uiAttachment ? JSON.stringify(uiAttachment) : null;
        r.encrypted = 0;

        if (replyMessage) {
          r.replyToId = replyMessage.id;
          r.replyTo = JSON.stringify(replyMessage);
        } else {
          r.replyToId = -1;
          r.replyTo = null;
        }

        if (shouldAddDirty) {
          addMessageDirtyAction(r, {
            type: 'send',
            value: {
              text,
              currentUid: currentUserId,
              attachment: sendAttachment ?? -1,
              reply_to_id: replyMessage ? replyMessage.id : -1,
              replyMessage
            }
          });
        }
      })
    );

    await database.batch(batch);
  });

  return tempId;
}
