import _ from 'lodash';
import ShortUniqueId from 'short-unique-id';
import { TokenInfo } from '../chain/xec';
import { CoinConfig } from './config-swap';
interface IOrder {
  id: string;
  version: number;
  priority: number;
  fromCoinCode: string;
  fromTokenId?: string;
  amountFrom: number;
  amountTo: number;
  fromSatUnit: number;
  isFromToken: boolean;
  toCoinCode: string;
  isToToken: boolean;
  toSatUnit: number;
  amountSentToUser: number;
  amountUserDeposit: number;
  createdRate: number;
  updatedRate: number;
  addressUserReceive: string;
  adddressUserDeposit: string;
  toTokenId?: string;
  listTxIdUserDeposit?: string[];
  listTxIdUserReceive?: string[];
  status?: string;
  isSentToFund?: boolean;
  isSentToUser?: boolean;
  endedOn?: Date;
  createdOn?: Date;
  error?: string;
  coinConfig?: CoinConfig;
  coinConfigReceive?: CoinConfig;
  toTokenInfo?: TokenInfo;
  fromTokenInfo?: TokenInfo;
  note?: string;
  isInQueue?: boolean;
  pendingReason?: string;
  lastModified?: Date;
  isResolve?: boolean;
  toNetwork: string;
  fromNetwork: string;
  actualSent: number;
  actualReceived: number;
}

export class Order implements IOrder {
  id: string;
  version: number;
  priority: number;
  fromCoinCode: string;
  fromTokenId?: string;
  amountFrom: number;
  amountTo: number;
  fromSatUnit: number;
  isFromToken: boolean;
  toCoinCode: string;
  isToToken: boolean;
  toSatUnit: number;
  amountSentToUser: number;
  amountUserDeposit: number;
  createdRate: number;
  updatedRate: number;
  addressUserReceive: string;
  adddressUserDeposit: string;
  toTokenId?: string;
  listTxIdUserDeposit?: string[];
  listTxIdUserReceive?: string[];
  status?: string;
  isSentToFund?: boolean;
  isSentToUser?: boolean;
  endedOn?: Date;
  createdOn?: Date;
  error?: string;
  coinConfig?: CoinConfig;
  coinConfigReceive?: CoinConfig;
  toTokenInfo?: TokenInfo;
  fromTokenInfo?: TokenInfo;
  note?: string;
  isInQueue?: boolean;
  pendingReason?: string;
  lastModified?: Date;
  isResolve?: boolean;
  toNetwork: string;
  fromNetwork: string;
  actualSent: number;
  actualReceived: number;
  static create(opts) {
    opts = opts || {};

    const x = new Order();

    const now = new Date();
    const end = new Date(now.getTime() + 60 * 60 * 1000);
    const uid = new ShortUniqueId({ length: 8 });
    x.version = 2;
    x.priority = opts.priority;
    x.createdOn = now;
    x.id = uid().toUpperCase();
    x.fromCoinCode = opts.fromCoinCode;
    x.amountFrom = opts.amountFrom;
    x.amountTo = opts.amountTo;
    x.fromSatUnit = opts.fromSatUnit;
    x.toSatUnit = opts.toSatUnit;
    x.isFromToken = opts.isFromToken;
    x.toCoinCode = opts.toCoinCode;
    x.amountSentToUser = opts.amountSentToUser;
    x.amountUserDeposit = 0;
    x.isToToken = opts.isToToken;
    x.addressUserReceive = opts.addressUserReceive;
    x.adddressUserDeposit = null;
    x.createdRate = opts.createdRate;
    x.status = 'waiting';
    x.toTokenId = opts.toTokenId || null;
    x.fromTokenId = opts.fromTokenId || null;
    x.listTxIdUserDeposit = [];
    x.listTxIdUserReceive = [];
    x.isSentToFund = false;
    x.isSentToUser = false;
    x.endedOn = end;
    x.error = null;
    x.coinConfig = null;
    x.coinConfigReceive = null;
    x.toTokenInfo = opts.toTokenInfo || null;
    x.fromTokenInfo = opts.fromTokenInfo || null;
    x.note = '';
    x.isInQueue = false;
    x.pendingReason = opts.pendingReason || null;
    x.lastModified = now;
    x.isResolve = false;
    x.toNetwork = opts.toNetwork;
    x.fromNetwork = opts.fromNetwork;
    x.actualReceived = 0;
    x.actualSent = 0;
    return x;
  }

  static fromObj(obj) {
    const x = new Order();

    x.version = obj.version;
    x.createdOn = obj.createdOn;
    x.id = obj.id;
    x.priority = obj.priority;
    x.fromCoinCode = obj.fromCoinCode;
    x.isFromToken = obj.isFromToken;
    x.toCoinCode = obj.toCoinCode;
    x.isToToken = obj.isToToken;
    x.addressUserReceive = obj.addressUserReceive;
    x.adddressUserDeposit = obj.adddressUserDeposit;
    x.amountUserDeposit = obj.amountUserDeposit;
    x.status = obj.status;
    x.isSentToFund = obj.isSentToFund;
    x.isSentToUser = obj.isSentToUser;
    x.createdRate = obj.createdRate;
    x.toTokenId = obj.toTokenId;
    x.fromTokenId = obj.fromTokenId;
    x.listTxIdUserDeposit = obj.listTxIdUserDeposit || [];
    x.listTxIdUserReceive = obj.listTxIdUserReceive || [];
    x.error = obj.error;
    x.amountFrom = obj.amountFrom;
    x.amountTo = obj.amountTo;
    x.fromSatUnit = obj.fromSatUnit;
    x.toSatUnit = obj.toSatUnit;
    x.coinConfig = obj.coinConfig;
    x.coinConfigReceive = obj.coinConfigReceive;
    x.toTokenInfo = obj.toTokenInfo;
    x.fromTokenInfo = obj.fromTokenInfo;
    x.updatedRate = obj.updatedRate;
    x.endedOn = obj.endedOn;
    x.note = obj.note;
    x.isInQueue = obj.isInQueue;
    x.pendingReason = obj.pendingReason;
    x.lastModified = obj.lastModified;
    x.isResolve = obj.isResolve;
    x.toNetwork = obj.toNetwork;
    x.fromNetwork = obj.fromNetwork;
    x.actualSent = obj.actualSent;
    x.actualReceived = obj.actualReceived;
    return x;
  }
}
