import {PixelRatio} from 'react-native';
import {
  Icon,
  IconChecks,
  IconClock,
  IconExclamationCircle,
} from '@tabler/icons-react-native';
import i18next from 'i18next';
import {SpringTransition} from 'react-native-ease';
import {EventsSocketsType} from '@config/constants';
import {ENV} from '@shared/keys';

import {
  ChatEventSubtype,
  ChatEventType,
  ChatUserStatus,
  MentionUser,
} from './interfaces';
import {
  LINE_HEIGHT_S_DIFFERENCE,
  LINE_HEIGHT_XS_DIFFERENCE,
} from './utils/computation';

export const CHATS_ERROR = 'Chats2Error';

export const ERROR_MESSAGES = {
  NO_APP_ASSOCIATED: 'No app associated with this mime type',
};

export const CHAT_ATTACHMENT_VIDEO_BITRATE = 2140000;
export const CHAT_ATTACHMENT_AUDIO_BITRATE = 128000;

// Sized-image variants requested via `?width=N`. Three tiers covering
// the display-size buckets we render at:
//   - TINY:   reply previews (50 dp), gallery selector strip (70 dp),
//             and the placeholder pass for single big chat tiles.
//   - SMALL:  every chat tile thumbnail — small/medium grids (80–120 dp)
//             AND the upgrade pass for the single big tile (160 dp).
//   - MEDIUM: gallery main video poster (~window width).
//
// Each tier is `base_dp × DPR`. We scale linearly (no cap) so the
// requested pixel count matches the device's actual screen pixel count
// for each tier:
//   - 2× DPR Android / iPad: 200 / 400 / 800 px
//   - 2.5× DPR mid-tier:     250 / 500 / 1000 px
//   - 3× DPR iPhone Pro:     300 / 600 / 1200 px
// Low-end Android (2×) downloads the smallest variants while iPhone Pro
// (3×) gets enough pixels to stay sharp on its denser screen — each
// device pays only for the bytes its display actually needs.
export const DPR = PixelRatio.get();

export const IMAGE_SIZE_TINY_PX = Math.round(50 * DPR);
export const IMAGE_SIZE_SMALL_PX = Math.round(150 * DPR);
export const IMAGE_SIZE_MEDIUM_PX = Math.round(300 * DPR);

export const CONVERSATIONS_QUERY_LIMIT = 15;
export const CONVERSATION_ITEM_AVATAR_SIZE = 56;
export const CONVERSATION_ITEM_V_PADDING = 8;
export const CONVERSATION_ITEM_HEIGHT =
  CONVERSATION_ITEM_AVATAR_SIZE +
  LINE_HEIGHT_XS_DIFFERENCE +
  LINE_HEIGHT_S_DIFFERENCE +
  CONVERSATION_ITEM_V_PADDING * 2;

export const CONVERSATION_SEPARATOR_HEIGHT = 1;
export const CHAT_MESSAGE_HEADER_HEIGHT = 64;
export const CONVERSATION_MESSAGES_LIMIT = 100;
export const INITIAL_LOAD_LIMIT = 100;
export const MESSAGES_QUERY_LIMIT = 50;
export const SYNC_EVENTS_LIMIT = 50;
export const MESSAGES_BATCH_SIZE = 50;
export const CHAT_MAX_ATTACHMENTS = 10;
export const LOCAL_INITIAL_VERSION = -1;
export const MAX_REACTIONS_FOR_MESSAGE = 8;
export const MAX_REACTIONS_PER_LINE = 4;
export const MAX_GROUP_DESCRIPTION_LENGTH = 2047;
export const CHAT_FOOTER_HEIGHT = 72;
export const CHAT_FOOTER_MAX_HEIGHT = 148;
export const PRIORITY_CONVERSATION_COUNT = 20;
export const DEFAULT_MENTION_NAME = 'Unknown';
export const MAX_FORWARD_ITEMS = 5;
export const MAX_PINNED_CONVERSATIONS = 5;
export const CHAT_PORTAL_HOST_NAME = {
  messages: 'chat-messages',
};
export const MAX_AUDIO_RECORDING_MINUTES = 10;
export const MAX_AUDIO_RECORDING_DURATION_MS =
  MAX_AUDIO_RECORDING_MINUTES * 60 * 1000;
export const MIN_AUDIO_RECORDING_DURATION_MS = 500;

export const AI_SUMMARY_MAX_RECORDING_DURATION_MS = 5 * 60 * 1000;
export const AI_SUMMARY_MIN_RECORDING_DURATION_MS = 5000;
export const AUDIO_ANIMATED_VALUES = {
  lockThreshold: 100,
  cancelThreshold: 100,
  cancelingAnimationDurationMs: 2000,
  showLockerDelay: 100,
  isActiveAnimationDuration: 300,
  micBlinkingAnimationDuration: 550,
  hintVisibilityDuration: 2000,
};

export const CHATS_QUERY_KEYS = {
  conversations: ['chatsConversations'],
  searchUsers: (search?: string) => ['chatsSearchUsers', search],
  searchChats: (search?: string) => ['chatsSearchChats', search],
  messageInfo: (ts: string, channel: string) => [
    'chatsMessageInfo',
    ts,
    channel,
  ],
};

export enum MessageStatusUI {
  Sent = 'SENT',
  Delivered = 'DELIVERED',
  Read = 'READ',
  Sending = 'SENDING',
  Error = 'ERROR',
}

export const MESSAGE_STATUS_ICONS: {[key: string]: Icon} = {
  [MessageStatusUI.Sent]: IconChecks,
  [MessageStatusUI.Delivered]: IconChecks,
  [MessageStatusUI.Read]: IconChecks,
  [MessageStatusUI.Sending]: IconClock,
  [MessageStatusUI.Error]: IconExclamationCircle,
};

/**
 * List of features that are available in the app.
 * We should never remove items in this array, just add new ones at the end.
 */

export enum FeatureKey {
  MessageInfo = 'message_info',
  MentionAll = 'mention_all',
  SearchMessage = 'search_message',
  VoiceMessage = 'voice_message',
  MessagePin = 'message_pin',
  NewCallsV2 = 'new_calls_v2', // This feat is displayed in a separate dialog in a chat screen
}

export const CHATS_FEATURES = [
  FeatureKey.MessageInfo,
  FeatureKey.MentionAll,
  FeatureKey.SearchMessage,
  FeatureKey.VoiceMessage,
  FeatureKey.MessagePin,
] as const;

export const CHATS_LOCAL_STORAGE_KEYS = {
  HasFetchedRecentEvents: 'CHATS_2_HAS_FETCHED_RECENT_EVENTS',
  HasFetchedAllConversations: 'CHATS_2_HAS_FETCHED_ALL_CONVERSATIONS',
  UnreadsStorage: 'CHATS_2_UNREADS_STORAGE',
  MessageRangesStorage: 'CHATS_2_MESSAGE_RANGES_STORAGE',
  ProcessedMessagesStorage: 'CHATS_2_PROCESSED_MESSAGES_STORAGE',
  LastFeatureShown: 'CHATS_2_LAST_FEATURE_SHOWN',
  PinnedMessagesStorage: 'CHATS_2_PINNED_MESSAGES_STORAGE',
  NewCallsV2ViewedStorage: 'CHATS_2_NEW_CALLS_V2_VIEWED_STORAGE',
  AiSummaryTooltipViewed: 'CHATS_2_AI_SUMMARY_TOOLTIP_VIEWED',
  ConversationDraftsStorage: 'CHATS_2_CONVERSATION_DRAFTS_STORAGE',
};

export enum AmplitudeConversationTypes {
  Individual = 'individual',
  Group = 'group',
}

export enum AmplitudeLeftReason {
  Voluntary = 'voluntary',
  Kicked = 'kicked',
}

export enum AmplitudeMessageTypes {
  Text = 'text',
  Image = 'image',
  File = 'file',
  ImageAndText = 'imageAndText',
  ImagesAndVideoAndText = 'imagesAndVideoAndText',
  ImagesAndVideo = 'imagesAndVideo',
  FileAndText = 'fileAndText',
  Audio = 'voiceNote',
  Gif = 'gif',
  Video = 'video',
  VideoAndText = 'videoAndText',
}

export const AUDIO_EXTENSIONS = ['MP4', 'AAC', 'WAV', 'PCM', 'M4A'];

export const CHATS_EVENTS_MAPPER = {
  [ChatEventType.channelCreated]: EventsSocketsType.CHATS_V2_NEW_CHANNEL,
  [ChatEventType.channelJoined]: EventsSocketsType.CHATS_V2_JOINED_CHAT,
  [ChatEventType.channelLeft]: EventsSocketsType.CHATS_V2_LEFT_CHAT,
  [`${ChatEventType.channelLeft}:${ChatEventSubtype.adminKicks}`]:
    EventsSocketsType.CHATS_V2_LEFT_CHAT,
  [`${ChatEventType.channelLeft}:${ChatEventSubtype.userDeactivation}`]:
    EventsSocketsType.CHATS_V2_LEFT_CHAT,
  [`${ChatEventType.channelLeft}:${ChatEventSubtype.userDeletion}`]:
    EventsSocketsType.CHATS_V2_LEFT_CHAT,
  [`${ChatEventType.channelLeft}:${ChatEventSubtype.userLeft}`]:
    EventsSocketsType.CHATS_V2_LEFT_CHAT,
  [ChatEventType.channelMarked]: EventsSocketsType.CHATS_V2_READ_CHAT,
  [ChatEventType.imCreated]: EventsSocketsType.CHATS_V2_NEW_CHAT,
  [ChatEventType.message]: EventsSocketsType.CHATS_V2_NEW_MESSAGE,
  [ChatEventType.channelAdminGranted]: EventsSocketsType.CHATS_V2_ADMIN_ADDED,
  [ChatEventType.channelAdminRevoked]: EventsSocketsType.CHATS_V2_ADMIN_REMOVED,
  [ChatEventType.channelChanged]: EventsSocketsType.CHATS_V2_CHANNEL_CHANGED,
  [`${ChatEventType.messageUpdate}:${ChatEventSubtype.messageUpdate}`]:
    EventsSocketsType.CHATS_V2_UPDATE_MESSAGE,
  [`${ChatEventType.messageReaction}:${ChatEventSubtype.add}`]:
    EventsSocketsType.CHATS_V2_REACTION_ADD,
  [`${ChatEventType.messageReaction}:${ChatEventSubtype.remove}`]:
    EventsSocketsType.CHATS_V2_REACTION_REMOVE,
  [ChatEventType.messageUpdate]: EventsSocketsType.CHATS_V2_UPDATE_MESSAGE,
  [ChatEventType.messageDeleted]: EventsSocketsType.CHATS_V2_DELETED_MESSAGE,
  [ChatEventType.attachmentChanged]: EventsSocketsType.CHATS_V2_ASSET_CHANGED,
  [`${ChatEventType.markedReceived}:${ChatEventSubtype.markedReceived}`]:
    EventsSocketsType.CHATS_V2_MARKED_RECEIVED,
  [`${ChatEventType.markedRead}:${ChatEventSubtype.markedRead}`]:
    EventsSocketsType.CHATS_V2_MARKED_READ,
  [ChatEventType.channelInfoChanged]:
    EventsSocketsType.CHATS_V2_CHANNEL_INFO_CHANGED,
  [`${ChatEventType.messagePin}:${ChatEventSubtype.add}`]:
    EventsSocketsType.CHATS_V2_PIN_ADD,
  [`${ChatEventType.messagePin}:${ChatEventSubtype.remove}`]:
    EventsSocketsType.CHATS_V2_PIN_REMOVE,
  [`${ChatEventType.messageReadByAll}:${ChatEventSubtype.messageReadByAll}`]:
    EventsSocketsType.CHATS_V2_MESSAGE_READ_BY_ALL,
} as const;

export type EventSocketName = keyof typeof CHATS_EVENTS_MAPPER;

export type ChatMuteOption = '1m' | '8h' | '1w' | 'always';

export const MUTE_OPTIONS: ChatMuteOption[] = ['dev', 'stg'].includes(ENV)
  ? ['1m', '8h', '1w', 'always']
  : ['8h', '1w', 'always'];

export type PinDuration = '1m' | '24h' | '30d' | 'always';

export const PIN_DURATION_OPTIONS: PinDuration[] = ['dev', 'stg'].includes(ENV)
  ? ['1m', '24h', '30d', 'always']
  : ['24h', '30d', 'always'];

export const MAX_PINNED_MESSAGES = 3;

export const INACTIVE_USER_STATUSES = {
  [ChatUserStatus.Deleted]: true,
  [ChatUserStatus.Deactivated]: true,
};

export const COMMAND_TAGS: Record<string, number> = {
  all: -1,
};

export const ALL_MENTION = {
  id: COMMAND_TAGS.all,
  label: 'all',
  command: '<!channel>',
  getLocalLabel: () => i18next.t('chat.messages.mention_all'),
  isMatch: (text: string) => {
    const localLabel = i18next
      .t('chat.messages.mention_all')
      .replace('@', '')
      .toLowerCase();
    const label = 'all';
    return (
      localLabel.includes(text.toLowerCase()) ||
      label.includes(text.toLowerCase())
    );
  },
  item: {
    id: COMMAND_TAGS.all,
    firstName: 'all',
    lastName: '',
    profilePicture: null,
  } as MentionUser,
};

export const SpringTransitionBouncyConfig: SpringTransition = {
  type: 'spring',
  mass: 3,
  stiffness: 1000,
  damping: 50,
};

export const SpringTransitionConfig: SpringTransition = {
  type: 'spring',
  mass: 3.5,
  stiffness: 3000,
  damping: 200,
};
