<?php

/**
 * Queue worker callback
 */
function diy_product_price_check_action($data) {
  $product = $data['product'];
  $ignore_updated_check = $data['ignore_updated_check'];

  // currently we can only check for EAN
  if($field_ean_number = field_get_items('node', $product, 'field_ean_number')) {
    $ean = $field_ean_number[0]['value'];

    if($price_items = diy_product_affilinet_search_price_items($ean, $product)) {

      $external_ids = array();

      foreach($price_items as $price_item) {
        $external_ids[] = $price_item['external_id'];

        $product_price = new DiyProductPrice($product->nid);

        // DIY-405
        // handle the case that we have
        // 1) a price item "price X" for shop A with state 1 in our database
        // 2) that price items disappears in API
        // 3) and (important) a new price item "price Y" for shop A appears in API
        // what we did so for: set "price X" to 3 (disappeared from api) and add "price Y" with state 0 (to be checked)
        // NOW we want:
        // - delete "price X"
        // - set "price Y" to state 1
        // only do, when new item has price > 0
        if($price_item['price'] > 0 && diy_product_price_check_for_existing_price_item($price_item, $product)) {
          $product_price->skipConfirmationStep = TRUE;
        }

        if($ignore_updated_check) {
          $product_price->ignoreUpdatedCheck = TRUE;
        }

        $product_price->handleProductPriceItem($price_item);
      }

      // clear not handled price items
      // check for existing price items from this source for this product
      // if one item does not appear in current result set, set it to state 3
      $query = new EntityFieldQuery();
      $query->entityCondition('entity_type', 'diy_product_price')
        ->propertyCondition('product_nid', $product->nid, '=')
        ->propertyCondition('source', 'affilinet', '=')
        ->propertyCondition('status', 3, '!=');

      if(!empty($external_ids)) {
        $query->propertyCondition('external_id', $external_ids, 'NOT IN');
      }

      $query->addMetaData('account', user_load(1));
      $result = $query->execute();

      if(isset($result['diy_product_price'])) {
        $entities = entity_load('diy_product_price', array_keys($result['diy_product_price']));

        foreach($entities as $entity) {
          $ewrapper = entity_metadata_wrapper('diy_product_price', $entity);
          $ewrapper->status->set(3);
          $ewrapper->save();
        }
      }
    }
  }
}

/**
 * Checks if a other price item exists for that shop
 *
 * @param $price_item
 */
function diy_product_price_check_for_existing_price_item($price_item, $product) {

  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'diy_product_price')
    ->propertyCondition('shop_nid', $price_item['shop_nid'], '=')
    ->propertyCondition('product_nid', $product->nid, '=')
    ->propertyCondition('external_id', $price_item['external_id'], '!=')
    ->propertyCondition('source', 'affilinet', '=')
    ->propertyCondition('status', 2, '!=')
    ->addMetaData('account', user_load(1));

  $result = $query->execute();

  if(isset($result['diy_product_price'])) {
    $entities = entity_load('diy_product_price', array_keys($result['diy_product_price']));

    foreach($entities as $entity) {
      entity_delete('diy_product_price', $entity->pid);
    }

    return true;
  }

  return false;
}

/**
 * Calculates price-informations for one price item
 */
function diy_product_get_price_information($price_item) {
  $total = $price_item->price + $price_item->delivery_costs;

  return array(
    'price' => number_format($price_item->price, 2, ',', '.') . '&euro;',
    'delivery' => t('from @price€ delivery', array('@price' => number_format($price_item->delivery_costs, 2, ',', '.'))),
    'total' => t('@price€ total', array('@price' => number_format($total, 2, ',', '.')))
  );
}

/**
 * Get price items for given product node
 */
function diy_product_get_price_items($node) {
  if($node->type != 'product') {
    return false;
  }

  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'diy_product_price')
    ->propertyCondition('product_nid', $node->nid, '=')
    ->propertyCondition('status', 1, '=')
    ->addMetaData('account', user_load(1));
  $result = $query->execute();

  if(isset($result['diy_product_price'])) {
    $current_domain = domain_get_domain();

    $entities = entity_load('diy_product_price', array_keys($result['diy_product_price']));

    // check if price items belong to a shop, which is able to be displayed on current domain
    // domain access
    $checked_entities = array();
    foreach($entities as $entity) {

      if(is_numeric($entity->shop_nid) && $domains = domain_get_node_domains($entity->shop_nid)) {

        // domain_site could be true (= published to all domains)
        // or, check for individual domains via $domains...
        if($domains['domain_site'] || in_array($current_domain['domain_id'], $domains['domain_id'])) {
          $checked_entities[] = $entity;
        }
      }
    }

    return $checked_entities;
  }

  return false;
}

/**
 * Get cheapest price item for given product node
 */
function diy_product_get_price_items_cheapest($node) {
  if($price_items = diy_product_get_price_items($node)) {

    usort($price_items, function($a, $b) {
      return strcmp($a->price, $b->price);
    });

    return reset($price_items);
  }

  return false;
}

/**
 * Admin page callback for changing price item state
 */
function diy_product_enable_price_item($pid, $action) {
  $num_updated = db_update('diy_product_price')
    ->fields(array(
      'status' => $action
    ))
    ->condition('pid', $pid, '=')
    ->execute();

  drupal_set_message(t('Updated %nums product prices.', array('%nums' => $num_updated)));
  drupal_goto('admin/product-prices');
}

/**
 * Admin page callback for deleting price item
 */
function diy_product_delete_price_item($pid) {
  $num_deleted = db_delete('diy_product_price')
    ->condition('pid', $pid, '=')
    ->execute();

  drupal_set_message(t('Deleted %nums product price item.', array('%nums' => $num_deleted)));
  drupal_goto('admin/product-prices');
}