<?php
class Plugg_User_Main_Identity_View extends Sabai_Application_Controller
{
    protected function _doExecute(Sabai_Application_Context $context)
    {
        $identity = $this->_parent->getRequestedUserIdentity($context);
        $manager = $context->plugin->getManagerPlugin();

        if ($manager instanceof Plugg_User_Manager_API) {
            $manager->userView($context, $identity);
            return;
        }

        // Is user profile allowed to be viewed by any user?
        if (!$context->plugin->getParam('allowViewAnyUser')) {
            if (!$context->user->isAuthenticated()) {
                $context->response->setError(
                    $context->plugin->_('Permission denied'),
                    array('base' => '/user/login', 'params' => array('return' => 1))
                );
                return;
            } else {
                // Check permission if viewing other user's profile
                if ($identity->getId() != $context->user->getId()) {
                    if (!$context->user->hasPermission('user profile view any')) {
                        $context->response->setError($context->plugin->_('Permission denied'));
                        return;
                    }
                }
            }
        }

        // Any tab requested?
        if ($tab = $this->_getRequestedUserTab($context, $identity)) {
            $plugin_name = $tab->get('plugin');
            if ($tab_plugin = $this->pluginManager->getPlugin($plugin_name)) {
                $tab_id = $tab->getId();
                $template = clone $context->response->getTemplate();
                $template->setObject('Plugin', $tab_plugin)->addTemplateDir($tab_plugin->getTemplatePath());
                $tab_content = $tab_plugin->userTabGetContent($tab->get('name'), $context->request, $context->user,
                                                                $template, $tab_id, $identity);
            }
        }

        // Create default tab if none requested
        if (empty($tab_id)) {
            $tab_id = 0;
            $tab_content = '';
            $stat = $this->_parent->getEntityByIdentity($context, $identity, 'Stat');
            $status = $this->_parent->getEntityByIdentity($context, $identity, 'Status');
            $widgets = $this->_getUserWidgets($context, $identity);
            // Add profile widget to the top if viewing other user's profile or public view is requested
            if ($identity->getId() != $context->user->getId() ||
                $context->request->getAsBool('public')
            ) {
                $profile_widget = array(
                    'content' => sprintf('<div class="user-box">
  <h3 class="user-widget-header">%s</h3>
  %s
</div>', $context->plugin->_('User profile'), $this->_renderUserIdentity($context, $manager, $identity))
                );
                if (!empty($widgets[0])) {
                    array_unshift($widgets[0], $profile_widget);
                } else {
                    $widgets[0][] = $profile_widget;
                }
            }
            $context->response->setVars(array(
                'identity_stat' => $stat,
                'identity_status' => $status,
                'widgets' => $widgets
            ));
        }

        // View
        $tabs = $this->_getUserTabList($context, $identity);
        array_unshift($tabs, array('id' => 0, 'title' => $context->plugin->_('Top')));
        $context->response->setVars(array(
            'tabs' => $tabs,
            'tab_content' => $tab_content,
            'tab_id' => $tab_id,
        ));

        // Dispatch event
        $this->pluginManager->dispatch('UserIdentityViewed', array($context->user, $identity));
    }

    private function _renderUserIdentity(Sabai_Application_Context $context, $manager, $identity)
    {
        $fields = $this->_getUserFields($context, $identity);
        $template = clone $context->response->getTemplate();
        $template->setObject('Plugin', $manager)->addTemplateDir($manager->getTemplatePath());
        return $manager->userViewRenderIdentity($context->user, $template, $identity, $fields);
    }

    private function _getUserFields(Sabai_Application_Context $context, $identity)
    {
        $ret = array();
        $extra_data = $identity->getData();
        $relationships = $context->plugin->getRelationships($identity, $context->user);
        $fields = $context->plugin->getModel()->Field
            ->criteria()
            ->active_is(1)
            ->viewable_is(1)
            ->fetch(0, 0, 'field_order', 'ASC');
        foreach ($fields as $field) {
            $plugin_name = $field->get('plugin');
            if (!$plugin = $this->pluginManager->getPlugin($plugin_name)) {
                continue;
            }
            $plugin_lib = $plugin->getLibrary();
            $field_name = $field->get('name');
            $field_data = array_merge(
                array(
                    'value' => '',
                    'visibility' => array('@all')
                ),
                (array)@$extra_data[$plugin_lib][$plugin_name][$field_name]
            );
            if ($field->get('configurable') && $context->user->getId() != $identity->getId()) {
                if (empty($field_data['visibility'])) continue;
                if (in_array('@private', $field_data['visibility'])) {
                    continue;
                } elseif (in_array('@user', $field_data['visibility'])) {
                    if (!$context->user->isAuthenticated()) continue;
                } elseif (!in_array('@all', $field_data['visibility'])) {
                    if (!array_intersect($field_data['visibility'], $relationships)) continue;
                }
            }
            $ret[] = array(
                'plugin' => $plugin_name,
                'name' => $field_name,
                'title' => sprintf($field->get('title'), $plugin->getNicename()),
                'content' => $plugin->userFieldRender($field_name, $field_data['value'], $context->user, $identity),
            );
        }
        return $ret;
    }

    private function _getUserWidgets(Sabai_Application_Context $context, $identity)
    {
        $ret = array();
        $model = $context->plugin->getModel();
        $criteria = $model->createCriteria('Widget')->active_is(1);
        // Check if viewing other user's profile and if so is allowed viewing private tab contents
        if ($context->user->getId() != $identity->getId() &&
            !$context->user->hasPermission('user widget view any private')
        ) {
            $criteria->private_is(0); // not allowed to view other user's private tab contents
        }
        $widgets = $model->Widget->fetchByCriteria($criteria, 0, 0, 'widget_order', 'ASC');
        foreach ($widgets as $widget) {
            $plugin_name = $widget->get('plugin');
            if (!$plugin = $this->pluginManager->getPlugin($plugin_name)) {
                continue;
            }
            $widget_name = $widget->get('name');
            $widget_mini = intval($widget->get('mini'));
            $template = clone $context->response->getTemplate();
            $template->setObject('Plugin', $plugin)->addTemplateDir($plugin->getTemplatePath());
            $widget_content = $plugin->userWidgetGetContent($widget_name, $context->user, $template, $identity, $widget_mini);
            if ($widget_content) {
                $ret[$widget_mini][] = array(
                    'content' => $widget_content
                );
            }
        }
        return $ret;
    }

    private function _getRequestedUserTab(Sabai_Application_Context $context, $identity)
    {
        $ret = false;
        if (!$tab_id = $context->request->getAsInt('tab_id')) return false;

        $model = $context->plugin->getModel();
        $criteria = $model->createCriteria('Tab')
            ->active_is(1)
            ->id_is($tab_id);
        // Check if viewing other user's profile and if so is allowed viewing private tab contents
        if ($context->user->getId() != $identity->getId() &&
            !$context->user->hasPermission('user tab view any private')
        ) {
            $criteria->private_is(0); // not allowed to view other user's private tab contents
        }
        return $model->Tab->fetchByCriteria($criteria, 1, 0, 'tab_order', 'ASC')->getNext();
    }

    private function _getUserTabList(Sabai_Application_Context $context, $identity)
    {
        $ret = array();
        $model = $context->plugin->getModel();
        $criteria = $model->createCriteria('Tab')->active_is(1);
        // Check if viewing other user's profile and if so is allowed viewing private tab contents
        if ($context->user->getId() != $identity->getId() &&
            !$context->user->hasPermission('user tab view any private')
        ) {
            $criteria->private_is(0); // not allowed to view other user's private tab contents
        }
        $tabs = $model->Tab->fetchByCriteria($criteria, 0, 0, 'tab_order', 'ASC');
        foreach ($tabs as $tab) {
            $plugin_name = $tab->get('plugin');
            if (!$tab_plugin = $this->pluginManager->getPlugin($plugin_name)) {
                continue;
            }
            $tab_name = $tab->get('name');
            $ret[] = array(
                'id' => $tab->getId(),
                'title' => sprintf($tab->get('title'), $tab_plugin->getNicename())
            );
            // Add CSS file if any
            if ($tab_plugin->hasCSS()) {
                $plugin_library = $tab_plugin->getLibrary();
                $context->response->addCSSFile($this->url->getCssUrl($plugin_library), 'screen', $plugin_library);
            }
        }
        return $ret;
    }
}