import { inject, Injectable } from '@angular/core';

import { Action, Selector, State, StateContext } from '@ngxs/store';
import { tap } from 'rxjs';

import {
  DownloadFilesAction,
  DownloadLicenseAction,
  DownloadsAction,
} from '../action/download.action';
import { IDownload } from '../interface/download.interface';
import { DownloadService } from '../services/download.service';

export class DownloadStateModel {
  download = {
    data: [] as IDownload[],
    total: 0,
  };
}

@State<DownloadStateModel>({
  name: 'download',
  defaults: {
    download: {
      data: [],
      total: 0,
    },
  },
})
@Injectable()
export class DownloadState {
  private downloadService = inject(DownloadService);

  @Selector()
  static download(state: DownloadStateModel) {
    return state.download;
  }

  @Action(DownloadsAction)
  downloads(ctx: StateContext<DownloadStateModel>, action: DownloadsAction) {
    return this.downloadService.downloads(action.payload).pipe(
      tap({
        next: result => {
          ctx.patchState({
            download: {
              data: result.data,
              total: result?.total ? result?.total : result.data?.length,
            },
          });
        },
        error: err => {
          throw new Error(err?.error?.message);
        },
      }),
    );
  }

  @Action(DownloadFilesAction)
  downloadFiles(ctx: StateContext<DownloadStateModel>, action: DownloadFilesAction) {
    return this.downloadService.downloadFiles(action.id).pipe(
      tap({
        next: result => {
          if (result && result.download_link) {
            window.location.assign(result.download_link);
          }
        },
        error: err => {
          throw new Error(err?.error?.message);
        },
      }),
    );
  }

  @Action(DownloadLicenseAction)
  downloadLicense(ctx: StateContext<DownloadStateModel>, action: DownloadFilesAction) {
    return this.downloadService.downloadLicense(action.id).pipe(
      tap({
        next: result => {
          if (result && result.download_link) {
            window.location.assign(result.download_link);
          }
        },
        error: err => {
          throw new Error(err?.error?.message);
        },
      }),
    );
  }
}
