import { Offer } from '@wix/bex-utils/@wix/ambassador-dealer-v1-serving-offer/types';
import { listOffers } from '@wix/bex-utils/@wix/ambassador-dealer-v1-serving-offer/http';
import { computed, makeObservable } from 'mobx';
import {
  ReportBI,
  TaskState,
  WixPatternsContainer,
  WixPatternsContainerParams,
} from '@wix/bex-core';
import { SuggestionsBIReporter } from './SuggestionsBIReporter';

export interface SuggestionsStateParams {
  placementId: string;
  container: WixPatternsContainer;
}

export class SuggestionsState {
  readonly placementId: string;
  readonly container: WixPatternsContainer;
  readonly fetchOffersTask = new TaskState<Offer[]>();
  readonly reportBI: ReportBI;

  readonly bi: SuggestionsBIReporter;
  readonly httpClient: WixPatternsContainerParams['httpClient'];

  constructor(params: SuggestionsStateParams) {
    this.placementId = params.placementId;
    this.container = params.container;
    this.httpClient = this.container.httpClient;
    this.reportBI = this.container.createBILogger({
      componentType: 'suggestionsWidget',
      route: window.location.pathname,
    });

    this.bi = new SuggestionsBIReporter({
      reportBI: this.reportBI,
      realEstateId: this.placementId,
      httpClient: this.httpClient,
    });

    makeObservable(this, {
      offers: computed,
      isFetching: computed,
      hasOffers: computed,
    });
  }

  init = () => {
    const startTime = performance.now();

    this.bi.loadStart();

    this.fetchOffersTask.runOnce(async () => {
      const offers = await this._fetchOffers();
      this.bi.loadEnd(startTime);
      return offers;
    });
  };

  private _fetchOffers = async () => {
    const { placementId, httpClient } = this;
    const { data } = await httpClient.request(
      listOffers({ realEstateId: placementId }),
    );

    return data.offers ?? [];
  };

  get offers(): Offer[] {
    return this.fetchOffersTask.status.isSuccess
      ? this.fetchOffersTask.status.data
      : [];
  }

  get isFetching(): boolean {
    return this.fetchOffersTask.status.isLoading;
  }

  get hasOffers() {
    return this.offers.length > 0;
  }

  onOfferViewed = (offerId: string) => {
    this.bi.reportOfferViewed(offerId);
  };

  onOfferClicked = (offerId: string, targetUrl?: string) => {
    this.bi.reportOfferClicked(offerId, targetUrl);
  };
}
