import { ProtobufNumber, ProtobufObject } from '../common/protojs.types.js';
import ItemMetadataState from './enums/ItemMetadataState.js';
import GapModel from './Gap.js';
import ThreadModel from './Thread';
import UserModel from './User.js';

// TODO(https://iavm.xyz/b/twpowertools/231): This class is being used for 2
// messages in different places. Fix this.
/**
 * Model for the `ForumMessage` protobuf message.
 *
 * WARNING: it has methods which correspond to the `MessageView` message.
 */
export default class MessageModel {
  private data: ProtobufObject;
  private thread: ThreadModel;
  private commentsAndGaps: Array<MessageModel | GapModel> | null;

  constructor(data?: ProtobufObject, thread?: ThreadModel) {
    this.data = data ?? {};
    this.thread = thread ?? new ThreadModel();
    this.commentsAndGaps = null;
  }

  getCreatedTimestamp() {
    return (this.data[1]?.[1]?.[2] as ProtobufNumber) ?? null;
  }

  getCreatedMicroseconds() {
    let a = this.getCreatedTimestamp();
    if (a === null) a = '0';
    return BigInt(a);
  }

  getRawCommentsAndGaps(): ProtobufObject[] {
    return this.data[12] ?? [];
  }

  private getMessageOrGapModels(): Array<MessageModel | GapModel> {
    const rawMogs = this.getRawCommentsAndGaps();
    return rawMogs
      .filter((mog) => mog !== undefined)
      .map((mog) => {
        if (mog[1]) return new MessageModel(mog[1], this.thread);
        if (mog[2]) return new GapModel(mog[2], this.thread);
        throw new Error('Expected message or gap.');
      });
  }

  getCommentsAndGaps(): Array<MessageModel | GapModel> {
    if (this.commentsAndGaps === null)
      this.commentsAndGaps = this.getMessageOrGapModels();
    return this.commentsAndGaps;
  }

  clearCommentsAndGaps() {
    this.commentsAndGaps = [];
    this.data[12] = [];
  }

  getPayload() {
    return this.data[1]?.[4] as string ?? null;
  }

  setPayload(value: string | null) {
    if (!this.data[1]) this.data[1] = [];
    this.data[1][4] = value;
  }

  getId() {
    return this.data[1]?.[1]?.[1] as ProtobufNumber ?? null;
  }

  getAuthor(): ProtobufObject | null {
    return this.data[3] ?? null;
  }

  getParentMessageId() {
    return this.data[1]?.[37] as ProtobufNumber ?? null;
  }

  clearParentMessageId() {
    if (!this.data[1]) return;
    delete this.data[1][37];
  }

  isDeleted() {
    return this.data[5]?.[3] as boolean ?? null;
  }

  getState() {
    return this.data[5]?.[1] as number ?? null;
  }

  getEndPendingStateTimestampMicros() {
    return this.data[1]?.[17] as ProtobufNumber ?? null;
  }

  isTakenDown() {
    return [
      ItemMetadataState.AUTOMATED_ABUSE_TAKE_DOWN_DELETE,
      ItemMetadataState.MANUAL_PROFILE_TAKE_DOWN_SUSPEND,
      ItemMetadataState.AUTOMATED_ABUSE_TAKE_DOWN_HIDE,
      ItemMetadataState.MANUAL_TAKE_DOWN_DELETE,
      ItemMetadataState.MANUAL_TAKE_DOWN_HIDE,
    ].includes(this.getState());
  }

  isComment() {
    return !!this.getParentMessageId;
  }

  toRawMessageOrGap(): ProtobufObject {
    return { 1: this.data };
  }

  mergeCommentOrGapViews(a: MessageModel) {
    this.commentsAndGaps = ThreadModel.mergeMessageOrGaps(
      a.getCommentsAndGaps(),
      this.getCommentsAndGaps(),
    );
    this.data[12] = this.commentsAndGaps.map((cog) => cog.toRawMessageOrGap());
  }

  /**
   * The following method is based on logic written by Googlers in the TW
   * frontend and thus is not included as part of the MIT license.
   *
   * Source:
   * module$exports$google3$customer_support$content$ui$client$tailwind$models$message_model$message_model.MessageModel.prototype.canComment
   */
  canComment(currentUser: UserModel) {
    if (this.isDeleted()) return false;
    if (this.isTakenDown()) return false;
    if (currentUser.isAccountDisabled()) return false;
    if (
      this.thread.isLocked() &&
      !currentUser.isAtLeastCommunityManager(this.thread.getForumId())
    ) {
      return false;
    }
    if (
      this.thread.isSoftLocked() &&
      !currentUser.isAtLeastSilverRole() &&
      !this.thread.isAuthoredByUser()
    ) {
      return false;
    }
    return true;
  }
}
