<?php

if (!defined('BASEPATH')) {
    exit('No direct script access allowed');
}

/**
 * CRUD model
 *
 * @author CIEXT skeleton
 */
class Crud_product extends \Ciext\Model\AbstractEventModel
{

    protected $crud;
    protected $id_product_group;
    protected $post = [];
    protected $id_lan;
    protected $group_data = [];

    public function __construct()
    {
        parent::__construct();
        $this->load->library('rtgrid/rtgrid_api');
        $this->crud = new rtgrid_api();

        // Load language file
        $this->load->library('gettext_language');
        $this->gettext_language->load(__DIR__ . '/../language/' . $this->config->item('language') . '.po');

        // Acceess check
        if (!$this->rt_user->isAllowed('product', 'view_product')) {
            $this->admin_lib->show_denied();
        }
        if (!$this->rt_user->isAllowed('product', 'edit_product')) {
            $this->crud->unset_action('edit');
            $this->crud->unset_action('delete');
            $this->crud->unset_action('add');
        }
        $this->id_lan = $this->load->library('db_lang_lib')->get_current_lang_id();

        $this->id_product_group = (int) $this->uri->segment(6);
    }

    public function render()
    {
        $this->crud->set_table('product');
        $this->crud->columns('photo, translate_name, price, wholesale_price');
        $this->crud->fields('photo'
                . ', article'
                . ', translate_name'
                . ', id_product_manufacturer'
                . ', translate_short_desc'
                . ', translate_description'
                . ', old_price'
                . ', price'
                . ', wholesale_price'
                . ', count'
                . ', icons'
                . ', id_resource_type_page'
                . ', related'
        );

        $this->crud->required_fields('photo', 'translate_name', 'article', 'translate_short_desc', 'id_product_manufacturer');

        $this->crud->where('id_product_group', $this->id_product_group);

        $this->crud->hidden('id_product_group', $this->id_product_group);

        if (!$this->crud->is_grid()) {
            $opt = $this->get_groups_attrs();
            if ($opt != $this->load->view('product/admin_table', ['data' => [], 'title' => [], 'id_lan' => $this->id_lan], true)) {
                $this->crud->add_tab($this->lang->line('Options'), $this->get_groups_attrs(), 200);
                $this->post = $this->input->post();
                $this->crud->callback_after_edit([$this, 'save_product_attributes']);
            }
            $this->tooltips();
        }

        // Add video gallery
        if (!empty($this->get_group_data('video_gallery'))) {
            $this->load->library('rtgrid_video/rtgrid_video_api', ['table' => 'product_video', 'parent_field' => 'id_product'])->attach_crud($this->crud);
        }

        $this->callbacks()->display_as()->observers();

        // Notify
        $this->notify(__FUNCTION__, ['crud' => $this->crud]);

        return $this->crud->render();
    }

    protected function tooltips()
    {
        $this->crud->tooltip('old_price', $this->lang->line('This price is displayed crossed out on the site. If the product is installed action, then the old price will be the actual price of the product. If the old price set here manually (greater than zero), then it will override the value of the promotional prices and check the site will be the current value. Usually, you can leave the old price of 0'));
    }

    protected function callbacks()
    {
        $main_photo = new image_upload('photo', $this->config->item('product_photo_path'));
        $main_width = $this->config->item('product_photo_width');
        $main_height = $this->config->item('product_photo_height');
        if (!empty($main_width) && !empty($main_height)) {
            $main_photo->set_width($main_width);
            $main_photo->set_height($main_height);
        }
        $this->crud->set_image_upload($main_photo);
        $this->crud->multilang(new multilang('translate_name', 'product_translate', 'name'));
        $this->crud->multilang(new multilang('translate_short_desc', 'product_translate', 'short_desc', [(new Rtgc_textarea(['maxlength' => 255])), 'field']));
        $this->crud->multilang(new multilang('translate_description', 'product_translate', 'description', [(new Rtgc_texteditor()), 'field']));
        $this->crud->callback('old_price', $this->config->item('product_currency_callback'));
        $this->crud->callback('price', $this->config->item('product_currency_callback'));
        $this->crud->callback('wholesale_price', $this->config->item('product_currency_callback'));
        $this->crud->callback('count', 'spinner');
        $this->crud->callback('id_product_manufacturer', $this->load->library('product/callback/rtgc_relation_translate', ['table' => 'product_manufacturer', 'field' => 'name'])->init());
        $this->load->library('resmng/respage_rtgrid', [
            'crud'                           => $this->crud,
            'alias_field'                    => 'article',
            'id_resource_type_page_template' => $this->config->item('product_page_template'),
            'parent_id'                      => $this->get_parent_id(),
            'route'                          => $this->config->item('product_page_route'),
            'private'                        => false
        ]);

        if (!empty($this->get_group_data('photo_gallery'))) {
            $this->crud->add_photogallery(new photogallery('product_photo', rtrim($this->config->item('product_photo_path'), '/')));
        }

        $this->load->library('product/callback/rtgc_set_relation_n_n');
        $this->crud->set_relation_n_n('icons', 'product_icon_linker', 'product_icon', 'name');
        $this->crud->set_relation_n_n('related', 'product_related_linker', 'product', 'name', []);

        return $this;
    }

    protected function get_groups_attrs()
    {
        $template = '<div class="control-group"><div class="controls">%s</div></div>';
        $db = clone $this->db;
        $q = $db
                ->select('a.id_product_attr as id, aa.name, a.type, aa.options, v.value, aa.id_lan')
                ->join('product_group_linker gl', 'gl.id_product_attr=a.id_product_attr', 'left')
                ->join('product_attr_translate aa', 'aa.id_product_attr=a.id_product_attr', 'left')
                ->join('product_attr_value v', 'v.id_product_attr=a.id_product_attr AND v.id_product=' . (int) $this->uri->get_next_segment('edit'), 'left')
                ->where('a.active', true)
                ->order_by('aa.id_lan', 'ASC')
                ->where('gl.id_product_group', $this->id_product_group)
                ->get('product_attr a')
                ->result_array();

        $this->load->helper('form');
        $this->load->library('db_lang_lib');
        $data = [];
        $title = [];
        foreach ($q as $v) {
            $lan_name = $this->db_lang_lib->get_lang_by_id($v['id_lan'])->name;
            $title[$this->db_lang_lib->get_lang_by_id($v['id_lan'])->id_lan] = $lan_name;
            $lan_short_name = $this->db_lang_lib->get_lang_by_id($v['id_lan'])->short_name;

            $name = 'option[' . $v['id'] . '][' . $lan_short_name . ']';
            $options = (!empty($v['options'])) ? array_combine(json_decode($v['options']), json_decode($v['options'])) : [];
            $value = empty($v['value']) ? '' : unserialize($v['value'])[$lan_short_name];
            switch ($v['type']) {
                case 1:
                    $clb = form_input($name, $value);
                    break;
                case 2:
                    $clb = form_dropdown($name, $options, $value);
                    break;
                case 3:
                    $clb = form_multiselect($name . '[]', $options, $value, 'class="multiselect"');
                    $this->ciext->load_jquery_ui();
                    $plugin_folder = '/' . $this->config->item('assets_folder') . '/plugins/multiselect';
                    $this->js_css->add_js($plugin_folder . '/js/ui.multiselect.js');
                    $this->js_css->add_css($plugin_folder . '/css/common.css');
                    $this->js_css->add_css($plugin_folder . '/css/ui.multiselect.css');
                    $this->js_css->add_js_string('$(function(){$(\'.multiselect\').css(\'width\', \'600px\').css(\'height\', \'200px\').multiselect();});');
                    break;
                case 4:
                    $clb = (new \Rtgc_textarea())->field($name, $value);
                    break;
                case 5:
                    $clb = (new \Rtgc_texteditor())->field($name, $value);
                    break;
                default :
                    $clb = '';
                    break;
            }
            $data[$v['id']]['title'][$v['id_lan']] = $v['name'];
            $data[$v['id']]['option'][] = [
                'id_lan' => $v['id_lan'],
                'input'  => sprintf($template, $clb),
            ];
        }

        $content = [
            'data'   => $data,
            'title'  => $title,
            'id_lan' => $this->id_lan,
        ];

        return $this->load->view('product/admin_table', $content, true);
    }

    public function save_product_attributes($post = [], $id = 0)
    {
        if (!empty($this->post['option'])) {
            // Remove old
            $this->db->where('id_product', $id)->delete('product_attr_value');

            // Add new
            $ins = [];
            foreach ($this->post['option'] as $k => $v) {
                $ins[] = [
                    'id_product_attr' => $k,
                    'id_product'      => $id,
                    'value'           => serialize($v),
                ];
            }
            $this->db->insert_batch('product_attr_value', $ins);
        }

        return true;
    }

    protected function display_as()
    {
        $this->crud->display_as('photo', $this->lang->line('Main photo'));
        $this->crud->display_as('article', $this->lang->line('Article'));
        $this->crud->display_as('translate_name', $this->lang->line('Name'));
        $this->crud->display_as('translate_short_desc', $this->lang->line('Short description'));
        $this->crud->display_as('translate_description', $this->lang->line('Description'));
        $this->crud->display_as('old_price', $this->lang->line('Old price'));
        $this->crud->display_as('price', $this->lang->line('Price'));
        $this->crud->display_as('wholesale_price', $this->lang->line('Wholesale price'));
        $this->crud->display_as('count', $this->lang->line('Count'));
        $this->crud->display_as('id_product_manufacturer', $this->lang->line('Manufacturer'));
        $this->crud->display_as('icons', $this->lang->line('Icons'));
        $this->crud->display_as('related', $this->lang->line('Related products'));

        return $this;
    }

    protected function observers()
    {
        $this->load->helper('rtgrid/rtgrid_obs');
        $action = 'edit_product';
        $moreBtn = ' <a href="{link}">>>></a>';

        $this->crud->attach(make_rtgrid_add_obs('product', $action, $this->lang->line('Product was added') . $moreBtn));
        $this->crud->attach(make_rtgrid_edit_obs('product', $action, $this->lang->line('Product was edited') . $moreBtn));
        $this->crud->attach(make_rtgrid_delete_obs('product', $action, $this->lang->line('Product was deleted')));

        return $this;
    }

    protected function get_parent_id()
    {
        $db = clone $this->db;
        $q = $db
                ->select('r.id_resource')
                ->join('resource r', 'r.id_item=g.id_resource_type_page', 'left')
                ->where('r.id_resource_type', 3)
                ->where('g.id_product_group', (int) $this->uri->get_next_segment('products'))
                ->get('product_group g')
                ->row_array();

        return !empty($q['id_resource']) ? $q['id_resource'] : $this->config->item('product_group_page_parent_id');
    }

    protected function get_group_data($key)
    {
        if (empty($this->group_data)) {
            $this->group_data = $this->db
                ->where('id_product_group', $this->id_product_group)
                ->get('product_group')
                ->row_array();
        }

        return empty($this->group_data[$key]) ? false : $this->group_data[$key];
    }
}
