import { InfiniteData } from 'react-query';

import { AxiosResponse } from 'axios';

import { Attachment, FileTypes } from 'src/types/attachments';
import { FormListItem } from 'src/types/forms';
import { Reaction } from 'src/types/reaction';
import { Pagination } from 'src/types/services';
import { Topic } from 'src/types/tickets';
import { User, UserListResponse } from 'src/types/user';

export enum MessageType {
  AUDIO = 'AUDIO',
  FILE = 'FILE',
  BUTTON = 'BUTTON',
  TEXT = 'TEXT',
  INFO = 'INFO',
  INFO_PARAMS = 'INFO_PARAMS',
}

export enum ChatableType {
  USER = 'USER',
  TOPIC = 'TOPIC',
}

export enum ChatStatus {
  UNASSIGNED = 'UNASSIGNED',
  ASSIGNED = 'ASSIGNED',
  CLOSED = 'CLOSED',
  QUALIFIED = 'QUALIFIED',
}

export enum TicketUserStatus {
  CLOSED = 'CLOSED',
  QUALIFIED = 'QUALIFIED',
  CANCELLED = 'CANCELLED',
}

export enum GroupInfoMessagges {
  USER_CREATED_GROUP = 'USER_CREATED_GROUP',
  USER_CHANGED_GROUP_TITLE = 'USER_CHANGED_GROUP_TITLE',
  USER_CHANGED_GROUP_PICTURE = 'USER_CHANGED_GROUP_PICTURE',
  USER_LEFT = 'USER_LEFT',
  USERS_ADDED = 'USERS_ADDED',
  USERS_REMOVED = 'USERS_REMOVED',
  CALL_INITIALIZED = 'CALL_INITIALIZED',
  CALL_REJECTED = 'CALL_REJECTED',
  CALL_MISSED = 'CALL_MISSED',
  CALL_FINISHED = 'CALL_FINISHED',
}

export enum MessageStatus {
  SUCCESS = 'SUCCESS',
  ERROR = 'ERROR',
  PENDING = 'PENDING',
  FORWARDED = 'FORWARDED',
  DELETED = 'DELETED',
  EDITED = 'EDITED',
}

export enum ChatType {
  REGULAR = 'REGULAR',
  TICKET = 'TICKET',
  REGULAR_GROUP = 'REGULAR_GROUP',
  FORM = 'FORM',
}

export enum SLAType {
  RESOLUTION = 'TIME_TO_RESOLUTION',
  ATTENTION = 'TIME_TO_FIRST_RESPONSE',
}

export type Sender = 'contact' | 'user';

export type MessageUser = {
  hasLeftChat: boolean;
  fullName: string;
  color: string | null;
  deleted: boolean;
};

export type Message = {
  id?: number | string;
  userId: number;
  text: string;
  createdAt: Date;
  attachments: Attachment[] | null;
  type: string;
  status?: MessageStatus;
  chatId?: number;
  reactions: Reaction[] | null;
  replyMessageId?: number;
  replyMessage?: Message;
  user?: MessageUser;
};

export type Chat = {
  id: number;
  otherUser: User | null;
  otherUsers: User[] | null;
  isRead: boolean;
  archived: boolean;
  messageUpdatedAt: Date;
  isOpen: boolean;
  lastMessage: Message | null;
  lastMessageId: number;
  unreadMessages: number;
  markedAsUnread: boolean;
  messages?: Message[];
};

export type SLATimer = {
  deadline: string;
  elapsedTime: number;
  id: number;
  isRunning: boolean;
  sla: number;
  startDate: string;
  trackedTime: number;
  type: SLAType;
};

export type Responsible = {
  id: number;
  responsible: User;
};

export type RegularChatListItem = BaseChatListItem & {};

export type TicketChatListItem = BaseChatListItem & {
  id: number;
  subject: string;
  topic: Topic;
  status: string;
  responsibleId: number | null;
};

export type GroupChatListItem = BaseChatListItem & {
  title: string;
  description: string | null;
  pictureUrl: string | null;
  color: string;
  createdAt: string;
  isAdmin?: boolean;
};

export type FormChatListItem = BaseChatListItem & {
  form?: FormListItem;
  responsible?: User;
  possibleStatusDestinations?: string[];
  status?: string;
  timeToFirstResponseSlaTimer?: SLATimer;
  timeToFirstResponseSlaTimerId?: number;
  timeToResolutionSlaTimer?: SLATimer;
  timeToResolutionSlaTimerId?: number;
};

export type BaseChatListItem = {
  chat: Chat;
  chatId: number;
  chatType: ChatType;
};

export type ChatListItem = BaseChatListItem &
  RegularChatListItem &
  TicketChatListItem &
  GroupChatListItem &
  FormChatListItem;

// Data
export type GroupChatData = {
  title: string;
  pictureUrl: string;
  userIds: number[];
  color: string;
  isAdmin?: boolean;
};

// Responses
export type ChatListResponse = ChatListItem[];

export type ChatListResponsePagination = Pagination<ChatListItem[]>;

export type TicketListResponse = TicketChatListItem[];

export type ChatByIdResponse = ChatListItem;

export type CreateGroupChatResponse = ChatListItem;

export type EditGroupChatResponse = ChatListItem;

export type ChatMessagesResponse = Pagination<Message[]>;

export type PaginatedChatResponse = Pagination<BaseChatListItem[]>;

export type GroupDictionaryItem = {
  character: string;
  groups: ChatListItem[];
};

export type TicketAgentStats = {
  isResponsible: boolean;
  amountOfTicketsWhichNeedAttention: number;
};

export type ChatsNotificationsResponse = {
  userChatNotifications: number;
  agentChatNotifications: number;
};

export type PosibleParticipantsResponse = UserListResponse;

// Query data
export type ChatMessagesQueryData = InfiniteData<
  AxiosResponse<ChatMessagesResponse>
>;

// Socket
export type MessageEditedSocket = Omit<Message, 'user'>;

// Audio
export type AudioFile = {
  uri: string;
  mime: string;
  type: FileTypes.AUDIO;
  name: string;
  size: string;
  width: number;
};
