import { Injectable, Logger } from '@nestjs/common';
import { CouchDb } from '@app/event-emitter/couchdb-datasources/couchdb';
import nano from 'nano';
import axios from 'axios';

const DB_NAME = 'eccm_daily_reports_v2';
const DATETIME_INDEX_ASC = 'datetime-json-index';

type Report = any; // TODO fix this type

@Injectable()
export class DailyEccmReportsV2Datasource {
  private static logger = new Logger(DailyEccmReportsV2Datasource.name);
  private static db = null;
  private static initilized = false;

  static async getDatasource(): Promise<nano.DocumentScope<Report>> {
    if (DailyEccmReportsV2Datasource.initilized) {
      return DailyEccmReportsV2Datasource.db;
    }
    DailyEccmReportsV2Datasource.initilized = true;
    const n = CouchDb.getCouchDb();
    const dbName = DB_NAME;
    const dbs = await n.db.list();
    if (!dbs.includes(dbName)) {
      await n.db.create(dbName);
    }
    DailyEccmReportsV2Datasource.db = await n.db.use(dbName);
    await this.checkAndCreateIndex();
    DailyEccmReportsV2Datasource.logger.log(
      `Connected to daily reports db - ${dbName}`,
    );
    return DailyEccmReportsV2Datasource.db;
  }

  static async checkAndCreateIndex(): Promise<void> {
    const couchDbUrl = CouchDb.getCouchDbUrl();
    const indexes = await DailyEccmReportsV2Datasource.getIndexes(couchDbUrl);
    const index = indexes.find(
      (index: any) => index.name === DATETIME_INDEX_ASC,
    );
    if (!index) {
      await DailyEccmReportsV2Datasource.createIndex(couchDbUrl);
    }
  }

  private static async getIndexes(couchDbUrl: string): Promise<any[]> {
    const response = await axios.get(
      `${couchDbUrl}/${DB_NAME}/_index?skip=0&limit=999999`,
      {
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
        },
      },
    );
    this.logger.debug(`Indexes: ${JSON.stringify(response.data.indexes)}`);
    return response.data.indexes;
  }

  private static async createIndex(couchDbUrl: string): Promise<boolean> {
    this.logger.debug(`Creating index ${DATETIME_INDEX_ASC}`);
    const body = {
      index: { fields: [{ datetime: 'asc' }] },
      name: DATETIME_INDEX_ASC,
      type: 'json',
    };
    const response = await axios.post(`${couchDbUrl}/${DB_NAME}/_index`, body, {
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
    });
    this.logger.debug(
      `Index ${DATETIME_INDEX_ASC} created ` +
        `with response: ${JSON.stringify(response.data)}`,
    );
    return true;
  }
}
