import axios from 'axios';
import { HttpService } from './http.service';
import { parseImage, parsePrice } from './utils';
import { Product } from './models';

const CancelToken = axios.CancelToken;

function parseRecipePrices( prices:any ) {
  for( let name in prices ) {
    prices[name] = parsePrice( prices[name] );
  }

  return prices;
}

export class NorthforkService {
  _NFHttp: any;
  _cartInited:boolean = false;
  _cartId:string;

  constructor( config?:any ) {
    this._NFHttp = new HttpService( { ...{
      host: 'https://api.northfork.se/api',
    }, ...config||{} } );
  }

  getRecipes( params?:any ) {
    let cancel:any;

    let promise:any = this._NFHttp.get( 'discovery/recipes', {
      params: params,
      cancelToken: new CancelToken(function executor(c:any) {
        cancel = c;
      }),
    } ).then( ( res:any ) => {
      res.data = res.data.map( ( item:any ) => {
        item.image_url = parseImage( item );
        item.price = parseRecipePrices( item.price );
        return item;
      } );

      return res;
    } );

    promise.cancel = cancel;
    return promise;
  }

  getRecipe( id:any, params?:any ) {
    return this._NFHttp.get( 'discovery/recipes/' + id, {
      params: params,
    } ).then( ( res:any ) => {
      let data = res.data;
      data.price = parseRecipePrices( data.price );
      data.image_url = parseImage( data );
      return data;
    } );
  }

  getStores(  params?:any ) {
    return this._NFHttp.get( 'int/stores', {
      params: params,
    } );
  }

  getProducts( params?: any ) {
    let cancel:any;
    
    let promise:any = this._NFHttp.get( 'int/products', {
      params: params,
      cancelToken: new CancelToken(function executor(c:any) {
        cancel = c;
      }),
    } ).then( ( res:any ) => {
      res.data = res.data.map( ( item:any ) => {
        let product:Product = {
          id: item.id,
          external_id: item.external_id,
          image_url: parseImage( item ),
          name: item.meta.title,
          brand: item.meta.brand_name,
          price: parsePrice( item.price.price ),
          is_active: item.is_active,
          size: item.size.size,
          size_unit_name: item.size.unit_name,
          mid: item.mid,
        };

        return product;
      } );

      return res;
    } );

    promise.cancel = cancel;
    return promise;
  }

  getProduct( id: number, params?:any ) {
    return this._NFHttp.get( 'int/products/' + id, {
      params: params,
    } ).then( ( res:any ) => {
      let data = res.data;
      let product:Product = {
        id: data.id,
        external_id: data.external_id,
        image_url: parseImage( data ),
        name: data.meta.title,
        brand: data.meta.brand_name,
        price: parsePrice( data.price.price ),
        is_active: data.is_active,
        size: data.size.size,
        size_unit_name: data.size.unit_name,
        mid: data.mid,
      };
      return product;
    } );
  }

  getIngredients( params?:any ) {
    return this._NFHttp.get( 'int/ingredients', {
      params: params
    } );
  }

  getCampaigns( params?:any ) {
    return this._NFHttp.get( 'int/campaigns', {
      params:params
    } );
  }

  createCampaign( data:any ) {
    return this._NFHttp.post( 'int/campaigns', data, {
    } );
  }

  getSubstitutes( storeIdentifier:string, productIdentifier:string, params?:any ) {
    let api = `smart-cart/stores/${storeIdentifier}/products/${productIdentifier}/substitutes`;
    return this._NFHttp.get( api, {
      params: params,
    } ).then( ( res:any ) => {
      res.data = res.data.map( ( product:any ) => {
        product.image_url = parseImage( product );
        product.price = parsePrice( product.price );
        product.brand = product.brand !== 'na'? product.brand: null;
        product.is_active = product.in_stock === true;
        delete product.in_stock;

        return product;
      } );
      return res;
    } );
  }

  getProductCategories( params?:any ) {
    return this._NFHttp.get( 'int/product-categories', {
      params: params,
    } ).then( ( res:any ) => {
      return res;
    } );
  }

  getCart( userId:any ) {
    if( !userId ) return;
    let cancel:any;

    let promise:any = this._NFHttp.get( 'int/carts?user_id=' + userId, {
      cancelToken: new CancelToken(function executor( c:any ) {
        cancel = c;
      }),
    } ).then( ( res:any ) => {
      this._cartInited = true;
      let cart = res.data && res.data[0];
      if( cart ) {
        this._cartId = cart.id;
        delete cart.id;
        delete cart.user_id;
      }
      return cart || null;
    } );

    promise.cancel = cancel;
    return promise;
  }

  saveCart( data:any ) {
    if( !this._cartInited ) return;

    let cancel:any;
    let action: string;
    let apiPath = 'int/carts';

    if( !this._cartId ) {
      action = 'post';
    } else {
      action = 'put';
      apiPath += '/' + this._cartId;
    }

    let promise:any = this._NFHttp[action]( apiPath, data, {
      cancelToken: new CancelToken(function executor( c:any ) {
        cancel = c;
      } ),
    } ).then( ( res:any ) => {
      let cart = res.data;

      if( action === 'post' ) this._cartId = cart.id;
      delete cart.id;
      delete cart.user_id;

      return cart;
    } );

    promise.cancel = cancel;
    return promise;
  }
}
