import { importExpr } from '@angular/compiler/src/output/output_ast';
import { ShoppingAction, ShoppingActionTypes } from '../actions/shopping.action';
import { ShoppingItem } from '../models/shopping-item';
import { Shopping } from '../models/shopping.model';


export interface ShoppingState {
  list: ShoppingItem[];
  shopping: Shopping;
  loading: boolean;
  updating: boolean;
  itens: number;
  total: number;
  error: Error;
}

const initialState: ShoppingState = {
  list: [],
  shopping: null,
  loading: false,
  updating: false,
  itens: 0,
  total: 0,
  error: undefined
};

export function ShoppingReducer(state: ShoppingState = initialState, action: ShoppingAction) {
  switch (action.type) {
    case ShoppingActionTypes.LOAD_SHOPPING_ITEMS:
      return {
        ...state,
        loading: true
      };
    case ShoppingActionTypes.LOAD_SHOPPING_ITEMS_SUCCESS:
      return {
        ...state,
        list: action.payload,
        itens: action.payload.length,
        total: action.payload
          .map(item => {
            const r = item.listPrice * item.quantity;
            return r;
          })
          .reduce((prevVal, r) => prevVal + r),
        loading: false
      };

    case ShoppingActionTypes.LOAD_SHOPPING_ITEMS_FAILURE:
      return {
        ...state,
        list: [],
        itens: 0,
        total: 0,
        error: action.payload,
        loading: false
      };
    case ShoppingActionTypes.LOAD_SHOPPING:
      return {
        ...state,
        loading: true
      };
    case ShoppingActionTypes.LOAD_SHOPPING_SUCCESS:
      return {
        ...state,
        shopping: action.payload,
        loading: false
      };
    case ShoppingActionTypes.LOAD_SHOPPING_FAILURE:
      return {
        ...state,
        list: [],
        shopping: null,
        error: action.payload,
        loading: false
      };

    case ShoppingActionTypes.ADD_ITEM:
      return {
        ...state,
        loading: true,
        updating: true,
      };
    case ShoppingActionTypes.ADD_ITEM_SUCCESS:
      let itens: ShoppingItem[] = [];
      if ( action.payload.id === null ){
        itens = [...state.list, action.payload];
      } else {
        itens = [...state.list];
        const item = state.list.find(i => i.id === action.payload.id);
        const index = state.list.indexOf(item);
        console.log('Index do item a ser alterado: ' + index);
        if (index !== -1) {
          itens[index] = action.payload;
        }
      }
      return {
        ...state,
        list: itens, // [...state.list, action.payload],
        itens: itens.length,
        total: [...state.list, action.payload]
          .map(item => {
            const r = item.listPrice * item.quantity;
            return r;
          })
          .reduce((prevVal, r) => prevVal + r),
        loading: false,
        updating: false,
      };
    case ShoppingActionTypes.ADD_ITEM_FAILURE:
      return {
        ...state,
        error: action.payload,
        loading: false,
        updating: false,
      };

    case ShoppingActionTypes.UPDATE_PRICE_ITEM:
      return {
        ...state,
        updating: true
      };
    case ShoppingActionTypes.UPDATE_PRICE_ITEM_SUCCESS:
      return {
        ...state,
        list: [...state.list.filter(item => item.id !== action.payload.id), action.payload],
        total: [...state.list.filter(item => item.id !== action.payload.id), action.payload]
          .map(item => {
            const r = item.listPrice * item.quantity;
            return r;
          })
          .reduce((prevVal, r) => prevVal + r),

        updating: false
      };
    case ShoppingActionTypes.UPDATE_PRICE_ITEM_FAILURE:
      return {
        ...state,
        error: action.payload,
        updating: false
      };

    case ShoppingActionTypes.UPDATE_SHOPPING:
      return {
        ...state,
        loading: true
      };
    case ShoppingActionTypes.UPDATE_SHOPPING_SUCCESS:
      return {
        ...state,
        shopping: action.payload,
        loading: false
      };
    case ShoppingActionTypes.UPDATE_SHOPPING_FAILURE:
      return {
        ...state,
        error: action.payload,
        loading: false
      };

    case ShoppingActionTypes.UPDATE_DELIVERY_TAX:
      return {
        ...state,
        updating: true
      };
    case ShoppingActionTypes.UPDATE_DELIVERY_TAX_SUCCESS:
      return {
        ...state,
        shopping: action.payload,
        updating: false
      };
    case ShoppingActionTypes.UPDATE_DELIVERY_TAX_FAILURE:
      return {
        ...state,
        error: action.payload,
        updating: false
      };

    case ShoppingActionTypes.UPDATE_QUANTITY_ITEM:
      return {
        ...state,
        updating: true
      };
    case ShoppingActionTypes.UPDATE_QUANTITY_ITEM_SUCCESS:
      return {
        ...state,
        list: [...state.list.map(item => item.id !== action.payload.id ? item : action.payload)],
        // filter(item => item.id !== action.payload.id), action.payload],
        total: [...state.list.filter(item => item.id !== action.payload.id), action.payload]
          .map(item => {
            const r = item.listPrice * item.quantity;
            return r;
          })
          .reduce((prevVal, r) => prevVal + r),

        updating: false
      };
    case ShoppingActionTypes.UPDATE_QUANTITY_ITEM_FAILURE:
      return {
        ...state,
        error: action.payload,
        updating: false
      };
    case ShoppingActionTypes.DELETE_ITEM:
      return {
        ...state,
        updating: true
      };
    case ShoppingActionTypes.DELETE_ITEM_SUCCESS:
      return {
        ...state,
        list: state.list.filter(item => item.id.toString() !== action.payload.data),
        itens: state.list.filter(item => item.id.toString() !== action.payload.data).length,
        total: state.list.filter(item => item.id.toString() !== action.payload.data)
          .map(item => {
            const r = item.listPrice * item.quantity;
            return r;
          })
          .reduce((prevVal, r) => prevVal + r, 0),
        updating: false
      };
    case ShoppingActionTypes.DELETE_ITEM_FAILURE:
      return {
        ...state,
        error: action.payload,
        updating: false
      };

    case ShoppingActionTypes.APPLY_DISCOUNT_ORDER:
      return {
        ...state,
        updating: true
      };
    case ShoppingActionTypes.APPLY_DISCOUNT_ORDER_SUCCESS:
      return {
        ...state,
        list: action.payload,
        itens: action.payload.length,
        total: action.payload
          .map(item => {
            const r = item.listPrice * item.quantity;
            return r;
          })
          .reduce((prevVal, r) => prevVal + r),
        updating: false
      };
    case ShoppingActionTypes.APPLY_DISCOUNT_ORDER_FAILURE:
      return {
        ...state,
        error: action.payload,
        updating: false
      };
    default:
      return state;
  }
}

/*
export function cartReducer(
  state = cart,
  action: ActionModel,
) {
  switch (action.type) {
    case ActionTypes.Add: {
      state.itens.push(action.payload);
      state.total = calculateTotal(state.itens);
      console.log(state.total);
      return state;
    }

    case ActionTypes.Remove: {
      const index = state.itens.indexOf(action.payload);
      state.itens.splice(index, 1);
      state.total = calculateTotal(state.itens);
      console.log(state.total);
      return state;
    }
    case ActionTypes.Remove: {
      state = new CartModel();
      state.total = calculateTotal(state.itens);
      console.log(state.total);
      return state;
    }
    default:
      return state;

  }

}

function calculateTotal(itens: ItemCartModel[]){
  let total = 0;
  itens.forEach(i => total += i.quantity * i.price);
  return total;
} */


