<?php

/**
 * Implementation of HOOK_menu()
 */
function diy_inseration_mailing_menu() {
  $items = array();

  $items['admin/config/diy/inseration-mailing'] = array(
    'title' => 'Inseration mailing settings',
    'description' => 'Set subject and mailtext for inseration-mail',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('diy_inseration_mailing_settings_form'),
    'access arguments' => array('administer diy defaults'),
    'type' => MENU_NORMAL_ITEM,
  );

  /*
  $items['testhook'] = array(
    'title' => 'Page Example',
    'page callback' => 'diy_inseration_mailing_testhook_callback',
    'access callback' => TRUE,
    'expanded' => TRUE,
  );
  */

  return $items;
}

/**
 * Callback for settings form.
 */
function diy_inseration_mailing_settings_form($form, &$form_state) {

  $form['diy_inseration_mailing_active'] = array(
    '#type' => 'checkbox',
    '#title' => t('Enable mailing.'),
    '#default_value' => variable_get('diy_inseration_mailing_active', FALSE),
  );

  $form['diy_inseration_mailing_redirect'] = array(
    '#type' => 'textfield',
    '#title' => t('Mail redirect'),
    '#default_value' => variable_get('diy_inseration_mailing_redirect', ''),
    '#description' => t('Send all mails to this address'),
    '#size' => 60,
    '#required' => FALSE,
  );

  $form['diy_inseration_mailing_subject'] = array(
    '#type' => 'textfield',
    '#title' => t('Mail subject'),
    '#default_value' => variable_get('diy_inseration_mailing_subject', ''),
    '#description' => t('Available replacement: !date'),
    '#size' => 60,
    '#required' => FALSE,
  );

  $form['diy_inseration_mailing_body'] = array(
    '#type' => 'textarea',
    '#title' => t('Mail body'),
    '#default_value' => variable_get('diy_inseration_mailing_body'),
    '#description' => t('Available replacements: !table, @username, @profilelink'),
    '#rows' => 6
  );

  return system_settings_form($form);
}

/*
function diy_inseration_mailing_testhook_callback() {
  diy_inseration_mailing_callback(array(
    'from' => 0,
    'to' => time(),
    'uid' => 1584
  ));

  return '';
}
*/

/**
 * Implements HOOK_cron();
 */
function diy_inseration_mailing_cron() {
  if(variable_get('diy_inseration_mailing_active', FALSE)) {
    $now = time();

    // once a day
    $last_run = variable_get('diy_inseration_mailing_schedule_daily', 0);
    $last_run_plus_one_day = $last_run + (24 * 60 * 60);

    if($last_run_plus_one_day < $now) {
      watchdog('diy_inseration_mailing', 'Triggered daily run.');
      diy_inseration_mailing_schedule_mails_sync($last_run, $now, 1);
      variable_set('diy_inseration_mailing_schedule_daily', $now);
    }

    // once a week
    $last_run = variable_get('diy_inseration_mailing_schedule_weekly', 0);
    $last_run_plus_one_week = $last_run + (24 * 60 * 60 * 7);

    if($last_run_plus_one_week < $now) {
      watchdog('diy_inseration_mailing', 'Triggered weekly run.');
      diy_inseration_mailing_schedule_mails_sync($last_run, $now, 2);
      variable_set('diy_inseration_mailing_schedule_weekly', $now);
    }
  }
}

/**
 * Helper function to trigger mailings
 * Called from HOOK_cron
 *
 * $fieldvalue 1 -> daily, 2 -> weekly
 */
function diy_inseration_mailing_schedule_mails_sync($last_run, $current_run, $field_value) {
  // check if inseration exists between $last_run and $current_run
  if($inserate = inserate_get_inserate_between($last_run, $current_run)) {

    // query users with settings
    if($users = diy_inseration_mailing_get_users($field_value)) {
      // Send to Queue for further processing
      $queue = DrupalQueue::get('diy_inseration_mailing_queue');

      foreach($users as $uid) {
        watchdog('diy_inseration_mailing', 'Added user '. $uid .' to queue.');

        $queue->createItem(array(
          'from' => $last_run,
          'to' => $current_run,
          'uid' => $uid
        ));
      }
    } else {
      watchdog('diy_inseration_mailing', 'No users found for type !type (1 daily, 2 weekly).', array('!type' => $field_value));
    }
  } else {
    watchdog('diy_inseration_mailing', 'No inserate found between !from and !to.', array('!from' => $last_run, '!to' => $current_run));
  }
}

/**
 * Implements HOOK_cron_queue_info().
 */
function diy_inseration_mailing_cron_queue_info(){
  $queues['diy_inseration_mailing_queue'] = array(
    'worker callback' => 'diy_inseration_mailing_callback'
  );
  return $queues;
}

/**
 * Worker callback for cron_queue_info.
 */
function diy_inseration_mailing_callback($settings) {
  // we need lat lon from our user
  $user = user_load($settings['uid']);

  watchdog('diy_inseration_mailing', 'Checking user !user', array('!user' => $settings['uid']));

  $users_branches = diy_craftsman_get_branche_tids($user->uid);
  if(!$users_branches) {
    watchdog('diy_inseration_mailing', 'User !user has no branches.', array('!user' => $settings['uid']));
    return;
  }

  if($field_geofield = field_get_items('user', $user, 'field_geofield')) {
    $user_lat = $field_geofield[0]['lat'];
    $user_lon = $field_geofield[0]['lon'];

    if(!empty($user_lat) && !empty($user_lon)) {

      // we also need max-distance
      if($anbieterprofile = profile2_load_by_user($user, 'anbieterprofil')) {
        if($field_max_entfernung = field_get_items('profile2', $anbieterprofile, 'field_max_entfernung')) {
          $max_distance = $field_max_entfernung[0]['value'];

          // now we can get list of inserations
          // maybe zero result
          if($inserate = inserate_get_inserate_between($settings['from'], $settings['to'])) {
            $inserate_for_mail = array();

            foreach($inserate as $inserat) {
              // check branche
              $field_inserat_branchen = field_get_items('node', $inserat, 'field_inserat_branchen');
              $inserat_branches = array();
              foreach($field_inserat_branchen as $field_inserat_branch) {
                $inserat_branches[] = $field_inserat_branch['tid'];
              }

              if(!array_intersect($users_branches, $inserat_branches)) {
                watchdog('diy_inseration_mailing', 'User !user has no branches for !inserat.', array('!user' => $settings['uid'], '!inserat' => $inserat->nid));
                continue;
              }

              if($field_geofield_inserat = field_get_items('node', $inserat, 'field_geofield')) {
                $inserat_lat = $field_geofield_inserat[0]['lat'];
                $inserat_lon = $field_geofield_inserat[0]['lon'];

                if(!empty($inserat_lat) && !empty($inserat_lon)) {
                  $distance = distance($user_lat, $user_lon, $inserat_lat, $inserat_lon, 'K');
                  $inserat->diy_distance = $distance;

                  watchdog('diy_inseration_mailing', 'Checking user !user with inserat !inserat (!d < !md)', array('!d' => $distance, '!md' => $max_distance, '!user' => $settings['uid'], '!inserat' => $inserat->nid));

                  if($distance <= $max_distance) {
                    $inserate_for_mail[] = $inserat;
                  }
                }
              }
            }

            if($inserate_for_mail) {
              diy_inseration_mailing_prepare_mail($user, $inserate_for_mail);
            }
          }
        }
      }
    }
  }
}

/**
 * Helper for sending out the mail with inserations
 */
function diy_inseration_mailing_prepare_mail($user, $inserate_for_mail) {
  $subject = variable_get('diy_inseration_mailing_subject', '');
  $body = variable_get('diy_inseration_mailing_body', '');

  if($subject && $body) {
    drupal_mail('diy_inseration_mailing', 'inserate_mail', $user->mail, user_preferred_language($user), array(
      'inserate' => $inserate_for_mail,
      'user' => $user,
      'subject' => $subject,
      'body' => $body
    ));
  }
}

/**
 * Implements HOOK_mail().
 */
function diy_inseration_mailing_mail($key, &$message, $params) {
  if($key == 'inserate_mail') {

    if($mail_redirect = variable_get('diy_inseration_mailing_redirect', '')) {
      $message['to'] = $mail_redirect;
    }

    $message['subject'] = format_string($params['subject'], array('!date' => format_date(time(), 'date_only')));

    $user_domains = $params['user']->domain_user;
    $user_domain = reset($user_domains);
    $user_domain = domain_load($user_domain);

    $user_base = $user_domain['path'];

    if(!$user_base) {
      global $base_url;
      $user_base = $base_url;
    }
    $user_base = rtrim($user_base,"/");

    $rows = array();
    $td_style = 'padding: 2px 8px .5em 8px;border-top: 1px solid #dfdfdf;border-left: 1px solid #e8e8e8;';
    $td_count = 1;
    foreach($params['inserate'] as $inserat) {

      if($td_count%2 == 0) {
        $td_style .= 'background-color: #f9f9f9;';
      } else {
        $td_style .= 'background-color: #f0f0f0;';
      }
      $td_count++;

      $period = '';
      $address = '';

      if($field_zeitraum = field_get_items('node', $inserat, 'field_zeitraum')) {
        $period = format_date(strtotime($field_zeitraum[0]['value']), 'date_only');

        if(isset($field_zeitraum[0]['value2'])) {
          $period .= ' - ' . format_date(strtotime($field_zeitraum[0]['value2']), 'date_only');
        }
      }

      if($field_inserat_addresse = field_get_items('node', $inserat, 'field_inserat_addresse')) {
        if($field_inserat_addresse[0]['postal_code']) {
          $address .= $field_inserat_addresse[0]['postal_code'] . ' ';
        }
        if($field_inserat_addresse[0]['locality']) {
          $address .= $field_inserat_addresse[0]['locality'];
        }
      }

      $rows[] = array(
        array(
          'data' => l($inserat->title, 'node/' . $inserat->nid, array('absolute' => true, 'attributes' => array('style' => 'color:#cfb516;'))),
          'style' => $td_style
        ),
        array(
          'data' => $address,
          'style' => $td_style
        ),
        array(
          'data' => $period,
          'style' => $td_style
        ),
        array(
          'data' => number_format($inserat->diy_distance, 0) . ' km',
          'style' => $td_style
        )
      );
    }

    $header_style = 'padding:2px 8px .5em 8px;text-align:left;border-top: 1px solid #dfdfdf;background-color:#fafafa;';
    $table = theme_table(array(
      'rows' => $rows,
      'header' => array(
        array(
          'data' => 'Inserat',
          'style' => $header_style
        ),
        array(
          'data' => 'Ort',
          'style' => $header_style
        ),
        array(
          'data' => 'Zeitraum',
          'style' => $header_style
        ),
        array(
          'data' => 'Entfernung',
          'style' => $header_style
        )
      ),
      'attributes' => array(
        'width' => '610px',
        'class' => 'data-table',
        'style' => 'background-color: #e8e8e8;border: 2px solid #e7e7e7;border-collapse: collapse;'
      ),
      'colgroups' => array(),
      'sticky' => false,
      'empty' => false,
      'caption' => null
    ));

    $message['body'][] = format_string($params['body'], array(
      '!table' => $table,
      '@username' => diy_user_get_name($params['user']),
      '@profilelink' =>  $user_base . '/user/login?destination=profile-benachrichtigungen_anfragen/'. $params['user']->uid .'/edit'
    ));

    watchdog('diy_inseration_mailing', 'Mail to: ' . $message['to'] . ' // ' . implode($message['body']));
  }
}

/**
 *
 */
function diy_inseration_mailing_get_users($key) {
  $all_users = diy_inseration_mailing_get_all_users();
  $possible_users_weekly = diy_inseration_mailing_get_all_users_weekly();

  // daily
  if($key == 1) {
    return array_diff($all_users, array_intersect($possible_users_weekly, $all_users));
  }

  // weekly
  if($key == 2) {
    return array_intersect($possible_users_weekly, $all_users);
  }

  return false;
}

/**
 * Get uids, and settings with field_benachrichtigung
 */
function diy_inseration_mailing_get_all_users() {
  // get all handwerker profiles
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'user')
    ->fieldCondition('field_anbieter', 'value', 1, '=')
    ->addMetaData('account', user_load(1));

  $result = $query->execute();
  if (isset($result['user'])) {
    $users = array_keys($result['user']);

    // users which dont want to get mail
    $no_mail = diy_inseration_mailing_get_users_non_mail();

    return array_diff($users, $no_mail);
  }

  return array();
}

/**
 * Get all users with weekly setting
 */
function diy_inseration_mailing_get_all_users_weekly() {
  return _diy_user_get_users_with_notification_setting(2);
}

/**
 * Helper function to get users which dont want to get mails
 */
function diy_inseration_mailing_get_users_non_mail() {
  return _diy_user_get_users_with_notification_setting(3);
}


function _diy_user_get_users_with_notification_setting($setting) {
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'profile2')
    ->entityCondition('bundle', 'benachrichtigungen_anfragen')
    ->fieldCondition('field_benachrichtigung', 'value', $setting, '=')
    ->addMetaData('account', user_load(1));

  $result = $query->execute();
  if (isset($result['profile2'])) {
    $uids = array();

    $profiles = array_keys($result['profile2']);
    $profiles = entity_load('profile2', $profiles);

    foreach($profiles as $profile) {
      $uids[] = $profile->uid;
    }

    return $uids;
  }

  return array();
}