import {
  formatMillisRemaining,
  formatAmount,
  convertData,
  remainingPercentage,
} from 'utils/helpers';
import { IAmount, UsageType } from 'typings';

// Sort here or in graphql??
const ITEM_SORT_RULES = {
  BALANCE: 1,
  SMS: 2,
  DATA: 3,
  ROAM_LIKE_HOME: 18,
  ROAMING: 22,
  VALID_TIME: 26,
  PHONE_OFFER: 28,
  EXCESS_DATA: 31,
  DISCOUNT: 40,
  TRAVEL_PACK: 43,
  CREDIT: 50,
};

export default class UsageItem {
  constructor(state: any) {
    this.title = state.title;
    this._included = state.included;
    this._remaining = state.remaining;
    this._usage = state.usage;
    this.infinite = state.infinite;
    this.isPrimary = state.isPrimary;
    this.type = UsageType[state.type];
  }

  private _included: IAmount;
  private _remaining: IAmount;
  private _usage: IAmount;

  title: string;
  infinite: boolean;
  isPrimary: boolean;
  type: any;

  get remaining() {
    if (!this._remaining) return this.infinite ? `∞ ${this.mainUnit}` : undefined;

    const { unit, amount } = this._remaining;

    if (amount < 0) {
      return '';
    }

    if (this.type === UsageType.VALID_TIME) {
      return formatMillisRemaining(amount);
    }

    if (this.infinite) {
      return `∞ ${unit}`;
    }

    return `${formatAmount(amount)} ${unit}`;
  }

  get included() {
    if (!this._included) return this.infinite ? `∞ ${this.mainUnit}` : undefined;

    const { unit, amount } = this._included;

    if (amount < 0) {
      return undefined;
    }

    if (this.type === UsageType.VALID_TIME) {
      return formatMillisRemaining(amount);
    }

    if (this.infinite) {
      return `∞ ${unit}`;
    }
    return `${formatAmount(amount)} ${unit}`;
  }

  get usage() {
    if (!this._usage) return undefined;

    return `${formatAmount(this._usage.amount)} ${this._usage.unit}`;
  }

  get used() {
    if (this._remaining && this._included) {
      const {
        amount: remainingAmount,
        unit: remainingUnit,
        usageType: remainingType,
      } = this._remaining;
      const { amount: includedAmount, unit: includedUnit } = this._included;

      if (remainingAmount < 0 || includedAmount < 0) {
        return undefined;
      }

      if (this.type === UsageType.VALID_TIME) {
        return formatMillisRemaining(remainingAmount);
      }

      let used = Math.round((includedAmount - remainingAmount) * 10) / 10;
      let unit = remainingUnit;

      if (remainingType === '2' && remainingUnit !== includedUnit) {
        const [convertedRemaining, convertedIncluded] = convertData(
          this._remaining,
          this._included,
        );

        used = Math.round((convertedIncluded.amount - convertedRemaining.amount) * 10) / 10;
        unit = convertedRemaining.unit;
      }

      if (used < 0) {
        return undefined;
      }

      return `${formatAmount(used)} ${unit}`;
    }

    return this.usage || undefined;
  }

  get displayUsage() {
    if (this._remaining && !this.infinite) {
      return this.type === UsageType.CREDIT
        ? `${this._remaining.amount > 0 ? '+ ' : ''}${this.remaining}`
        : `${this.remaining} eftir`;
    }

    return this.usage || undefined;
  }

  get mainUnit() {
    return this._remaining?.unit || this._usage?.unit;
  }

  get remainingAmount() {
    return this._remaining?.amount;
  }

  get isPrimaryData() {
    return this.type === UsageType.DATA && this.isPrimary;
  }

  get remainingPercentage() {
    return this.infinite ? 100 : remainingPercentage(this._remaining, this._included);
  }

  get order() {
    return ITEM_SORT_RULES[UsageType[this.type]] || 45;
  }
}
