/**
 * Copyright IBM Corp. 2016, 2025
 * SPDX-License-Identifier: BUSL-1.1
 */

import ApplicationAdapter from './application';
import { service } from '@ember/service';
import { sanitizePath } from 'core/utils/sanitize-path';
import { encodePath } from 'vault/utils/path-encoding-helpers';
import { tracked } from '@glimmer/tracking';
import { getOwner } from '@ember/owner';

export default class GeneratedItemListAdapter extends ApplicationAdapter {
  @service store;
  namespace = 'v1';

  // these items are set by calling getNewAdapter in the path-help service.
  @tracked apiPath = '';
  paths = {};

  // These are the paths used for the adapter actions
  get getPath() {
    return this.paths.getPath || '';
  }
  get createPath() {
    return this.paths.createPath || '';
  }
  get deletePath() {
    return this.paths.deletePath || '';
  }

  getDynamicApiPath() {
    const result = getOwner(this)
      .lookup('route:vault.cluster.access.method')
      .modelFor('vault.cluster.access.method');
    this.apiPath = result.apiPath;
    return result.apiPath;
  }

  async fetchByQuery(store, query, isList) {
    const { id } = query;
    const payload = {};
    if (isList) {
      payload.list = true;
    }
    const path = isList ? this.getDynamicApiPath(id) : '';

    const resp = await this.ajax(this.urlForItem(id, isList, path), 'GET', { data: payload });
    const data = {
      id,
      method: id,
    };
    return { ...resp, ...data };
  }

  query(store, type, query) {
    return this.fetchByQuery(store, query, true);
  }

  queryRecord(store, type, query) {
    return this.fetchByQuery(store, query);
  }

  urlForItem(id, isList, dynamicApiPath) {
    const itemType = sanitizePath(this.getPath);
    let url;
    id = encodePath(id);
    // the apiPath changes when you switch between routes but the apiPath variable does not unless the model is reloaded
    // overwrite apiPath if dynamicApiPath exist.
    // dynamicApiPath comes from the model->adapter
    let apiPath = this.apiPath;
    if (dynamicApiPath) {
      apiPath = dynamicApiPath;
    }
    // isList indicates whether we are viewing the list page
    // of a top-level item such as userpass
    if (isList) {
      url = `${this.buildURL()}/${apiPath}${itemType}/`;
    } else {
      // build the URL for the show page of a nested item
      // such as a userpass group
      url = `${this.buildURL()}/${apiPath}${itemType}/${id}`;
    }

    return url;
  }

  urlForQueryRecord(id, modelName) {
    return this.urlForItem(id, modelName);
  }

  urlForUpdateRecord(id) {
    const itemType = this.createPath.slice(1, this.createPath.indexOf('{') - 1);
    return `${this.buildURL()}/${this.apiPath}${itemType}/${id}`;
  }

  urlForCreateRecord(modelType, snapshot) {
    const id = snapshot.record.mutableId; // computed property that returns either id or private settable _id value
    const path = this.createPath.slice(1, this.createPath.indexOf('{') - 1);
    return `${this.buildURL()}/${this.apiPath}${path}/${id}`;
  }

  urlForDeleteRecord(id) {
    const path = this.deletePath.slice(1, this.deletePath.indexOf('{') - 1);
    return `${this.buildURL()}/${this.apiPath}${path}/${id}`;
  }

  createRecord(store, type, snapshot) {
    return super.createRecord(...arguments).then((response) => {
      // if the server does not return an id and one has not been set on the model we need to set it manually from the mutableId value
      if (!response?.id && !snapshot.record.id) {
        snapshot.record.id = snapshot.record.mutableId;
        snapshot.id = snapshot.record.id;
      }
      return response;
    });
  }
}
