import {Injectable} from "@angular/core";
import {MenuItem} from "../../sharedComponents/menu";
import {Option} from "../../sharedComponents/input/input.component";
import {from, Subscription} from "rxjs";
import {HttpClient} from "@angular/common/http";
import {properties} from "../../../../environments/environment";
import {Page} from "../../utils/entities/adminTool/page";
import {map} from "rxjs/operators";
import {StakeholderConfiguration} from "../../monitor-admin/utils/indicator-utils";

@Injectable({
  providedIn: 'root'
})
export class ResourcesService {
  
  private subscription: Subscription;
  private routes = ResourcesService.types.map(type => '/indicators/' + type.value);
  
  public static readonly types: Option[] = StakeholderConfiguration.TYPES;
  
  constructor(private http: HttpClient) {
  }
  
  private async getResourcesItemsAsync(prefix = '', portal: string = null, target = '_self'): Promise<MenuItem[]> {
    let items = [
      new MenuItem("methodology", "Methodology", "", "", false, [],
      null, {}, null, null, null, null, '_self'),
      ResourcesService.setLink(new MenuItem("methodological-approach", "Methodological Approach",
        "", "", false, [], null, {}, null, null, null, null, target),
        prefix + "/methodology/methodological-approach", portal),
    ResourcesService.setLink(new MenuItem("terminology", "Terminology and construction",
        "", "", false, [], null, {}, null, null, null, null, target),
        prefix + "/methodology/terminology", portal)];
    items.push(new MenuItem("indicators-page", "Indicators",
      "", "", false, [], null, {}));
    items.push(ResourcesService.setLink(new MenuItem("indicator-themes", "Indicator Themes",
      "", "", false, [], null, {}, null, null, null, null, target), prefix + "/indicators/themes", portal));
    let promise = new Promise<void>(resolve => {
      this.isPagesEnabled().subscribe(status => {
        ResourcesService.types.forEach((type, index) => {
          if (status[index]) {
            items.push(ResourcesService.setLink(
              new MenuItem("indicators-" + type.value, type.label,
                "", "", false, [], null, {}, null, null, null, null, target),
              prefix + "/indicators/" + type.value, portal)
            );
          }
        });
        resolve();
      }, error => {
        console.error(error);
        resolve();
      });
    })
    await promise;
    return items;
  }
  
  setResources(items: MenuItem[], prefix = '', portal: string = null, target = '_self') {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
    let resources = new MenuItem('resources', 'Resources', "", "", false, [], null, {});
    let index = items.push(resources) - 1;
    this.subscription = from(this.getResourcesItemsAsync(prefix, portal, target)).subscribe(resourcesItems => {
      items[index].items = resourcesItems;
    });
  }
  
  public isPagesEnabled() {
    let url = properties.adminToolsAPIURL + "/monitor/monitor/pages";
    return this.http.get<Page[]>((properties.useLongCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
      .pipe(map(pages => {
        let result = this.routes.map(() => false);
        pages.forEach(page => {
          let index = this.routes.findIndex(route => route === page.route && page.isEnabled);
          if (index !== -1) {
            result[index] = true;
          }
        });
        return result;
      }));
  }
  
  private static setLink(item: MenuItem, route: string, portal: string = null) {
    if (portal) {
      item.url = portal + route + (item.fragment ? '#' + item.fragment : '');
    } else {
      item.route = route;
    }
    return item;
  }
}
