
// Angular Core
import { Injectable, OnDestroy, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

// Services
import { ApiService } from '../api/api.service';
import { DataTransmitterService } from '../dataTransmitter/data-transmitter.service';
import { Subscription } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class CartValidationService implements OnInit, OnDestroy{
  sitename!: string;
  sitenameListener!: Subscription;

  constructor(private http: HttpClient, public api: ApiService, private dataTransmitter: DataTransmitterService) { }

  ngOnInit(): void {
    this.dataTransmitter.sitename.subscribe((sitename) => {
      this.sitename = sitename;
    });
  }
  ngOnDestroy(): void {
    this.sitenameListener.unsubscribe();
  }

  /*
  * Model for shopping cart object
  * @type type
  */
  shoppingCart: any;

  /**
   * Inject messages validation array if not existent
   * @returns {object} Shoppingcart object initialized for validation
   */
  getValidationMsgs() {
    return [
      {
        msg:"",
        valid: true,
        key: 'firstOrdrCrdtLmtBlock',
        critical: true
      },
      {
        msg: 'Supplier requires a minimum qty for the above listed products in cart. Please add to your order to meet the minimum required as shown alert when clicked Buy Now.',
        valid: true,
        key: 'minQuantityPurchase',
        critical: false
      },
      {
        msg: '',
        valid: true,
        key: 'SupplierOrderNotice',
        critical: false
      },
      {
        msg: 'FIRST ORDER NOTICE: Please allow up to 24 business hours for Account Setup with this supplier before your order can be processed.',
        valid: true,
        key: 'firstOrder',
        critical: false
      },
      {
        msg: 'FIRST ORDER NOTICE: <strong>Wasatch requires pre-payment for your 1st order via Credit Card/ACH/Check.</strong> They\'ll contact you or call 1-801-987-8239 to make payment after placing the order. Once payment is received, your order will ship.',
        valid: true,
        key: 'wasatchFirstOrder',
        critical: false
      },
      {
        msg: 'This supplier no longer services your state. Please use the Change Suppliers tool or remove all items from this seller before proceeding to checkout.',
        valid: true,
        key: 'supplierUnavailable',
        critical: true
      },
      {
        msg: '',
        valid: true,
        key: 'supplierInfo',
        critical: false
      },
      {
        msg: 'The contents in your cart contain one or more Schedule (2) drugs and may require CSOS authentication before your order can be processed.',
        valid: true,
        key: 'schedule2Substance',
        critical: false
      },
      {
        msg: 'The cutoff time for this supplier has passed. Any order placed after this cutoff time with this supplier may not get processed until the following business day.',
        valid: true,
        key: 'cutoffTime',
        critical: false
      },
      {
        msg: 'Same Day shipping is for user\'s in the NY Metro area only. Please choose a different shipping method if you are out of area otherwise your order may be declined at the Supplier\'s consent.',
        valid: true,
        key: 'sameDayShipping',
        critical: false
      },
      {
        msg: '',
        valid: true,
        key: 'controlSubstanceFound',
        critical: false
      },
      {
        msg: 'No shipping method selected. Please select from the available shipping methods',
        valid: true,
        key: 'shippingSelected',
        critical: true
      },
      {
        msg: 'This order contains refrigerated product(s) and must ship overnight.',
        valid: true,
        key: 'refrigeratedFound',
        critical: false
      },
      {
        msg: 'There are one or more items on your order that are no longer available. Please adjust your order accordingly',
        valid: true,
        key: 'out-of-stock',
        critical: true
      },
      {
        msg: 'This order contains HAZMAT items and will force your entire order to ship Ground, You may want to order the Hazmat item separately.',
        valid: true,
        key: 'hazmatFound',
        critical: false
      },
      {
        msg: 'This order contains refrigerated product(s) and must ship 2nd day. Please choose 2nd Day shipping to proceed to checkout.',
        valid: true,
        key: 'paragonRefrigeratedFound',
        critical: false
      },
      {
        msg: 'The Quantity Available for one or more items has changed. Please review and adjust your order before proceeding to checkout.',
        valid: true,
        key: 'productShortage',
        critical: true
      },
      {
        msg: this.sitename + ' credits Qualifications: Your order contains a product eligible for '+this.sitename+' Credits, you must have at least three unique SKU’s in your order with this supplier to qualify. \n\
                    You may add to your order or proceed to checkout now and your '+this.sitename+' Credits will be removed from the order.',
        valid: true,
        key: 'trxadeCredits',
        critical: false
      },
      {
        msg: 'The price of one or more items has changed. Please review your cart carefully before proceeding to checkout.',
        valid: true,
        key: 'priceChange',
        critical: false
      },
      {
        msg: 'This item may be shipped separately subject to Ground shipping only.',
        valid: true,
        key: 'groundShippingOnly',
        critical: false
      },
      {
        msg: 'There are one or more items on your order that are expired and no longer available. Please adjust your order accordingly',
        valid: true,
        key: 'item-expired',
        critical: true
      },
      {
        msg: 'Supplier Requires Updated Information prior to placing new orders. Please go to Manage Suppliers Page, Find Supplier and Click Apply Now to complete requested Application or Payment Form. Once Account is reactivated you will be able to place your order here.',
        valid: true,
        key: 'updateRequired',
        critical: true
      },
      {
        msg:"The Supplier's GCR Ratio has not been met, please adjust your order to meet Ratio and then you can submit your order.",
        valid: true,
        key: 'gcrNotMet',
        critical: true
      },
      {
        msg: 'This product is a Controlled Substance and requires an approved controls account prior to placing an order. Please remove the item from your cart, go to Categories/Controls page and click Apply for Controls next to item sold by specific Supplier to setup your account.',
        valid: true,
        key: 'applyForControls',
        critical: true
      },
      {
        msg: 'Suppliers in your cart require an Active Account before they’ll allow you to place your 1st order. Please click the orange button below the order to either Esign or have the Required document emailed to you for completion. Once your account is setup you can come back to the cart and place your order.',
        valid: true,
        key: 'applyNow',
        critical: true
       },
       {
        msg: 'This order contains one or more items from a supplier that is currently suspended. Please remove the items from your cart or contact us for more information.',
        valid: true,
        key: 'suspendedSource',
        critical: true
       },
       {
        msg:"",
        valid: true,
        key: 'ExceededAllocation',
        critical: true
       },
       {
        msg: 'Due to multiple failed payments on recent orders, your default payment terms have been changed to <strong>Prepay by Credit Card only</strong>. You will not be able to check out with ACH or Net Terms until the outstanding failed payments are resolved.',
        valid: true,
        key: 'PrepayCreditCard',
        critical: false
       },
    ];

  };

  /**
   * Assigning cart data to shoppingCart for the first time
   * @param {type} cart
   * @return {undefined}
   */
  setShoppingCart(cart: any) {
    this.shoppingCart = cart;
  };

  /**
   * Set valid proeprty
   * @returns {undefined}
   */
  setValid(key: string = '', supplier: any = {}, valid: boolean = false) {
    // supplier.msg = [];
    supplier.msg?.forEach((msg: any) => {
      if (msg.key === key) {
        msg.valid = valid;
      }
    }, this);
  };
  /**
   * Set the msg property for controlSubstanceFound
   * @param {type} key
   * @param {type} supplier
   * @param {type} msg
   * @return {undefined}
   */
  setMsg(key: any, supplier: any, msg: any) {
    supplier.msg?.forEach((m: any) => {
      if (m.key === key) {
        m.msg = msg;
      }
    }, this);
  };
  /**
   * Validation for the whole shipping cart 
   * @return {undefined}
   */
  validateAllShipping() {
    const dataArray = Object.keys(this.shoppingCart).map(key => ({key, value: this.shoppingCart[key]}));
    dataArray.forEach((supplier: any) => {

      const methodData = Object.keys(supplier.value.shippingData.shipping_methods).map(key => ({key, value: supplier.value.shippingData.shipping_methods[key]}));
      var isSelected = false;
      methodData.forEach((method: any) => {
        if (method.value.selected) {
          isSelected = true;
        }
      })
      if (!isSelected) {
        this.setValid('shippingSelected', supplier.value, false);
      }
    }, this);
  };
  /**
   * Validation for shipping methods 
   * @return {undefined}
   */
  validateShipping(supplier: any) {
    var isSelected = false;
    for(let method in supplier.shippingData.shipping_methods){
      if (supplier.shippingData.shipping_methods[method]?.selected) {
        isSelected = true;
        if (supplier.shippingData.shipping_methods[method].name === "Same Day") {
          this.setValid('sameDayShipping', supplier, false);
        } else {
          this.setValid('sameDayShipping', supplier, true);
        }
      }
    }
    if (isSelected) {
      this.setValid('shippingSelected', supplier, true);
    }
    else {
      this.setValid('shippingSelected', supplier, false);
    }
  };

  /**
   * Reset cart notifications
   * @param {type} supplier
   */
  resetAll(supplier: any) {
    this.setValid('controlSubstanceFound', supplier, true);
    this.setValid('schedule2Substance', supplier, true);
    this.setValid('refrigeratedFound', supplier, true);
    this.setValid('out-of-stock', supplier, true);
    this.setValid('hazmatFound', supplier, true);
    this.setValid('paragonRefrigeratedFound', supplier, true);
    this.setValid('shippingSelected', supplier, true);
    this.setValid('productShortage', supplier, true);
    this.setValid('trxadeCredits', supplier, true);
    this.setValid('supplierUnavailable', supplier, true);
    this.setValid('firstOrder', supplier, true);
    this.setValid('applyForControls', supplier, true);
    this.setValid('applyNow', supplier, true);
    this.setValid('suspendedSource', supplier, true);
  };
  /**
   * Method for validation of Ndc
   * @param {type} boolean
   */
  validateNdc(item: any) {
    var ndc = item.ndc;

    if (ndc.length < 10) {
      return false;
    }
    if (ndc == 0) {
      return false;
    }
    if (ndc.match(/\d{5}-\d{4}-\d{2}/) || ndc.match(/\d{5}-\d{4}-\d{1}/)
      || ndc.match(/\d{11}/) || ndc.match(/\d{10}/)) {
      return true;
    }
    return false;
  };
  /**
   * Method for validation of trxade credits
   * @param {type} boolean
   */
  checkIfCreditsExist(supplier: any) {
    var i = 0;
    const dataArray =  Object.keys(supplier.items).map(key => ({key, value: supplier.items[key]}));
    dataArray.forEach((item: any) => {
      if (item.value.is_credited === true) {
        i++;
      }
    });
    if (i > 0) {
      return true;
    }
    else {
      return false;
    }
  };

}
