import defaultsDeep from 'lodash-es/defaultsDeep';

import { UserStatePayloadBadges } from 'mweb/chat/chatClient';

export const GLOBAL_BADGES_URL =
  'https://badges.twitch.tv/v1/badges/global/display';

export function makeChannelBadgeURL(channelID: string): string {
  return `https://badges.twitch.tv/v1/badges/channels/${channelID}/display`;
}

interface BadgePayloadVersion {
  readonly image_url_1x: string;
  readonly image_url_2x: string;
  readonly image_url_4x: string;
  readonly description: string;
  readonly title: string;
  readonly click_action: string;
  readonly click_url: string;
}

export interface BadgesPayload {
  readonly [badgeSet: string]: {
    readonly versions: {
      readonly [badge: string]: BadgePayloadVersion;
    };
  };
}

export interface Badge {
  readonly images: {
    readonly [scale: string]: string;
  };
  readonly alt: string;
}

export class BadgerService {
  badges: BadgesPayload;

  async init(channelID: string): Promise<void> {
    const badges = await Promise.all([
      this.getGlobalBadges(),
      this.getChannelBadges(channelID),
    ]);
    this.badges = defaultsDeep(badges[1], badges[0]) as BadgesPayload;
  }

  getBadgeData(badges: UserStatePayloadBadges | null): Badge[] {
    if (!badges) {
      return [];
    }
    return Object.keys(badges)
      .map(badge => {
        let badgeData: BadgePayloadVersion;
        try {
          badgeData = this.badges[badge].versions[badges[badge]];
        } catch (err) {
          return undefined;
        }
        return {
          images: {
            '1x': badgeData.image_url_1x,
            '2x': badgeData.image_url_2x,
            '4x': badgeData.image_url_4x,
          },
          alt: badgeData.description,
        };
      })
      .filter(x => x) as Badge[];
  }

  getGlobalBadges(): Promise<BadgesPayload> {
    return this.fetch(GLOBAL_BADGES_URL);
  }

  getChannelBadges(channelID: string): Promise<BadgesPayload> {
    return this.fetch(makeChannelBadgeURL(channelID));
  }

  async fetch(url: string): Promise<BadgesPayload> {
    try {
      const resp = await fetch(url);
      const data = await resp.json();
      return data.badge_sets;
    } catch {
      return {};
    }
  }
}

const badgerService = new BadgerService();
export default badgerService;
