import {
  PlayerAnalyticsTracker,
  PlayerAnalyticsTrackerI,
} from "./playerAnalyticsTracker";
import {
  PlayerLifecycleListener,
  PlayerManager,
} from "../appUtils/playerManager";
import { Player } from "../appUtils/playerManager/player";
import { AnalyticPlayerListener } from "./AnalyticPlayerListener";
import { PlayerRole } from "../appUtils/playerManager/conts";

enum PlayerAnalyticsTrackerType {
  PlayerAnalyticsTracker = "PlayerAnalyticsTracker",
}

class PlayerAnalyticsTrackerFactory {
  createTracker(type: PlayerAnalyticsTrackerType) {
    switch (type) {
      case PlayerAnalyticsTrackerType.PlayerAnalyticsTracker:
        return new PlayerAnalyticsTracker();
      default:
        return new PlayerAnalyticsTracker();
    }
  }
}

export class PlayerAnalyticsManager implements PlayerLifecycleListener {
  static instance: PlayerAnalyticsManager;
  private trackers: Record<string, PlayerAnalyticsTrackerI> = {};
  private trackerFactory: PlayerAnalyticsTrackerFactory;

  public getTracker(
    id: string,
    type: PlayerAnalyticsTrackerType = PlayerAnalyticsTrackerType.PlayerAnalyticsTracker
  ): PlayerAnalyticsTrackerI {
    if (!this.trackers[id]) {
      this.trackers[id] = this.trackerFactory.createTracker(type);
    }

    return this.trackers[id];
  }

  constructor(trackerFactory: PlayerAnalyticsTrackerFactory) {
    this.trackerFactory = trackerFactory;
    this.startListenPlayerManager();
  }

  static getInstance(
    trackerFactory: PlayerAnalyticsTrackerFactory = new PlayerAnalyticsTrackerFactory()
  ): PlayerAnalyticsManager {
    if (!PlayerAnalyticsManager.instance) {
      PlayerAnalyticsManager.instance = new PlayerAnalyticsManager(
        trackerFactory
      );
    }

    return PlayerAnalyticsManager.instance;
  }

  private startListenPlayerManager() {
    PlayerManager.getInstance().addLifecycleListener(this);
  }

  // PlayerLifecycleListener

  onRegistered = (player: Player) => {
    if (player.playerRole !== PlayerRole.Primary) {
      return;
    }

    const tracker = this.getTracker(player.playerId);
    tracker.setPlayer(player);

    const analyticsListener = new AnalyticPlayerListener({
      analyticsTracker: tracker,
      player,
    });

    player.addListener({
      id: AnalyticPlayerListener.analyticsListenerID,
      listener: analyticsListener,
    });
  };

  onUnRegistered = (player: Player) => {
    player.removeListener(AnalyticPlayerListener.analyticsListenerID);
    delete this.trackers[player.playerId];
  };
}
