import axios from 'axios';
import { loggerPlugin } from '@/plugins/logger';
import { KV_API } from '@/config/env';
import fetchAdapter from '@vespaiach/axios-fetch-adapter';

class KvApiAdapter {
  constructor(url, db = 1) {
    this.baseURL = url;
    this.db = db;

    this.kvApi = axios.create({
      baseURL: `${url}/api/kv`,
      adapter: fetchAdapter,
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
      },
    });
  }

  /**
   * @param {string} key
   * @param {any} value
   * @param {number} ttl
   * @param {string} crypt
   * @returns
   */
  async set(key, value, ttl = 0, crypt = '') {
    try {
      const body = {
        key,
        value,
      };

      if (ttl && ttl > 0) {
        body.ttl = ttl;
      }

      if (crypt && crypt !== '') {
        body.crypt = crypt;
      }

      /** @type {KvResponse} */
      const response = await this.kvApi.post('/set', body);
      const result = response.data;

      return result.success ? result.data : null;
    } catch (error) {
      loggerPlugin.error({
        msg: 'KV_ADAPTER_SET_ERROR',
        key,
        value,
        ttl,
        crypt,
        error,
      });
      return null;
    }
  }

  /**
   * @param {string} key
   * @param {string} [crypt]
   * @returns
   */
  async get(key, crypt = '') {
    try {
      const qs = {
        key,
      };

      if (crypt) {
        qs.crypt = crypt;
      }

      /** @type {KvResponse} */
      const response = await this.kvApi.get('/get', { params: qs });
      const result = response.data;

      return result.success ? result.data : null;
    } catch (error) {
      loggerPlugin.error({
        msg: 'KV_ADAPTER_GET_ERROR',
        key,
        crypt,
        error,
      });
      return null;
    }
  }

  /**
   * @param {string} key
   * @returns
   */
  async del(key) {
    try {
      /** @type {KvResponse} */
      const response = await this.kvApi.post('/delete', {}, {
        params: {
          key,
        },
      });
      const result = response.data;

      return result.success;
    } catch (error) {
      loggerPlugin.error({
        msg: 'KV_ADAPTER_DELETE_ERROR',
        key,
        error,
      });
      return null;
    }
  }

  /**
   * @param {string} key
   * @returns
   */
  async exists(key) {
    try {
      /** @type {KvResponse} */
      const response = await this.kvApi.get('/exists', {
        params: {
          key,
        },
      });
      const result = response.data;

      return result.success ? result.data : null;
    } catch (error) {
      loggerPlugin.error({
        msg: 'KV_ADAPTER_EXISTS_ERROR',
        key,
        error,
      });
      return null;
    }
  }

  /**
   * @param {string} key
   * @returns
   */
  async info(key) {
    try {
      /** @type {KvResponse} */
      const response = await this.kvApi.get('/info', {
        params: {
          key,
        },
      });
      const result = response.data;

      return result.success ? result.data : null;
    } catch (error) {
      loggerPlugin.error({
        msg: 'KV_ADAPTER_INFO_ERROR',
        key,
        error,
      });
      return null;
    }
  }

  /**
   * @param {string} key
   * @param {number} ttl
   * @returns
   */
  async setTtl(key, ttl) {
    try {
      /** @type {KvResponse} */
      const response = await this.kvApi.post('/ttl', {
        key,
        ttl,
      });
      const result = response.data;

      return result.success;
    } catch (error) {
      loggerPlugin.error({
        msg: 'KV_ADAPTER_TTL_ERROR',
        key,
        error,
      });
      return null;
    }
  }

  /**
   * @param {string} key
   * @param {number} [ttl]
   * @returns
   */
  async lock(key, ttl = 60) {
    try {
      /** @type {KvResponse} */
      const response = await this.kvApi.post('/lock', {
        key,
        ttl,
      });
      const result = response.data;

      return result.success;
    } catch (error) {
      loggerPlugin.error({
        msg: 'KV_ADAPTER_INFO_ERROR',
        key,
        error,
      });
      return null;
    }
  }

  /**
   * @param {string} key
   * @returns
   */
  async unlock(key) {
    try {
      /** @type {KvResponse} */
      const response = await this.kvApi.post('/unlock', {}, {
        params: {
          key,
        },
      });
      const result = response.data;

      return result.success;
    } catch (error) {
      loggerPlugin.error({
        msg: 'KV_ADAPTER_UNLOCK_ERROR',
        key,
        error,
      });
      return null;
    }
  }

  /**
   * @param {string} key
   * @returns
   */
  async getLockState(key) {
    try {
      /** @type {KvResponse} */
      const response = await this.kvApi.get('/state', {
        params: {
          key,
        },
      });
      const result = response.data;

      return result.data;
    } catch (error) {
      loggerPlugin.error({
        msg: 'KV_ADAPTER_STATE_ERROR',
        key,
        error,
      });
      return null;
    }
  }
}

export const KvAdapter = new KvApiAdapter(KV_API);
