<?php

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

use \Ciext\Model\TableModelFactory as TFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as Xlsx_writer;
use \PhpOffice\PhpSpreadsheet\Reader\Xlsx as Xlsx_reader;

/**
 * @author Igor Ratsun
 * @author Olexandr Vlasiuk
 */
class Translate extends \Ciext\Controller\AbstractAdminController
{

    public function __construct()
    {
        parent::__construct();
        if (!$this->rt_user->isAllowed('system', 'translate_manager')) {
            $this->admin_lib->show_denied();
        }
        $this->load->model('ciext/translate_tmodel');
    }

    public function values()
    {
        $this->load->model('ciext/translate_tmodel');
        $this->load->helper('form');

        $langs = TFactory::create('lan')->set_predicates(['active' => true])->fetch_all();

        $data = [];
        foreach ($this->get_keys_from_files(APPPATH) as $item) {
            $data = array_merge($data, $item);
        }
        $lines = array_unique($data);
        sort($lines);

        $current_lang = (int) $this->uri->get_next_segment('values');
        if (!in_array($current_lang, array_column($langs, 'id_lan'))) {
            $current_lang = $this->load->library('db_lang_lib')->get_current_lang_id();
        }
        $exists = $this->translate_tmodel->fetch_all_by_lang_id($current_lang);
        $values = array_column($exists, 'value', 'line');

        $diff = array_diff(array_keys($values), $lines);
        if (!empty($diff)) {
            foreach ($diff as $val) {
                $lines[] = $val;
            }
            sort($lines);
        }
        // Import
        if ($this->session->flashdata('translate_imported_data')) {
            $values = array_merge($values, $this->session->flashdata('translate_imported_data'));
        }

        $content = $this->load->view('ciext/translate/translate', [
            'langs'        => $langs,
            'lines'        => $lines,
            'values'       => $values,
            'diff'         => $diff,
            'imported'     => $this->session->flashdata('translate_imported_data') ? $this->session->flashdata('translate_imported_data') : [],
            'lines_ids'    => array_column($exists, 'id_translate', 'line'),
            'current_lang' => $current_lang,
            'values_link'  => base_url($this->config->item('admin_page') . '/translate/values'),
            'save_link'    => base_url($this->config->item('admin_page') . '/translate/save'),
            'export_link'  => base_url($this->config->item('admin_page') . '/translate/export/' . $current_lang),
            'import_link'  => base_url($this->config->item('admin_page') . '/translate/import'),
                ], true);

        return $this->admin_lib->show([
                    'content' => $content,
                    'title'   => $this->lang->line('Translate manager')
        ]);
    }

    public function save()
    {
        $lines = (array) $this->input->post('line');
        $ids = (array) $this->input->post('id');
        $values = (array) $this->input->post('value');
        $id_lan = (int) $this->input->post('lan');
        if ($this->translate_tmodel->save_batch($lines, $ids, $values, $id_lan) > 0) {
            $this->session->set_flashdata('translate_message', $this->lang->line('Translations was saved'));
            $this->session->set_flashdata('translate_class', 'success');
        }

        redirect(base_url($this->config->item('admin_page') . '/translate/values/' . $id_lan));
    }

    public function export()
    {
        $data = [];
        foreach ($this->get_keys_from_files(APPPATH) as $item) {
            $data = array_merge($data, $item);
        }
        $lines = array_flip(array_unique($data));
        $lines = array_map(function($v) {
            return '';
        }, $lines);
        ksort($lines);

        $current_lang = (int) $this->uri->get_next_segment('export');
        if (empty($current_lang)) {
            $current_lang = $this->load->library('db_lang_lib')->get_current_lang_id();
        }
        $exists = $this->translate_tmodel->fetch_all_by_lang_id($current_lang);

        if (!empty($exists)) {
            $lines = array_merge($lines, array_column($exists, 'value', 'line'));
        }
        $examples = $this->input->get('example') ? array_column($this->translate_tmodel->fetch_all_by_lang_id($this->input->get('example')), 'value', 'line') : [];
        // PHPExel Spredsheet
        $spreadsheet = new Spreadsheet();
        $spreadsheet->getProperties()->setCreator('Ciext');
        $sheet = $spreadsheet->getActiveSheet();
        // Set sheet title data
        $sheet->setCellValue('A1', 'Key')->setCellValue('B1', 'Value');
        if (!empty($examples)) {
            $sheet->setCellValue('C1', $this->lang->line('Example'));
        }
        // Prepare data
        $data_tr = [];
        foreach ($lines as $key => $value) {
            $data_tr[] = [(string) $key, (string) $value, (string) (!empty($examples[$key]) ? $examples[$key] : '')];
        }
        $sheet->fromArray($data_tr, NULL, 'A2');
        $lang = $this->load->library('db_lang_lib')->get_lang_by_id($current_lang);
        // Save data as exel file
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment;filename="language_' . (isset($lang->short_name) ? $lang->short_name : '00') . '.xlsx"');
        header('Cache-Control: max-age=0');
        $writer = new Xlsx_writer($spreadsheet);
        $writer->save('php://output');
        exit;
    }

    public function import()
    {
        $this->load->library('upload', [
            'upload_path'   => ($this->config->item('cache_path') ?: './application/cache/'),
            'allowed_types' => ['xls', 'xlsx', 'csv'],
        ]);
        if (!$this->upload->do_upload('import')) {
            $this->session->set_flashdata('translate_message', $this->upload->display_errors());
            $this->session->set_flashdata('translate_class', 'danger');
        } else {
            $file = $this->upload->data()['full_path'];

            $reader = new Xlsx_reader();
            $objPHPExcel = $reader->load($file);
            $data = $objPHPExcel->getSheet(0)->toArray();
            unset($data[0]);
            unlink($file);
            $import = [];
            foreach ($data as $item) {
                if (!isset($item[0]) || !isset($item[1])) {
                    continue;
                }
                $import[$item[0]] = $item[1];
            }
            if (!empty($import)) {
                $this->session->set_flashdata('translate_imported_data', $import);
                $this->session->set_flashdata('translate_message', sprintf($this->lang->line('File imported. Records count %s. Please, check and save changes.'), count($import)));
                $this->session->set_flashdata('translate_class', 'info');
            }
        }

        $id_lan = (int) $this->input->post('lan');
        redirect(base_url($this->config->item('admin_page') . '/translate/values/' . $id_lan));
    }

    public function keys()
    {
        $this->load->model('ciext/translate/translate_crud');

        return $this->admin_lib->show([
                    'content' => $this->translate_crud->render(),
                    'title'   => $this->lang->line('Translate manager') . '/' . $this->lang->line('Keys')
        ]);
    }

    protected function get_keys_from_files($base)
    {
        $keys = [];
        $path = rtrim($base, '/');
        foreach (scandir($path) as $item) {
            if (in_array($item, ['.', '..'])) {
                continue;
            }
            $filename = $path . DIRECTORY_SEPARATOR . $item;
            if (is_dir($filename)) {
                $keys = array_merge($keys, $this->get_keys_from_files($filename));
                continue;
            }
            $lines = $this->fetch_lines($filename);
            if (empty($lines)) {
                continue;
            }
            $keys[$filename] = $lines;
        }

        return $keys;
    }

    protected function fetch_lines($filename)
    {
        if (pathinfo($filename, PATHINFO_EXTENSION) !== 'php') {

            return [];
        }
        $matches = [];
        preg_match_all('/line\(\'([^\']*)\'\)|line\("([^"]*)"\)/i', file_get_contents($filename), $matches);

        return !empty($matches) ? array_filter(array_merge($matches[1], $matches[2])) : [];
    }

}
