<?php

/**
 * Allow affiliate to see there leads in member area
 * @am_plugin_api 6.0
 */
class Am_Plugin_AffLeads extends Am_Plugin
{
    const PLUGIN_STATUS = self::STATUS_BETA;
    const PLUGIN_COMM = self::COMM_COMMERCIAL;
    const PLUGIN_REVISION = '6.3.43';

    protected $_configPrefix = 'misc.';

    static function getDbXml()
    {
        return <<<CUT
<schema version="4.0.0">
    <table name="user">
        <field name="aff_leads_tiers2" type="tinyint" />
    </table>
</schema>
CUT;
    }

    public function useTiers()
    {
        return (defined('AM_AFFLEADS_TIERS') && AM_AFFLEADS_TIERS);
    }

    public function useTiersAll()
    {
        return (defined('AM_AFFLEADS_TIERS_ALL') && AM_AFFLEADS_TIERS_ALL);
    }

    function _initSetupForm(Am_Form_Setup $form)
    {
        $form->addAdvCheckbox('allow_export')
            ->setLabel(___('Allow to export Leads'));
        $form->addAdvCheckbox('allow_filter')
            ->setLabel(___('Allow to filter Leads'));
        $form->addSortableMagicSelect('fields')
            ->setLabel(___('Show these fields'))
            ->loadOptions($this->getUserFields())
            ->setJsOptions(<<<CUT
{
    sortable: true,
    onChange: function(val){jQuery("[data-name$='products[]']").closest('.am-row').toggle(val.hasOwnProperty("__subscriptions"));}
}
CUT
);
        $form->setDefault('fields', $this->getDefaultFields());

        $form->addMagicSelect('products', ['class' => 'am-combobox-fixed'])
            ->setlabel("Show Products\nkeep empty to display all")
            ->loadOptions($this->getDi()->productTable->getProductOptions());
    }

    function getDefaultFields()
    {
        return ['name', 'email', 'added'];
    }

    function onUserMenu(Am_Event $e)
    {
        $menu = $e->getMenu();
        $page = $menu->findById('aff');
        if ($page) {
            $page->addPage([
                'id' => 'aff-leads',
                'controller' => 'aff-leads',
                'label' => ___('Your Leads'),
                'order' => 60
            ]);
        }
    }

    public function onGridUserInitForm(Am_Event_Grid $event)
    {
        if (!$this->getDi()->authAdmin->getUser()->hasPermission('aff')) return;

        if (!$this->useTiers() || $this->useTiersAll()) return;

        $form = $event->getGrid()->getForm();
        $form->addAdvCheckbox('aff_leads_tiers2')->setLabel('Can see Tier2 Leads');
    }

    function getUserFields()
    {
        $fields = [
            'name' => ___('Name'),
            'name_f' => ___('First Name'),
            'name_l' => ___('Last Name'),
            'email' => ___('E-Mail'),
            'street' => ___('Street'),
            'city' => ___('City'),
            'state' => ___('State'),
            'full_state' => ___('State Title'),
            'country' => ___('Country'),
            'full_country' => ___('Country Title'),
            'zip' => ___('Postal Index'),
            'phone' => ___('Phone'),
            'login' => ___('Username'),
            'added' => ___('Added'),
            'status' => ___('Status'),
        ];

        if ($this->useTiers() || $this->useTiersAll())
            $fields['tier'] = ___('Tier');

        foreach ($this->getDi()->userTable->customFields()->getAll() as $field) {
            if (isset($field->from_config) && $field->from_config) {
                if ($field->sql) {
                    $fields[$field->name] = $field->title;
                } else {
                    $fields['__data_' . $field->name] = $field->title;
                }
            }
        }

        $fields['__subscriptions'] = ___('Active Subscriptions');
        $fields['__total_spend'] = ___('Total Spend');

        return $fields;
    }
}

class AffLeadsController extends Am_Mvc_Controller_Grid
{
    protected $layout = 'member/layout.phtml';

    public function preDispatch()
    {
        $this->getDi()->auth->requireLogin($this->getDi()->url('aff-leads', false));
        if (!$this->getDi()->user->is_affiliate)
            $this->redirect('member');
        parent::preDispatch();
    }

    public function createGrid()
    {
        $ds = new Am_Query($this->getDi()->userTable);
        $ds->leftJoin('?_country', 'c', 't.country = c.country');
        $ds->leftJoin('?_state', 's', 't.country = s.country AND t.state=s.state');
        $ds->addField('CONCAT(t.name_f, " ", t.name_l)', 'name');
        $ds->addField('c.title', 'full_country');
        $ds->addField('s.title', 'full_state');

        if (in_array('__subscriptions', $this->getPlugin()->getConfig('fields', []))) {
            if ($_ = $this->getPlugin()->getConfig('products')) {
                $cond = $this->getDi()->db->escapeWithPlaceholders(
                    't.user_id=a.user_id AND a.begin_date <= ? AND a.expire_date >= ? AND a.product_id IN (?a)',
                    sqlDate('now'),
                    sqlDate('now'),
                    $this->getDi()->productTable->extractProductIds($_) ?: [-1]
                );
                $ds->leftJoin('?_access', 'a', $cond);
            } else {
                $cond = $this->getDi()->db->escapeWithPlaceholders(
                    't.user_id=a.user_id AND a.begin_date <= ? AND a.expire_date >= ?', sqlDate('now'), sqlDate('now')
                );
                $ds->leftJoin('?_access', 'a', $cond);
            }
            $ds->leftJoin('?_product', 'p', 'a.product_id=p.product_id');
            $ds->addField("GROUP_CONCAT(DISTINCT p.title SEPARATOR ', ')", '__subscriptions');
        }

        if (in_array('__total_spend', $this->getPlugin()->getConfig('fields', []))) {
            $ds->addField("(SELECT ROUND(SUM(amount/base_currency_multi),2) FROM ?_invoice_payment WHERE user_id=t.user_id)", '__total_spend');
        }

        $ds2 = clone $ds;

        $ds->addField('(1)', 'tier');
        $ds->addWhere('t.aff_id=?', $this->getDi()->auth->getUserId());

        if (($this->getDi()->user->aff_leads_tiers2 && $this->getDi()->plugins_misc->loadGet('aff-leads')->useTiers())
            || $this->getDi()->plugins_misc->loadGet('aff-leads')->useTiersAll())
        {
            $ds2->addField('(2)', 'tier');
            $ds2->leftJoin('?_user', 'aff2', 'aff2.user_id=t.aff_id');
            $ds2->addWhere('aff2.aff_id=?', $this->getDi()->auth->getUserId());

            $ds->addUnion($ds2);
        }

        $ds = $ds->setOrderRaw('added DESC');

        $grid = new Am_Grid_Editable('_al', ___('Affiliate Leads'), $ds, $this->_request, $this->view, $this->getDi());
        $grid->actionsClear();

        if ($this->getPluginConfig('allow_export'))
            $grid->actionAdd(new Am_Grid_Action_ExportAffLeads('_export', ___('Export')));

        $fieldTitles = $this->getPlugin()->getUserFields();
        foreach ($this->getPluginConfig('fields', $this->getPlugin()->getDefaultFields()) as $field) {
            switch ($field) {
                case 'added' :
                    $grid->addField(new Am_Grid_Field_Date('added', ___('Date/Time')));
                    break;
                case '__total_spend':
                    $grid->addField(new Am_Grid_Field('__total_spend', ___('Total Spend')))
                        ->setGetFunction([$this, 'getFieldValue'])
                        ->setRenderFunction(function ($r, $fn, $g, $fo) {
                            return $g->renderTd(Am_Currency::render($r->$fn));
                        });
                    break;
                default:
                    $grid->addField($this->createField($field, $fieldTitles[$field]));
            }
        }

        if ($this->getPluginConfig('allow_filter'))
            $grid->setFilter(new Am_Grid_Filter_AffLeads());

        return $grid;
    }

    function createField($field, $title)
    {
        $f = new Am_Grid_Field($field, $title, (strpos($field, '__') !== false ? false : true));
        $f->setGetFunction([$this, 'getFieldValue']);
        return $f;
    }

    function getFieldValue(User $record, $controller, $field)
    {
        if ($field == '__subscriptions') {
            $value = $record->__subscriptions;
        } elseif ($field == '__total_spend') {
            $value = $record->__total_spend;
        } elseif (strpos($field, '__data_') !== false) {
            $key = str_replace('__data_', '', $field);
            $value = $record->data()->get($key);
        } else if ($field == 'status') {
            switch ($record->get($field)) {
                case User::STATUS_ACTIVE : $value = ___('Active');
                    break;
                case User::STATUS_EXPIRED : $value = ___('Expired');
                    break;
                case User::STATUS_PENDING :
                default : $value = ___('Pending');
            }
        } else {
            $value = $record->get($field);
        }
        if (is_array($value))
            $value = implode(", ", $value);

        return $value;
    }

    /**
     * @return Am_Plugin_AffLeads
     */
    function getPlugin()
    {
        return $this->getDi()->plugins_misc->loadGet('aff-leads');
    }

    function getPluginConfig($key, $default = null)
    {
        return $this->getPlugin()->getConfig($key, $default);
    }
}

class Am_Grid_Action_ExportAffLeads extends Am_Grid_Action_Export
{
    protected $usePreset = false;
}

class Am_Grid_Filter_AffLeads extends Am_Grid_Filter_Abstract
{
    protected function applyFilter()
    {
        $ds = $this->grid->getDataSource();

        $filter = $this->vars['filter'];

        if (@$filter['dat1'])
            $ds->addWhere('t.added>=?', Am_Form_Element_Date::createFromFormat(null, $filter['dat1'])->format('Y-m-d 00:00:00'));
        if (@$filter['dat2'])
            $ds->addWhere('t.added<=?', Am_Form_Element_Date::createFromFormat(null, $filter['dat2'])->format('Y-m-d 23:59:59'));

        if (empty($filter['text'])) return;

        //use name field for search if field is not submitted explicitly
		$field = empty($filter['field']) ? 'name' : $filter['field'];
		$db = $this->grid->getDi()->db;

		if (strpos($field, '__data_') !== false) {
			$key = str_replace('__data_', '', $field);
			$ds->leftJoin('?_data', 'd', "t.user_id=d.id AND d.table='user' AND d.key='{$key}'");

			$ds->addWhere(
				'd.value LIKE ?',
				'%' . $filter['text'] . '%');
		} else {
            $ds->addHaving(
					$db->escapeWithPlaceholders(
							'(?# LIKE ?)',
							$field,
							'%' . $filter['text'] . '%'
						)
				);
		}
    }

    public function getEnabledFields()
    {
        $plugin = $this->grid->getDi()->plugins_misc->loadGet('aff-leads');
        $fieldTitles = $plugin->getUserFields();
        $fields = $plugin->getConfig('fields', $plugin->getDefaultFields());
        $options = [];
        foreach ($fields as $field) {
            $options[$field] = $fieldTitles[$field];
        }
        return $options;
    }

    public function renderInputs()
    {
        $prefix = $this->grid->getId();

        $dat1 = @$this->vars['filter']['dat1'];
        $dat2 = @$this->vars['filter']['dat2'];
        $filter = @$this->vars['filter']['text'];
        $start = ___('Start Date');
        $end = ___('End Date');
        $text_filter_title = ___('Filter Text');
        $options = Am_Html::renderOptions(array_merge(['' => '-- ' . ___('Select Search Criteria') . ' --'], $this->getEnabledFields()), @$this->vars['filter']['field']);

        return <<<CUT
<input type="text" placeholder="$start" name="{$prefix}_filter[dat1]" class='datepicker' style="width:100px" value="{$dat1}" />
<input type="text" placeholder="$end" name="{$prefix}_filter[dat2]" class='datepicker' style="width:100px" value="{$dat2}" />
<select name="{$prefix}_filter[field]">
{$options}
</select>
<input type="text" placeholder="$text_filter_title" name="{$prefix}_filter[text]" value="{$filter}" style="width:190px" />
CUT;
    }

    function getTitle()
    {
        return ___('Filter Leads');
    }
}