import { CometChat } from "@cometchat/chat-sdk-react-native";
import { MessageBubbleAlignmentType } from "../base/Types";
import { CometChatMessageOption } from "./CometChatMessageOption";
import { CometChatTheme } from "../../theme/type";
import { JSX } from "react";

/**
 * Represents the interface for a message template.
 */
interface MessageTemplateInterface {
  /**
   * The category of the message template.
   */
  category: string;

  /**
   * The type of the message template.
   */
  type: (typeof CometChat.MESSAGE_TYPE)[keyof typeof CometChat.MESSAGE_TYPE];

  /**
   * The content view of the message template.
   * @param messageObject - The message object.
   * @param alignment - The alignment of the message bubble.
   * @returns The JSX element representing the content view.
   */
  ContentView?: (
    messageObject: CometChat.BaseMessage,
    alignment: MessageBubbleAlignmentType
  ) => JSX.Element | null;

  /**
   * The bubble view of the message template.
   * @param messageObject - The message object.
   * @returns The JSX element representing the bubble view.
   */
  BubbleView?: (messageObject: CometChat.BaseMessage) => JSX.Element | null;

  /**
   * The bottom view of the message template.
   * @param messageObject - The message object.
   * @returns The JSX element representing the bottom view.
   */
  BottomView?: (
    messageObject: CometChat.BaseMessage,
    alignment: MessageBubbleAlignmentType
  ) => JSX.Element | null;

  /**
   * The header view of the message template.
   * @param messageObject - The message object.
   * @param alignment - The alignment of the message bubble.
   * @returns The JSX element representing the header view.
   */
  HeaderView?: (
    messageObject: CometChat.BaseMessage,
    alignment: MessageBubbleAlignmentType
  ) => JSX.Element | null;

  LeadingView?: (
    messageObject: CometChat.BaseMessage,
    alignment: MessageBubbleAlignmentType
  ) => JSX.Element | null;

  /**
   * The status info view of the message template for DateTime and Receipt.
   * @param messageObject - The message object.
   * @param alignment - The alignment of the message bubble.
   * @returns The JSX element representing the status info view.
   */
  StatusInfoView?: (
    messageObject: CometChat.BaseMessage,
    alignment: MessageBubbleAlignmentType
  ) => JSX.Element | null;

  /**
   * The footer view of the message template.
   * @param messageObject - The message object.
   * @param alignment - The alignment of the message bubble.
   * @returns The JSX element representing the footer view.
   */
  FooterView?: (
    messageObject: CometChat.BaseMessage,
    alignment: MessageBubbleAlignmentType
  ) => JSX.Element | null;

  /**
   * The reply view of the message template for displaying quoted messages.
   * @param messageObject - The message object.
   * @param alignment - The alignment of the message bubble.
   * @returns The JSX element representing the reply view.
   */
  ReplyView?: (
    messageObject: CometChat.BaseMessage,
    alignment: MessageBubbleAlignmentType
  ) => JSX.Element | null;

  /**
   * The options of the message template.
   * @param loggedInUser - The logged in user.
   * @param messageObject - The message object.
   * @param group - The group.
   * @returns The array of CometChatMessageOption.
   */
  options?: (
    loggedInUser: CometChat.User,
    messageObject: CometChat.BaseMessage,
    theme: CometChatTheme,
    group?: CometChat.Group,
  ) => CometChatMessageOption[];
}

/**
 * Represents a message template for CometChat.
 */
export class CometChatMessageTemplate implements MessageTemplateInterface {
  /**
   * The category of the message template.
   */
  category: string;
  /**
   * The type of the message template.
   */
  type: (typeof CometChat.MESSAGE_TYPE)[keyof typeof CometChat.MESSAGE_TYPE];
  /**
   * The content view of the message template.
   * @param messageObject - The message object.
   * @param alignment - The alignment of the message bubble.
   * @returns The JSX element representing the content view.
   */
  ContentView?: (
    messageObject: CometChat.BaseMessage,
    alignment: MessageBubbleAlignmentType
  ) => JSX.Element | null;
  /**
   * The bubble view of the message template.
   * @param messageObject - The message object.
   * @returns The JSX element representing the bubble view.
   */
  BubbleView?: (messageObject: CometChat.BaseMessage) => JSX.Element | null;
  /**
   * The bottom view of the message template.
   * @param messageObject - The message object.
   * @returns The JSX element representing the bottom view.
   */
  BottomView?: (
    messageObject: CometChat.BaseMessage,
    alignment: MessageBubbleAlignmentType
  ) => JSX.Element | null;
  /**
   * The header view of the message template.
   * @param messageObject - The message object.
   * @param alignment - The alignment of the message bubble.
   * @returns The JSX element representing the header view.
   */
  HeaderView?: (
    messageObject: CometChat.BaseMessage,
    alignment: MessageBubbleAlignmentType
  ) => JSX.Element | null;

  LeadingView?: (
    messageObject: CometChat.BaseMessage,
    alignment: MessageBubbleAlignmentType
  ) => JSX.Element | null;
  /**
   * The status info view of the message template for DateTime and Receipt.
   * @param messageObject - The message object.
   * @param alignment - The alignment of the message bubble.
   * @returns The JSX element representing the status info view.
   */
  StatusInfoView?: (
    messageObject: CometChat.BaseMessage,
    alignment: MessageBubbleAlignmentType
  ) => JSX.Element | null;
  /**
   * The footer view of the message template.
   * @param messageObject - The message object.
   * @param alignment - The alignment of the message bubble.
   * @returns The JSX element representing the footer view.
   */
  FooterView?: (
    messageObject: CometChat.BaseMessage,
    alignment: MessageBubbleAlignmentType
  ) => JSX.Element | null;
  /**
   * The reply view of the message template for displaying quoted messages.
   * @param messageObject - The message object.
   * @param alignment - The alignment of the message bubble.
   * @returns The JSX element representing the reply view.
   */
  ReplyView?: (
    messageObject: CometChat.BaseMessage,
    alignment: MessageBubbleAlignmentType
  ) => JSX.Element | null;
  /**
   * The options of the message template.
   * @param loggedInUser - The logged in user.
   * @param messageObject - The message object.
   * @param group - The group.
   * @returns The array of CometChatMessageOption.
   */
  options?: (
    loggedInUser: CometChat.User,
    messageObject: CometChat.BaseMessage,
    theme: CometChatTheme,
    group?: CometChat.Group
  ) => CometChatMessageOption[];

  /**
   * Constructs a new instance of the CometChatMessageTemplate class.
   * @param {MessageTemplateInterface} options - The options for the message template.
   */
  constructor({
    category = "MESSAGE",
    type = CometChat.MESSAGE_TYPE.TEXT,
    ContentView,
    BottomView,
    BubbleView,
    HeaderView,
    LeadingView,
    StatusInfoView,
    FooterView,
    ReplyView,
    options,
  }: MessageTemplateInterface) {
    this.category = category;
    this.type = type;
    this.ContentView = ContentView;
    this.BottomView = BottomView;
    this.BubbleView = BubbleView;
    this.HeaderView = HeaderView;
    this.LeadingView = LeadingView;
    this.StatusInfoView = StatusInfoView;
    this.FooterView = FooterView;
    this.ReplyView = ReplyView;
    this.options = options;
  }
}
