import startCase from 'lodash-es/startCase';

import { UserStatePayload } from 'mweb/chat/chatClient';
import {
  MessageEvent,
  MessageEventType,
  POST,
} from 'mweb/chat/events/messageEvent';
import {
  ModerationEvent,
  ModerationEventType,
  TIMEOUT,
} from 'mweb/chat/events/moderationEvent';
import {
  SUBSCRIPTION,
  RESUBSCRIPTION,
  SubscriptionEvent,
  ResubscriptionEvent,
} from 'mweb/chat/events/subscribeEvent';
import {
  ConnectionStatusEventType,
  HostingStatusEventType,
  ConnectionStatusEvent,
  HostingStatusEvent,
  DISCONNECTED,
  CONNECTED,
  HOSTING,
  UNHOST,
} from 'mweb/chat/events/statusEvent';
import { ChatEvent } from 'mweb/chat/events/baseChatEvent';
import {
  makeCheermoteURL,
  MessagePart,
  BITS_COLOR_MAP,
} from 'mweb/chat/events/utils/createMessageData';
import idCreator from 'mweb/chat/events/utils/idCreator';

export const TEST_MESSAGE: string = 'Kappa text';

export const TEST_USERSTATE: UserStatePayload = {
  badges: { warcraft: 'horde' },
  bits: undefined,
  color: '#aabbcc',
  'display-name': 'Voxel',
  emotes: { 25: ['0-4'] },
  id: '1234567890',
  'user-id': '12345',
  username: 'voxel',
};

const TEXT_MESSAGE_PART: MessagePart = {
  type: 'TEXT',
  content: ' text ',
};

const EMOTE_MESSAGE_PART: MessagePart = {
  type: 'EMOTE',
  content: {
    alt: 'Kappa',
    images: {
      '1x': 'https://static-cdn.jtvnw.net/emoticons/v1/25/1.0',
      '2x': 'https://static-cdn.jtvnw.net/emoticons/v1/25/2.0',
      '4x': 'https://static-cdn.jtvnw.net/emoticons/v1/25/3.0',
    },
  },
};

const LINK_MESSAGE_PART: MessagePart = {
  type: 'LINK',
  content: {
    displayText: 'chat.rocks',
    url: 'https://chat.rocks',
  },
};

let idCounter = 0;
export function buildTestMessageEvent(
  username: string = 'voxel',
  type: MessageEventType = POST,
  deleted: boolean = false,
): MessageEvent {
  idCounter += 1;
  return {
    type,
    id: String(idCounter),
    badges: [
      {
        images: {
          '1x':
            'https://static-cdn.jtvnw.net/badges/v1/de8b26b6-fd28-4e6c-bc89-3d597343800d/1',
          '2x':
            'https://static-cdn.jtvnw.net/badges/v1/de8b26b6-fd28-4e6c-bc89-3d597343800d/2',
          '4x':
            'https://static-cdn.jtvnw.net/badges/v1/de8b26b6-fd28-4e6c-bc89-3d597343800d/3',
        },
        alt: 'For the Horde!',
      },
    ],
    user: {
      username: username,
      usernameDisplay: startCase(username),
      color: '#aabbcc',
      isIntl: false,
    },
    messageParts: [EMOTE_MESSAGE_PART, TEXT_MESSAGE_PART, LINK_MESSAGE_PART],
    deleted,
  };
}

export function buildTestMessageEventWithCheer(
  username: string = 'voxel',
): MessageEvent {
  idCounter += 1;
  return {
    type: POST,
    id: String(idCounter),
    badges: [],
    user: {
      username: username,
      usernameDisplay: startCase(username),
      color: '#aabbcc',
      isIntl: false,
    },
    messageParts: [
      {
        type: 'EMOTE',
        content: {
          alt: 'Cheer',
          images: {
            '1x': makeCheermoteURL('cheer', 100, 1),
            '1.5x': makeCheermoteURL('cheer', 100, 1.5),
            '2x': makeCheermoteURL('cheer', 100, 2),
            '3x': makeCheermoteURL('cheer', 100, 3),
            '4x': makeCheermoteURL('cheer', 100, 4),
          },
          cheerColor: BITS_COLOR_MAP.purple,
          cheerAmount: 100,
        },
      },
    ],
    deleted: false,
  };
}

export function buildTestModerationEvent(
  username: string = 'voxel',
  type: ModerationEventType = TIMEOUT,
  reason: string | null = 'for being too awesome',
): ModerationEvent {
  return {
    type,
    id: idCreator(`${username}-mod`),
    username,
    reason,
    duration: 0.001,
  };
}

export function buildTestSubscriptionEvent(
  isPrime: boolean = false,
): SubscriptionEvent {
  return {
    type: SUBSCRIPTION,
    id: idCreator(`voxel-sub`),
    username: 'voxel',
    channel: 'lirik',
    isPrime,
  };
}

export function buildTestResubscriptionEvent(
  isPrime: boolean = false,
  withMessage: boolean = false,
  deleted: boolean = false,
): ResubscriptionEvent {
  return {
    type: RESUBSCRIPTION,
    id: idCreator(`voxel-sub`),
    isPrime,
    months: 3,
    channel: 'lirik',
    badges: [],
    user: {
      username: 'voxel',
      usernameDisplay: 'Voxel',
      color: 'Toasted Meringue',
      isIntl: false,
    },
    messageParts: withMessage ? [TEXT_MESSAGE_PART] : undefined,
    deleted,
  };
}

export function buildTestConnectionStatusMessage(
  type: ConnectionStatusEventType = CONNECTED,
  withReason: boolean = false,
): ConnectionStatusEvent {
  if (type === DISCONNECTED) {
    return {
      type: DISCONNECTED,
      id: 'yolo',
      reason: withReason ? 'lost in a series of tubes' : undefined,
    };
  }
  return {
    type,
    id: 'yolo',
  } as ConnectionStatusEvent;
}

export function buildTestHostingStatusMessage(
  type: HostingStatusEventType = HOSTING,
): HostingStatusEvent {
  if (type === HOSTING) {
    return {
      type: HOSTING,
      id: 'hostapalooza',
      channel: 'voxel',
      hostedChannel: 'monstercat',
    };
  }
  return {
    type: UNHOST,
    id: 'no-more-hosta',
    channel: 'voxel',
  };
}

function randomBoolean(): boolean {
  return Boolean(Math.round(Math.random()));
}

export function createTestEvents(count: number = 100): ChatEvent[] {
  return Array(count)
    .fill(0)
    .map(() => {
      const rand = Math.round(Math.random() * 99);
      if (rand >= 98) {
        return buildTestResubscriptionEvent(randomBoolean(), randomBoolean());
      } else if (rand >= 95) {
        return buildTestSubscriptionEvent(randomBoolean());
      } else if (rand >= 91) {
        return buildTestModerationEvent();
      } else if (rand >= 90) {
        return buildTestMessageEventWithCheer();
      } else {
        return buildTestMessageEvent();
      }
    });
}
