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

import dayjs from 'dayjs/esm';

import { isPresent } from 'app/core/util/operators';
import { DATE_FORMAT } from 'app/config/input.constants';
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 { IInputData, NewInputData } from '../input-data.model';
import { SecurityPermission } from 'app/security/security-permission.model';
import { AccountService } from 'app/core/auth/account.service';
import { SecurityAction } from 'app/security/security-action.model';
import { Resources } from 'app/security/resources.model';

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

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

  private accountService = inject(AccountService);

  /* ResilientService - Service Methods */
  /* ********************************** */
  private readonly resourceUrl = this.applicationConfigService.getEndpointFor('api/input-data');
  override getResourceUrl(): string { return this.resourceUrl; }
  
  private readonly dateProperties: Map<string, string> = new Map([
      ["dataDate", DateTypeEnum.DATE],
      ["changeDate", DateTypeEnum.TIMESTAMP],
      ["creationDate", DateTypeEnum.TIMESTAMP]
  ]);
  override getDateProperties(): Map<string, string> { return this.dateProperties; }

  export(periodId: number): Observable<Blob> {
    return this.http.get(`${this.resourceUrl}/export/${periodId}`, { responseType: 'blob' });
  }

  /* ResilientService - Security Overriden methods */
  /* ********************************************* */
  override canUpdate(inputData: IInputData): boolean {
    // Check if the Period is still OPEN to allow changes
    // TODO

    // Check if user permission is SecurityPermission.HIERARCHY.
    // In this case, must check if user has access to inputDataUpload.owner
    const securityPermission: SecurityPermission = this.accountService.getPermission(Resources.INPUT_DATA, SecurityAction.UPDATE);
    if (SecurityPermission.HIERARCHY === securityPermission) {
      if (this.accountService.getParentOrganization()?.id != inputData.owner?.id) {
        return false;
      }
    }

    return true;
  }

  override canDelete(inputData: IInputData): boolean {
    // Check if the Period is still OPEN to allow changes. Delete will remove data from the Period
    // TODO

    // Check if user permission is SecurityPermission.HIERARCHY.
    // In this case, must check if user has access to inputDataUpload.owner
    const securityPermission: SecurityPermission = this.accountService.getPermission(Resources.INPUT_DATA, SecurityAction.DELETE);
    if (SecurityPermission.HIERARCHY === securityPermission) {
      if (this.accountService.getParentOrganization()?.id != inputData.owner?.id) {
        return false;
      }
    }

    return true;
  }
}
