import { effect, inject, Injectable } from '@angular/core';
import { MessageService } from './message.service';
import { httpResource, HttpResourceOptions, HttpResourceRequest } from '@angular/common/http';
import { getOdata, saveFile, openOrSaveFile } from '../utils/util';

export interface HttpResourceRequestWithFileName extends HttpResourceRequest {
  fileName: string;
}

@Injectable({ providedIn: 'root' })
export class FastResourceService {
  private messageService = inject(MessageService);

  http = <T>(
    request: () => HttpResourceRequest | undefined,
    options?: HttpResourceOptions<T, unknown>
  ) => {
    const resource = httpResource<T>(request, options);
    effect(() => {
      const error = resource.error();
      if (error)
        this.messageService.throw(error);
    });

    return resource;
  }

  httpText = <T = string>(
    request: () => HttpResourceRequest | undefined,
    options?: HttpResourceOptions<T, string>
  ) => {
    const resource = httpResource.text(request, options);
    effect(() => {
      const error = resource.error();
      if (error)
        this.messageService.throw(error);
    });

    return resource;
  }

  httpFile = (
    request: () => HttpResourceRequestWithFileName
  ) => {
    const resource = httpResource.blob(() => request()?.url, {
      parse: blob => {
        openOrSaveFile(blob, request().fileName)
      }
    });

    effect(() => {
      const error = resource.error();
      if (error)
        this.messageService.throw(error);
    });

    return resource;
  }

  odata = (
    url: () => string | undefined,
    skipDateConversion: boolean = false
  ) => {
    const resource = httpResource(url, {
      parse: response => getOdata(response, skipDateConversion)
    });

    effect(() => {
      const error = resource.error();
      if (error)
        this.messageService.throw(error);
    });

    return resource;
  }

  odataExport = (
    request: () => HttpResourceRequestWithFileName
  ) => {
    const resource = httpResource.blob(() => request()?.url, {
      parse: blob => {
        saveFile(blob, request().fileName)
      }
    });

    effect(() => {
      const error = resource.error();
      if (error)
        this.messageService.throw(error);
    });

    return resource;
  }
}
