import {Injectable} from '@angular/core';
import {BehaviorSubject} from 'rxjs';

import ontology from '../data/rural_attractiveness.owl.json';

@Injectable({providedIn: 'root'})
export class AdjusterPresetsService {
  activeProblem: Problem;
  activeRole: Role;
  activeSchema: Schema;

  schemaChanges: BehaviorSubject<Schema>;

  roles: Role[] = [];
  schemas: Schema[] = [];

  constructor() {
    this.loadRoles();
    this.loadSchemas();
  }

  changeSchema(schema: Schema) {
    console.log(schema);
    this.schemaChanges.next(schema);
  }

  getActiveRoleProblems(): Array<Problem> {
    return this.activeRole.problems ?? [];
  }

  getActiveSchemaGroups(): Array<DatasetGroup> {
    return this.activeSchema.groups ?? [];
  }

  //TODO:  Where to store factor's (group's) weight??
  getGroupDatasets(groupID: string): Array<any> {
    return ontology
      .find((subject) => subject['@id'] == groupID)["http://www.semanticweb.org/attractiveness/hasDataset"]
      ?.map((entity) => {
        const datasetEntity = ontology.find((subject) => subject['@id'] == entity['@id']);
        return {
          id: datasetEntity["@id"],
          name: datasetEntity["http://www.w3.org/2000/01/rdf-schema#label"][0]["@value"], //TODO: i18n this!
          desc: '',
          included: true
        }
      }) ?? [];
  }

  loadRoles() {
    this.roles = ontology
      .filter((subject) => subject['@type']?.includes("http://www.semanticweb.org/attractiveness/Role"))
      .map((subject) => {
        return {
          id: subject['@id'],
          labels: subject["http://www.w3.org/2000/01/rdf-schema#label"],
          problems: subject["http://www.semanticweb.org/attractiveness/solvesProblem"].map(
            (problem) => {
              const problemEntity = ontology.find((subject) => subject['@id'] == problem['@id']);
              return {
                id: problem['@id'],
                labels: problemEntity?.["http://www.w3.org/2000/01/rdf-schema#label"],
                requiredDatasets: problemEntity?.["http://www.semanticweb.org/attractiveness/requiresDataset"].map((dataset) => dataset['@id'])
              }
            }
          )
        }
      });
    this.activeRole = this.roles[0];
    this.activeProblem = this.roles[0].problems[0];
    console.log("Roles", this.roles);
  }

  loadSchemas() {
    this.schemas = ontology
      .filter((subject) => subject['@type']?.includes("http://www.semanticweb.org/attractiveness/ClassificationSchema"))
      .map((subject) => {
        return {
          id: subject['@id'],
          labels: subject["http://www.w3.org/2000/01/rdf-schema#label"],
          groups: subject["http://www.semanticweb.org/attractiveness/consistsOf"].map(
            (group) => {
              return {
                id: group['@id'],
                labels: ontology.find((subject) => subject['@id'] == group['@id'])?.["http://www.w3.org/2000/01/rdf-schema#label"]
              }
            }
          )
        }
      });
    this.activeSchema = this.schemas[0];
    if (this.schemaChanges === undefined) {
      this.schemaChanges = new BehaviorSubject(this.activeSchema);
    } else {
      this.schemaChanges.next(this.activeSchema);
    }
    console.log("Schemas", this.schemas);
  }

  pickProblem(role) {
    this.activeProblem = role.problems[0] ?? null;
  }
}

export type DatasetGroup = {
  id: string;
  labels?: Label[];
};

export type Label = {
  "@value": string
  "@language"?: string,
};

export type Problem = {
  id: string;
  labels?: Label[];
  requiredDatasets: string[]
};

export type Role = {
  id: string;
  labels?: Label[];
  problems?: Problem[];
};

export type Schema = {
  id: string,
  labels?: Label[];
  groups?: DatasetGroup[];
};

