import { makeAutoObservable } from 'mobx';
import {
  TOKEN_KEY_SEPARATOR,
  TOKEN_PATH_PREFIX,
  TokenType,
  TokenTypeOption
} from './token.interface';

export class Token {
  key: string;
  value: string | number;
  type: TokenTypeOption;
  /**
   * The theme id for which this token is for
   */
  themeId?: string;
  /**
   * When a token is copied or imported from another theme it will have a
   * reference to the original theme id
   */
  referenceThemeId?: string;

  constructor(token: TokenType) {
    this.key = token.key;
    this.value = token.value;
    this.type = token.type;
    this.referenceThemeId = token?.referenceThemeId || '';
    this.themeId = token?.themeId || '';
    makeAutoObservable(this);
  }

  get objectify(): TokenType {
    return {
      key: this.key,
      value: this.value,
      type: this.type,
      themeId: this.themeId || '',
      referenceThemeId: this.referenceThemeId || ''
    };
  }

  get keyValuePair() {
    const id = `${this.key}${TOKEN_KEY_SEPARATOR}${this.type}`;
    return {
      [id]: this.value
    };
  }

  get tokenPath(): string {
    let prefix = this.type;
    if (this.type === 'token') {
      prefix = TOKEN_PATH_PREFIX;
    }
    return `${prefix}.${this.key}`;
  }

  get tokenReferencePath(): string {
    return `${this.key} (${this.value})`;
  }

  get readonlyValue(): string | number {
    if (typeof this.value === 'function') {
      return TOKEN_PATH_PREFIX;
    } else {
      if (typeof this.value === 'string' || typeof this.value === 'number') {
        return `${this.key} (${this.value})` as string;
      }
      return `${this.key} (${JSON.stringify(this.value)})` as string;
    }
  }

  get readonly(): string | number {
    if (typeof this.value === 'function') {
      return TOKEN_PATH_PREFIX;
    } else {
      return this.value as string;
    }
  }

  get stringValue(): string | number {
    if (typeof this.value === 'string' || typeof this.value === 'number') {
      return this.value;
    }
    return JSON.stringify(this.value);
  }

  setKey(key: string) {
    this.key = key;
  }

  setValue(value: string | number) {
    this.value = value;
  }

  setType(value: TokenTypeOption) {
    this.type = value;
  }
}
