<?php

/**
 * @title Schedule Emails
 * @desc send emails by schedule
 * @setup_url default/admin-content/p/scheduleemails
 */
class Bootstrap_ScheduleEmails extends Am_Module
{
    const NAME = 'schedule-email';

    function onInitAccessTables(Am_Event $e)
    {
        $e->getRegistry()->registerAccessTable($this->getDi()->scheduleEmailTable);
    }

    function onSetupEmailTemplateTypes(Am_Event $e)
    {
        $e->addReturn([
            'id' => self::NAME,
            'title' => ___('Schedule Email'),
            'mailPeriodic' => $this->getDi()->config->get('email_queue_enabled') ? Am_Mail::BACKGROUND : Am_Mail::REGULAR,
            'vars' => ['user'],
        ], self::NAME);
    }

    function onHourly(Am_Event $e)
    {
        $this->sendAccess();
        $this->sendSearch();
    }

    public function sendSearch()
    {
        $tmpls = $this->getDi()->emailTemplateTable->selectObjects("SELECT * FROM ?_email_template WHERE name = ? AND schedule_type=?",
            self::NAME, 'search');
        foreach ($tmpls as $tmpl) {
            if (!$this->matchSchedule($tmpl->schedule)) continue;

            try {
                $q = new Am_Query_User;
                $q->load($tmpl->saved_search_id);
            } catch (Exception $e) {
                continue;
            }
            $q->addWhere('u.unsubscribed=?', 0);
            $q->clearFields();
            $q->addField('u.user_id');
            $r = $q->query();
            while ($res = $this->getDi()->db->fetchRow($r))
            {
                $user = $this->getDi()->userTable->load($res['user_id']);
                $this->_send($user, $tmpl);
            }
        }
    }

    function sendAccess()
    {
        $userTable = $this->getDi()->userTable;
        $etCache = [];
        $resource_ids = [];
        foreach ($this->getDi()->db->select("SELECT email_template_id, schedule FROM ?_email_template WHERE name = ? AND schedule_type=?",
            self::NAME, 'access') as $row)
        {
            if ($this->matchSchedule($row['schedule']))
                $resource_ids[] = $row['email_template_id'];
        }
        if (!count($resource_ids)) return;

        $q = $this->getDi()->resourceAccessTable
            ->getResourcesForMembers(ResourceAccess::EMAILTEMPLATE,
            "resource_id IN (" . implode(', ', $resource_ids) . ")")
            ->query();
        while ($res = $this->getDi()->db->fetchRow($q))
        {
            if (!$res['user_id']) continue;
            if (!($user = $userTable->load($res['user_id'], false))) continue;
            if ($user->unsubscribed) continue;

            if (!array_key_exists($res['resource_id'], $etCache)) {
                if (!$etCache[$res['resource_id']] = $this->getDi()->scheduleEmailTable->load($res['resource_id'], false)) {
                    continue; // no template found
                }
            }

            $tmpl = $etCache[$res['resource_id']];

            if (!$this->matchNewsletter($user, $tmpl)) continue;
            if (!$tmpl->checkNotConditions($user)) continue;

            $this->_send($user, $tmpl);
        }
    }

    function matchSchedule($schedule = false)
    {
        if (!$schedule)
            return false;

        foreach (explode(PHP_EOL, $schedule) as $line)
        {
            [$date, $hour] = explode(' ', $line);
            if ($this->getDi()->dateTime->format("m/d/y") != $date)
                continue;

            if (intval($this->getDi()->dateTime->format("G")) == intval($hour))
                return true;
        }

        return false;
    }

    function matchNewsletter(User $user, EmailTemplate $tmpl)
    {
        //check newsletters
        if ($this->getDi()->modules->isEnabled('newsletter')) {
            if (($n = $tmpl->schedule_newsletters) && ($nids = array_filter(@explode(',', $n))))
            {
                if (!array_intersect($nids, $this->getDi()->newsletterUserSubscriptionTable->getSubscribedIds($user->pk()))) {
                    return false;
                }
            }
        }
        return true;
    }

    function _send(User $user, EmailTemplate $tmpl)
    {
        $rcpt = [];
        if ($tmpl->recipient_user)
        {
            $rcpt[] = $user;
        }

        if ($tmpl->recipient_aff && $user->aff_id && ($aff = $this->getDi()->userTable->load($user->aff_id, false)))
        {
            $rcpt[] = $aff;
        }
        if ($tmpl->recipient_subusers_parent && $user->subusers_parent_id && ($parent = $this->getDi()->userTable->load($user->subusers_parent_id, false)))
        {
            $rcpt[] = $parent;
        }
        if ($tmpl->recipient_admin)
        {
            $rcpt[] = Am_Mail_Template::TO_ADMIN;
        }
        if ($tmpl->recipient_emails)
        {
            foreach (array_map('trim', explode(',', $tmpl->recipient_emails)) as $email) {
                if ($email) {
                    $rcpt[] = $email;
                }
            }
        }
        $tpl = Am_Mail_Template::createFromEmailTemplate($tmpl);
        $tpl->setUser($user);
        foreach ($rcpt as $recipient)
        {
            try {
                $tpl->send($recipient);
            } catch (Exception $e) {
                $this->getDi()->errorLogTable->logException($e);
            }
        }
    }
}