import { CogniteClient as CogniteClientV6 } from '@cognite/sdk-v6';
import { CogniteClient } from '@cognite/sdk';
import type { QueryRequest, Query } from './codegen';
import type { ModelNodeMap } from './schema';
/// <reference path='./codegen.d.ts'/>
import { generateQueryOp } from './codegen.esm.js';
import { FieldsSelection } from '@genql/runtime';

const getTypeKey = (typeName: string, version: number | string) =>
  `${typeName}_${version}`;

const CDF_ALPHA_VERSION_HEADERS = { 'cdf-version': 'alpha' };

export class FDMQueryClient {
  private _client: CogniteClient | CogniteClientV6;

  constructor(client: CogniteClient | CogniteClientV6) {
    this._client = client;
  }
  public runQuery = async <R extends QueryRequest>(
    query: R & { __name?: string }
  ) => {
    const response = await this._client.post<{
      data: FieldsSelection<Query, R>;
    }>(
      `/api/v1/projects/${PROJECT}/schema/api/${DM_NAME}/${DM_VERSION}/graphql`,
      { data: generateQueryOp(query) }
    );
    return response;
  };

  public async upsertNodes<T extends keyof ModelNodeMap>(
    key: T,
    items: ModelNodeMap[T][]
  ): Promise<ModelNodeMap[T][]> {
    const data = {
      items,
      spaceExternalId: DM_NAME,
      model: [DM_NAME, getTypeKey(key, DM_VERSION)],
      overwrite: true,
    };

    const res = await this._client.post<{ items: ModelNodeMap[T][] }>(
      `/api/v1/projects/${this._client.project}/datamodelstorage/nodes`,
      {
        data,
        headers: CDF_ALPHA_VERSION_HEADERS,
        responseType: 'json',
      }
    );

    return res.data.items;
  }
}

export const FDMQueryClientBuilder = {
  fromToken: (appId = 'FDMQueryClient') => {
    return new FDMQueryClient(
      new CogniteClientV6({
        appId,
        // @ts-ignore
        getToken: () => Promise.resolve(BEARER_TOKEN),
        project: PROJECT,
        baseUrl: `https://${CLUSTER}.cognitedata.com`,
      })
    );
  },
  fromClient: (client: CogniteClient) => {
    return new FDMQueryClient(client);
  },
};

/// <reference path='./codegen.d.ts'/>
export * from './codegen';
export * from './schema';
