import { inject, Injectable } from '@angular/core';
import { HttpClient, HttpResponse } from '@angular/common/http';
import { map, Observable } from 'rxjs';

import { isPresent } from 'app/core/util/operators';
import { ApplicationConfigService } from 'app/core/config/application-config.service';
import { ResilientService, DateTypeEnum } from 'app/resilient/resilient-base/resilient-base.service';
import { createRequestOption } from 'app/core/request/request-util';
import { IPeriod, NewPeriod } from '../period.model';
import { IPeriodVersion } from 'app/entities/period-version/period-version.model';
import { PeriodStatus } from 'app/entities/enumerations/period-status.model';

export type EntityResponseType = HttpResponse<IPeriod>;
export type EntityArrayResponseType = HttpResponse<IPeriod[]>;

@Injectable({ providedIn: 'root' })
export class PeriodService extends ResilientService<IPeriod, NewPeriod> {
  protected http = inject(HttpClient);
  protected applicationConfigService = inject(ApplicationConfigService);

  /* ResilientService - Overriden methods */
  /* ************************************ */
  
  override canUpdate(period: IPeriod): boolean {
    // Its null!! Allow edition... strange...
    if (!period) return true;
    
    // If activityProgressKey is NOT null, than we can't edit a running ActivityDomain
    if (period.activityProgressKey) return false;
    
    // Only CREATED Period's allow edition
    if (period && period.state !== PeriodStatus.CREATED) return false;
    
    //Otherwise, allow
    return true;
  }

  override canDelete(period: IPeriod): boolean {
    if (!period) return true;
    
    // If still in CREATE, it can be deleted safely
    if (period.state === PeriodStatus.CREATED) return true;
    
    // If is ENDED, will never be deletable.
    if (period.state === PeriodStatus.ENDED) return false;
    
    // Remaining situations are more complex and require some kind of server request.
    // - If contains any PeriodVersion, it's no longer deletable.
    // - If Doesn's contains PeriodVersion, in teory it should delete everyting associated and then delete the Period
    // TODO: Invoke server to get a more functional response
    
    return false;   // TODO: Review this. For now, its better to prevent DELETE by default
  }
  
  /* ResilientService - Service Methods */
  /* ********************************** */
  private readonly resourceUrl = this.applicationConfigService.getEndpointFor('api/periods');
  override getResourceUrl(): string { return this.resourceUrl; }
  
  private readonly dateProperties: Map<string, string> = new Map([
      ["beginDate", DateTypeEnum.DATE],
      ["endDate", DateTypeEnum.DATE],
      ["creationDate", DateTypeEnum.TIMESTAMP]
  ]);
  override getDateProperties(): Map<string, string> { return this.dateProperties; }
  
  /* PeriodService - Service methods */
  /* ************************************** */
  queryVersions(periodId: number): Observable<HttpResponse<IPeriodVersion[]>> {
    return this.http.get<IPeriodVersion[]>(`${this.resourceUrl}/${periodId}/versions`, { observe: 'response' });
  }
  
  lastVersion(periodId: number): Observable<HttpResponse<IPeriodVersion>> {
    return this.http.get<IPeriodVersion>(`${this.resourceUrl}/${periodId}/lastVersion`, { observe: 'response' });
  }
  
  getVersion(periodVersionId: number): Observable<HttpResponse<IPeriodVersion>> {
    return this.http.get<IPeriodVersion>(`${this.resourceUrl}/${periodVersionId}/version`, { observe: 'response' });
  }

  queryByState(state: PeriodStatus): Observable<HttpResponse<IPeriod[]>> {
    return this.http.get<IPeriod[]>(`${this.resourceUrl}/byState/${state}`, { observe: 'response' });
  }
}
