<?php

include_once 'diy_product.features.inc';
include_once 'services/diy_product.affilinet.inc';
include_once 'services/diy_product.bot.inc';
include_once 'services/diy_product.price.inc';

/**
 * Implements hook_cron().
 */
function diy_product_cron() {
  $last_run = variable_get('diy_product_last_price_update', 0);

  // if cron did not run today
  if(date('ymd', $last_run) != date('ymd', time())) {

    // add stuff to update queue
    $queue = DrupalQueue::get('diy_product_price_check');
    $queue_items_count = $queue->numberOfItems();

    if($queue_items_count > 0) {
      $text = t('There are %items left in price check queue. Did not trigger another run.', array('%items' => $queue_items_count));
      diy_product_log($text, WATCHDOG_ERROR);
    } else {
      $ignore_updated_check = variable_get('diy_product_update_prices', false);

      // Queue is empty, add all products for price check and sync
      if($products = diy_product_get_products()) {
        foreach($products as $product) {
          $queue->createItem(array(
            'product' => $product,
            'ignore_updated_check' => $ignore_updated_check
          ));
        }
      }

      // set new run
      variable_set('diy_product_last_price_update', time());

      // reset check box for updated check (@see admin/config/diy/product)
      variable_set('diy_product_update_prices', false);
    }
  }
}

/**
 * Implements hook_entity_info().
 */
function diy_product_entity_info() {
  return array(
    'diy_product' => array(
      'label' => t('DIY External Product'),
      'entity class' => 'Entity',
      'controller class' => 'EntityAPIController',
      'base table' => 'diy_product',
      'entity keys' => array(
        'id' => 'pid',
        'label' => 'title'
      )
    ),
    'diy_product_price' => array(
      'label' => t('Product Price information'),
      'base table' => 'diy_product_price',
      'entity class' => 'Entity',
      'controller class' => 'EntityAPIController',
      'entity keys' => array(
        'id' => 'pid'
      )
    )
  );
}

/**
 * Implements hook_menu().
 */
function diy_product_menu() {
  $items = array();

  $items['admin/config/diy/product'] = array(
    'title' => 'DIY Product settings',
    'description' => 'Configuration for products',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('diy_product_settings_form'),
    'access arguments' => array('administer diy defaults'),
    'type' => MENU_NORMAL_ITEM,
    'file' => 'diy_product.admin.inc',
    'file path' => drupal_get_path('module', 'diy_product'),
  );

  $items['admin/products/price-item/change/%/%'] = array(
    'title' => 'Enable price item',
    'description' => 'Enable price item',
    'page callback' => 'diy_product_enable_price_item',
    'page arguments' => array(4, 5),
    'access callback' => 'user_access',
    'access arguments' => array('administer diy defaults'),
    'type' => MENU_CALLBACK,
  );

  $items['admin/products/price-item/delete/%'] = array(
    'title' => 'Delete price item',
    'description' => 'Delete price item',
    'page callback' => 'diy_product_delete_price_item',
    'page arguments' => array(4),
    'access callback' => 'user_access',
    'access arguments' => array('administer diy defaults'),
    'type' => MENU_CALLBACK,
  );

  return $items;
}

/**
 * Implements HOOK_theme().
 */
function diy_product_theme($existing, $type, $theme, $path) {
  return array(
    'diy_product_priceitem' => array(
      'template' => 'priceitem',
      'variables' => array(
        'data' => array()
      )
    ),
  );
}

/**
 * Implements HOOK_cron_queue_info().
 */
function diy_product_cron_queue_info(){
  $queues['diy_product_affilinet_sync'] = array(
    'worker callback' => 'diy_product_affilinet_sync_action',
    'time' => 240
  );
  $queues['diy_product_bot_sync'] = array(
    'worker callback' => 'diy_product_bot_sync_action',
    'time' => 240
  );
  $queues['diy_product_price_check'] = array(
    'worker callback' => 'diy_product_price_check_action',
    'time' => 120
  );
  return $queues;
}

/**
 * Helper function for controlling logging.
 */
function diy_product_log($msg, $severity = WATCHDOG_NOTICE) {
  if(variable_get('diy_product_sync_logging', 0)) {
    watchdog('diy_product', $msg, array(), $severity);
  }
}

/**
 * Implements HOOK_node_view().
 */
function diy_product_node_view($node, $view_mode, $langcode) {
  if ($node->type == 'shop' && $view_mode == 'full' && !user_access('edit any shop content')) {
    drupal_not_found();
  }
}

/**
 * Implementation of hook_action_info().
 */
function diy_product_action_info() {
  return array(
    'diy_product_create_product_action' => array(
      'label' => t('Create products'),
      'type' => 'diy_product',
      'configurable' => FALSE,
      'vbo_configurable' => TRUE,
      'triggers' => array('any'),
      'pass rows' => TRUE
    ),
  );
}

/**
 * Form callback admin product creation
 */
function diy_product_create_product_action_form($context, &$form_state) {
  $current_domain = domain_get_domain();

  $form = array();

  $form['#attached']['css'] = array(
    drupal_get_path('module', 'diy_product') . '/css/diy_product_adminform.css',
  );

  $form['tm'] = array(
    '#type' => 'fieldset',
    '#title' => t('Reference'),
    '#collapsible' => FALSE,
    '#collapsed' => FALSE,
  );
  $form['tm']['tool'] = array(
    '#type' => 'select',
    '#title' => t('Tool'),
    '#default_value' => '',
    '#options' => diy_product_get_select_options('ct_werkzeug'),
  );
  $form['tm']['material'] = array(
    '#type' => 'select',
    '#title' => t('Material'),
    '#default_value' => '',
    '#options' => diy_product_get_select_options('material'),
  );

  $form['node_options'] = array(
    '#type' => 'fieldset',
    '#title' => t('Node options'),
    '#collapsible' => FALSE,
    '#collapsed' => FALSE,
  );
  $form['node_options']['publish_domains'] = array(
    '#type' => 'select',
    '#title' => t('Domain'),
    '#multiple' => TRUE,
    '#default_value' => $current_domain['domain_id'],
    '#options' => domain_field_get_domain_options(),
    '#required' => TRUE
  );
  $field = field_info_field('field_tools_mu');
  $options_mu[0] = t('- None -');
  $options_mu += array_map('t', list_allowed_values($field));
  $form['node_options']['mu'] = array(
    '#type' => 'select',
    '#title' => t('Measurement unit '),
    '#options' => $options_mu,
    '#default_value' => 0
  );
  $form['node_options']['su'] = array(
    '#type' => 'textfield',
    '#title' => t('Scale unit '),
    '#description' => t('eg. 7,5')
  );

  $form['products'] = array(
    '#type' => 'fieldset',
    '#title' => t('Products'),
    '#weight' => 5,
    '#collapsible' => FALSE,
    '#collapsed' => FALSE,
  );

  $index = 0;
  foreach($form_state['selection'] as $key => $id) {

    $form['products']['productwrapper' . $index] = array(
      '#type' => 'fieldset',
      '#weight' => $index,
      '#collapsible' => FALSE,
      '#collapsed' => FALSE,
      '#attributes' => array('class' => array('diy-aff-product-select-item'))
    );

    $options = diy_product_get_product_options($id, true);
    $first = array_keys($options);
    $form['products']['productwrapper' . $index]['productprice' . $index] = array(
      '#type' => 'checkboxes',
      '#default_value' => array(reset($first)),
      '#options' => $options,
      '#title' => t('Price-Item')
    );

    $options = diy_product_get_product_options($id);
    $form['products']['productwrapper' . $index]['product' . $index] = array(
      '#type' => 'radios',
      '#default_value' => reset($first),
      '#options' => $options,
      '#title' => t('Product-Entity')
    );

    $form['products']['productwrapper' . $index]['smu_wrapper'] = array(
      '#type' => 'fieldset',
      '#collapsible' => FALSE,
      '#collapsed' => FALSE,
      '#attributes' => array('class' => array('diy-aff-product-smu-wrapper'))
    );
    $form['products']['productwrapper' . $index]['smu_wrapper']['mu' . $index] = array(
      '#type' => 'select',
      '#title' => t('MU'),
      '#options' => $options_mu,
      '#default_value' => 0
    );
    $form['products']['productwrapper' . $index]['smu_wrapper']['su' . $index] = array(
      '#type' => 'textfield',
      '#title' => t('SU'),
      '#size' => 10
    );


    $index++;
  }

  return $form;
}

/**
 * Submit function to process user input on product creation
 */
function diy_product_create_product_action_submit($form, $form_state) {
  $config = array();

  $tool = $form_state['complete form']['tm']['tool']['#value'];
  $material = $form_state['complete form']['tm']['material']['#value'];

  if($tool) {
    $config['type'] = 'tool';
    $config['reference_nid'] = $tool;
  } else if($material) {
    $config['type'] = 'material';
    $config['reference_nid'] = $material;
  }

  $config['domains'] = $form_state['complete form']['node_options']['publish_domains']['#value'];

  $mu_default = $form_state['complete form']['node_options']['mu']['#value'];
  $su_default = $form_state['complete form']['node_options']['su']['#value'];

  $products = array();
  $count = count($form_state['selection']);
  for($i = 0; $i < $count; $i++) {

    if($mu_product = $form_state['complete form']['products']['productwrapper' . $i]['smu_wrapper']['mu' . $i]['#value']) {
      $mu_set = $mu_product;
    } else {
      $mu_set = $mu_default;
    }

    if($su_product = $form_state['complete form']['products']['productwrapper' . $i]['smu_wrapper']['su' . $i]['#value']) {
      $su_set = $su_product;
    } else {
      $su_set = $su_default;
    }

    $products[$form_state['complete form']['products']['productwrapper' . $i]['product' . $i]['#default_value']] = array(
      'priceitems' => $form_state['complete form']['products']['productwrapper' . $i]['productprice' . $i]['#value'],
      'productentity' => $form_state['complete form']['products']['productwrapper' . $i]['product' . $i]['#value'],
      'mu' => $mu_set,
      'su' => $su_set
    );
  }

  $config['products'] = $products;

  return $config;
}

/**
 * Helper function for getting all materials/tools for #option
 */
function diy_product_get_select_options($node_type) {
  $nodes = node_load_multiple(array(), array('type' => $node_type));

  $options = array(0 => '---');
  foreach($nodes as $nid => $node) {
    $options[$nid] = $node->title;
  }

  return $options;
}

/**
 * Callback for adding products (admin form)
 */
function diy_product_create_product_action(&$object, $context) {
  $reference_nid = $context['reference_nid'];
  $products = $context['products'][$object->pid];

  diy_product_handle_product_creation($reference_nid, $products, $context);
}

/**
 * Returns products with same EAN for use in #options
 */
function diy_product_get_product_options($pid, $hide_title = FALSE) {

  $result = db_select('diy_product', 'd')
    ->fields('d')
    ->condition('d.pid', $pid, '=')
    ->execute();
  $row = $result->fetchAssoc();

  if(empty($row['ean'])) {
    $rows = array($row);
  } else {
    $result = db_select('diy_product', 'd')
      ->fields('d')
      ->condition('d.ean', $row['ean'], '=')
      ->condition('d.pid', $pid, '!=')
      ->execute();

    $rows = array($row);
    while($record = $result->fetchAssoc()) {
      $rows[] = $record;
    }
  }

  $options = array();
  foreach($rows as $row) {
    if($hide_title) {
      $options[$row['pid']] = '&nbsp;';
    } else {
      $this_shop = node_load($row['shop_nid']);
      $options[$row['pid']] = $row['title'] . ' / ' . $this_shop->title;
    }
  }

  return $options;
}

/**
 * Creates new drupal product entity and price items from selection
 *
 * @param $type string, material or tool
 * @param $reference_nid nid of material or tool entity
 * @param $products informations about product and product prices
 */
function diy_product_handle_product_creation($reference_nid, $products, $context) {
  $product_entity = $products['productentity'];
  $price_items = $products['priceitems'];

  $p = new DiyProduct();
  $p->mu = $products['mu'];
  $p->su = $products['su'];
  $p->domains = $context['domains'];
  if($p->handleEntity($product_entity, $reference_nid)) {
    $p->setPriceItems($price_items);
    $p->handleProductPriceItems();
  } else {
    drupal_set_message('Shop has no Domain set for ProductId ' . $product_entity, 'error');
  }
}

/**
 * Returns themed logo for given shop
 */
function diy_product_get_logo_for_shop($nid) {
  if($shop = node_load($nid)) {
    if($field_logo = field_get_items('node', $shop, 'field_logo')) {

      return theme_image_style(array(
        'style_name' => 'shop_logo',
        'path' => $field_logo[0]['uri'],
        'width' => NULL,
        'height' => NULL
      ));

    }
  }

  return '';
}

/**
 * Simple callback for loading all product nodes
 */
function diy_product_get_products() {
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'node')
    ->entityCondition('bundle', 'product')
    ->addMetaData('account', user_load(1));
  $result = $query->execute();

  if(isset($result['node'])) {
    $product_items_nids = array_keys($result['node']);
    $product_items = entity_load('node', $product_items_nids);

    return $product_items;
  }

  return false;
}

/**
 * Helper for getting shop
 */
function diy_product_get_shop_by_shopid($shop_id) {
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'node')
    ->entityCondition('bundle', 'shop')
    ->fieldCondition('field_external_id', 'value', $shop_id, '=')
    ->addMetaData('account', user_load(1));
  $result = $query->execute();

  if(isset($result['node'])) {
    $product_items_nids = array_keys($result['node']);

    return reset($product_items_nids);
  }

  return false;
}

/**
 * Implements HOOK_preprocess_views_view().
 */
function diy_product_preprocess_views_view(&$vars) {
  $view = &$vars['view'];

  if ($view->name == 'external_products') {
    drupal_add_library('system', 'ui.dialog');

    drupal_add_js(drupal_get_path('module', 'diy_product') . '/js/diy_product_views.js');
    drupal_add_css(drupal_get_path('module', 'diy_product') .'/css/diy_product_views.css');
  }
}

/**
 * Implements HOOK_preprocess_node().
 */
function diy_product_preprocess_node(&$vars) {
  if($vars['type'] == 'product') {

    if($cheapest_price_item = diy_product_get_price_items_cheapest($vars['node'])) {
      $vars['processed_retail_price'] = number_format($cheapest_price_item->price, 2, ',', '.');

      $shop = node_load($cheapest_price_item->shop_nid);

      $shop_link_attributes = array(
        'class' => 'producer-link',
        'target' => '_blank',
        'rel' => 'nofollow'
      );

      if($GLOBALS['theme'] != 'diy_amp') {
        $shop_link_attributes['onclick'] = 'Drupal.behaviors.trackOutboundLink(\'outbound-shop\', \''. $shop->title .'\',\''. $cheapest_price_item->deeplink .'\', '. $vars['nid'] .');return false;';
      }

      $vars['shop_link'] = l('&raquo; ' . t('goto shop'), $cheapest_price_item->deeplink, array(
        'absolute' => true,
        'html' => true,
        'attributes' => $shop_link_attributes
      ));

      if($field_logo = field_get_items('node', $shop, 'field_logo')) {
        $shop_logo = theme('image_style', array(
          'style_name' => 'shop_logo_small',
          'path' => $field_logo[0]['uri']
        ));

        $shop_logo_attributes = array(
          'class' => 'producer-link',
          'target' => '_blank',
          'rel' => 'nofollow'
        );

        if($GLOBALS['theme'] != 'diy_amp') {
          $shop_logo_attributes['onclick'] = 'Drupal.behaviors.trackOutboundLink(\'outbound-shop\', \''. $shop->title .'\',\''. $cheapest_price_item->deeplink .'\', '. $vars['nid'] .');return false;';
        }

        $vars['shop_logo'] = l($shop_logo, $cheapest_price_item->deeplink, array(
          'absolute' => true,
          'html' => true,
          'attributes' => $shop_logo_attributes
        ));
      }
    }

    if($field_link = field_get_items('node', $vars['node'], 'field_link')) {

      $producer_title = 'Not set';
      if($field_producer = field_get_items('node', $vars['node'], 'field_producer')) {
        $tid = $field_producer[0]['tid'];
        $term = taxonomy_term_load($tid);
        $producer_title = $term->name;
      }

      $producer_link_attributes = array(
        'class' => 'producer-link',
        'target' => '_blank',
        'rel' => 'nofollow'
      );

      if($GLOBALS['theme'] != 'diy_amp') {
        $producer_link_attributes['onclick'] = 'Drupal.behaviors.trackOutboundLink(\'outbound-prod\', \''. $producer_title .'\',\''. $field_link[0]['url'] .'\', '. $vars['nid'] .');return false;';
      }

      $vars['producer_link'] = l('&raquo; ' . t('goto producer'), $field_link[0]['url'], array(
        'absolute' => true,
        'html' => true,
        'attributes' => $producer_link_attributes
      ));
    }

    if($field_price = field_get_items('node', $vars['node'], 'field_price')) {
      $vars['processed_price_label'] = t('SRP');
      if($vars['view_mode'] == 'full') {
        $vars['processed_price_label'] = t('suggested retail price');
      }

      $vars['processed_price'] = number_format($field_price[0]['value'], 2, ',', '.');
    }

    $vars['processed_tools_mu_label'] = t('Meas. Unit');
    if($scale_unit = field_get_items('node', $vars['node'], 'field_tools_su')) {
      $vars['processed_tools_su_value'] = number_format($scale_unit[0]['value'], 2, ',', '.');
    }

    if($mesurement_unit = field_get_items('node', $vars['node'], 'field_tools_mu')) {
      $vars['processed_tools_mu_value'] = $mesurement_unit[0]['value'];
      $vars['processed_tools_mu_text'] =_diy_tools_get_mu_text($vars['processed_tools_mu_value']);
    }
  }
}