import { action, makeObservable, observable, runInAction, toJS } from 'mobx';
import { environment } from 'enviroments/enviroments';
import { loadable } from './Decorators/LoadingDecorator';
import { IncidentsRecord } from 'types/default';
import { Entity, EntityStore } from './EntityStore';
import { RootStore } from './RootStore';
import { Incident, IncidentEdit } from '../myApi';
import request from 'services/request';
import FileDownload from '../services/FileDownload';

type ListRecord = IncidentsRecord;

export type TypeRecommendationOrEffectsResults = {
  description: string;
  id: number;
  name: string;
};

export type TypeRecommendationOrEffectsList =
  | {
      count: number;
      next: string | null;
      previous: string | null;
      results: TypeRecommendationOrEffectsResults[];
    }
  | undefined;

export class Incidents extends Entity {
  @observable private listRecord: ListRecord;

  constructor(id: string, listRecord: ListRecord) {
    super(id);
    this.listRecord = listRecord;
  }

  get _listRecord(): any {
    return this.listRecord;
  }

  @action
  setListRecord = (value: ListRecord): any => {
    this.listRecord = value;
  };
}

export class IncidentsStore extends EntityStore<Incidents> {
  @observable recommendationsList: TypeRecommendationOrEffectsList;

  @observable incident: Incident | null = null;

  @observable effectsList: TypeRecommendationOrEffectsList;

  @observable isIncidentLoading = false;

  constructor(private readonly rootStore: RootStore) {
    super();
    makeObservable(this);
  }

  async fetchIncidentsList(
    page: number,
    pageSize: number,
    sort: string,
  ): Promise<void> {
    const response = await request({
      method: 'get',
      url:
        page && pageSize
          ? `${environment.endPoints.incidents.incident}?page=${page}&page_size=${pageSize}${sort}`
          : `${environment.endPoints.incidents.incident}`,
      data: {
        filter: [
          {
            field: 'importance',
            filter_type: 'integer-range',
            value: '100;101',
          },
        ],
      },
    });

    runInAction(() => {
      this.entities.clear();
      this.total = response.data.count;
      for (const item of response.data.results) {
        const incident = new Incidents(item.user_friendly_id, item);
        incident.setListRecord(item);
        this.entities.set(item.user_friendly_id, incident);
      }
    });
  }

  async fetchIncidentById(uuid: string): Promise<void> {
    this.isIncidentLoading = true;
    const response = await request({
      method: 'get',
      url: `incidents/${uuid}/`,
      data: {
        filter: [
          {
            field: 'importance',
            filter_type: 'integer-range',
            value: '100;101',
          },
        ],
      },
    });

    runInAction(() => {
      this.incident = response.data;
    });

    this.isIncidentLoading = false;
  }

  resetSelectedIncident(): void {
    this.incident = null;
  }

  async patchIncident(id: string, data: IncidentEdit): Promise<void> {
    const response = await request({
      method: 'patch',
      url: `${environment.endPoints.incidents.incident}${id}/`,
      data,
    });

    runInAction(() => {
      const newRecord = new Incidents(
        response.data.user_friendly_id,
        response.data,
      );
      this.entities.set(newRecord.id as string, newRecord);
      this.incident = response.data;
    });
  }

  async exportCSV(): Promise<any> {
    return request({
      method: 'get',
      url: `${environment.exportsCSV.incidents}`,
      responseType: 'blob',
    }).then((res: any) => {
      const regexp = /"(.*?)"/;
      const filename = res.headers['content-disposition'].match(regexp)[1];
      FileDownload(res.data, filename);
    });
  }

  @loadable
  async fetchRecommendations(page: number): Promise<void> {
    const response = await request({
      method: 'get',
      url: `incidents/recommendations/?page=${page}`,
    });

    runInAction(() => {
      this.recommendationsList = response.data;
    });
  }

  @loadable
  async fetchEffects(page: number): Promise<void> {
    const response = await request({
      method: 'get',
      url: `incidents/effects/?page=${page}`,
    });

    runInAction(() => {
      this.effectsList = response.data;
    });
  }
}
