<?php

/*
 * *************************************************
 * Copyright (C) 2021 Earworks.                    *
 * Codeigniter Project Template Modification       *
 * Please contact our email for more information : *
 * contact@earworks.co.id                          *
 * *************************************************
 */

defined('BASEPATH') OR exit('No direct script access allowed');

use Illuminate\Database\Capsule\Manager as Capsule;

/**
 * Description of Visitor_user
 *
 * @author Andhy Taslin <andhy@earworks.co.id>
 * @since 1.0
 */
class Visitor_user extends MY_Controller {

    /**
     * Base Url in this controller
     * @var string 
     */
    public $base = 'visitor-user/index';

    /**
     * Pre Load required file
     */
    public function __construct() {
        parent::__construct();
        $this->load->model(['user_role_model']);
        $this->load->helper(['form', 'pagination']);
    }

    public function index($pages = 1) {
        $this->granted_backoffice(User_model::ACCESS_USER_LIST);
        $query = User_model::get_dbo('users')
            ->leftJoin('user_profile', 'users.id', '=', 'user_profile.user_id')
            ->leftJoin('user_roles', 'users.id', '=', 'user_roles.user_id')
            ->where('user_roles.role_id', 3);

        $query_pagination = query_pagination($query, [
            'per_page' => $this->get('show', 20),
            'pages' => $pages,
            'order' => $this->get('order', 'id'),
            'keyword' => $this->get('keyword'),
            'search_field' => ['users.username', 'user_profile.name', 'user_profile.email', 'user_profile.phone', 'user_profile.optic'],
            'uri_segment' => 3,
            'base_url' => base_url($this->base)
        ]);

        Ci::view(__METHOD__, [
            'query_pagination' => $query_pagination,
            'pagination' => create_pagination($query_pagination),
            'redir' => '?redir=' . urlencode(current_url() . url_query())
        ]);
    }

    public function whatsapp($id = null) {

        $this->granted_backoffice(User_model::ACCESS_USER_UPDATE);
        $model = $this->_find($id);

        exit;
    }

    public function email($id = null) {
        $this->granted_backoffice(User_model::ACCESS_USER_UPDATE);
        $model = $this->_find($id);
        $profile = $model->profile;
        if (!$profile->email) {
            $this->session->set_flashdata('danger', 'Email tidak ada.');
            redirect($this->get_redir());
        }
        $emails = explode(';', $profile->email);
        if ($emails) {
            $results = [];
            $this->load->helper('mail');
            foreach ($emails as $email) {
                $results[] = send_mail([
                    'to' => $email,
                    'subject' => 'Astra Honda Motor Group Customer Appreciation 2023 - Reminder',
                    'message' => Ci::partials('email/reminder', [
                        'user' => $model,
                        'profile' => $profile
                    ])
                ]);
            }

//            if (!in_array(false, $results)) {
//                $model->status = User_data_model::STATUS_MAIL_SENT;
//            } else {
//                $model->status = User_data_model::STATUS_MAIL_FAILURE;
//            }
            $model->updated_at = date('Y-m-d H:i:s');
            $model->updated_by = $this->user['user']['id'];
            $model->save();
        }
        $this->session->set_flashdata('success', 'Email terkirim');
        redirect($this->get_redir());
    }

    public function create() {
        $this->granted_backoffice(User_model::ACCESS_USER_CREATE);
        $model = new User_model();
        $profile_model = new User_profile_model();
        // Post Data
        $data_user = [
            'phone' => $this->post('phone'),
            'password_default' => $this->post('password_default'),
            'status' => $this->post('status', User_model::STATUS_ACTIVE),
        ];
        $data_profile = [
            'name' => $this->post('name'),
            'location' => $this->post('location'),
            'card_name' => $this->post('card_name'),
            'info_tambahan' => $this->post('info_tambahan'),
            'email' => $this->post('email'),
            'optic' => $this->post('optic'),
            'province' => $this->post('province'),
            'city' => $this->post('city'),
            'district' => $this->post('district'),
            'sub_district' => $this->post('sub_district'),
            'poscode' => $this->post('poscode'),
            'address' => $this->post('address'),
            'pax' => $this->post('pax'),
            'pax_name' => $this->post('pax_name'),
            'pax_email' => $this->post('pax_email'),
            'pax_phone' => $this->post('pax_phone'),
            'table' => $this->post('table'),
            'seat' => $this->post('seat'),
            'main_course' => $this->post('main_course'),
            'alergy' => $this->post('alergy'),
        ];
        $roles = [User_model::LOGIN_TYPE_VISITOR];
        // validate data
        $validate = $this->validate_form(['name', 'email', 'phone', 'password_default'], false);
        // processing data
        if ($validate === true) { // must exact true type data
            Capsule::beginTransaction();
            // save user data
            $this->load->helper('hash');
            $data_user['password'] = run_hash($data_user['password_default']);
            $data_user['username'] = phone($data_user['phone']);
            $exists = User_model::get_dbo()->where('username', $data_user['username'])->count();
            if ($exists > 0) {
                $this->session->set_flashdata('danger', 'Phone number exists');
                Capsule::rollback();
            } else {
                unset($data_user['phone']);
                $model->save_update($data_user);
                // save identity
                $identity = User_model::generate_identity($model->id);
                User_model::get_dbo()->where('id', $model->id)->update(['identity' => $identity]);
                // save profile user
                $data_profile['user_id'] = $model->id;
                $data_profile['avatar'] = 'user.png';
                $data_profile['phone'] = $data_user['username'];
                $data_profile['pax_phone'] = phone($data_profile['pax_phone']);
                $profile_model->save_update($data_profile);
                // save role
                User_role_model::arrange($model->id, $roles);
                // Commit data
                Capsule::commit();
                // default (false) = don't encode url (for redirect)
                $this->session->set_flashdata('success', 'create user success');
                redirect($this->get_redir());
            }
        } elseif ($validate[static::$field_status] === static::CODE_INVALID_PARAMETER) {
            $this->_show_alert($validate);
        }
//        // get master role
//        $role_list = Role_model::get_dbo()->get();

        Ci::view(__METHOD__, [
            'data' => array_merge($data_profile, $data_user),
            'redir' => $this->get_redir(true), // true = encode url (for display)
            'model' => $model,
            'profile_model' => $profile_model,
//            'role_list' => $role_list
        ]);
    }

    public function update($id = null) {
        $this->granted_backoffice(User_model::ACCESS_USER_UPDATE);
        $model = $this->_find($id);

        $profile_model = $model->profile;
        // post data
        $data_user = [
            'phone' => $this->post('phone', $model->username),
            'password_default' => $this->post('password_default', $model->password_default),
            'status' => $this->post('status', $model->status)
        ];
        $data_profile = [
            'name' => $this->post('name', $profile_model->name),
            'location' => $this->post('location', $profile_model->location),
            'card_name' => $this->post('card_name', $profile_model->card_name),
            'info_tambahan' => $this->post('info_tambahan', $profile_model->info_tambahan),
            'email' => $this->post('email', $profile_model->email),
            'optic' => $this->post('optic', $profile_model->optic),
            'province' => $this->post('province', $profile_model->province),
            'city' => $this->post('city', $profile_model->city),
            'district' => $this->post('district', $profile_model->district),
            'sub_district' => $this->post('sub_district', $profile_model->sub_district),
            'poscode' => $this->post('poscode', $profile_model->poscode),
            'address' => $this->post('address', $profile_model->address),
            'pax' => $this->post('pax', $profile_model->pax),
            'pax_name' => $this->post('pax_name', $profile_model->pax_name),
            'pax_email' => $this->post('pax_email', $profile_model->pax_email),
            'pax_phone' => $this->post('pax_phone', $profile_model->pax_phone),
            'table' => $this->post('table', $profile_model->table),
            'seat' => $this->post('seat', $profile_model->seat),
            'main_course' => $this->post('main_course', $profile_model->main_course),
            'alergy' => $this->post('alergy', $profile_model->alergy),
        ];
        $roles = [User_model::LOGIN_TYPE_VISITOR];
        // validate data
        $validate = $this->validate_form(['name', 'email', 'optic'], false);
        // prosessing data
        if ($validate === true) {
            Capsule::beginTransaction();
            // save user data
            if ($data_user['password_default']) {
                $this->load->helper('hash');
                $data_user['password'] = run_hash($data_user['password_default']);
            }
            $data_user['username'] = phone($data_user['phone']);
            $exists = User_model::get_dbo()->where('username', $data_user['username'])->count();
            if ($exists > 0 && $data_user['username'] != $model->username) {
                $this->session->set_flashdata('danger', 'Phone number exists');
                Capsule::rollback();
            } else {
                unset($data_user['phone']);
                $model->save_update($data_user);
                // save user profile
                $data_profile['phone'] = $data_user['username'];
                $data_profile['pax_phone'] = phone($data_profile['pax_phone']);
                $profile_model->save_update($data_profile);
                // save roles
                User_role_model::arrange($model->id, $roles);
                // commit save
                Capsule::commit();
                // default (false) = don't encode url (for redirect)
                $this->session->set_flashdata('success', 'update user success');
                redirect($this->get_redir());
            }
        } elseif ($validate[static::$field_status] === static::CODE_INVALID_PARAMETER) {
            $this->_show_alert($validate);
        }
//        // get master role
//        $role_list = Role_model::get_dbo()->get();

        Ci::view(__METHOD__, [
            'data' => array_merge($data_user, $data_profile),
            'redir' => $this->get_redir(true), // true = encode url (for display)
            'model' => $model,
            'profile_model' => $profile_model,
//            'role_list' => $role_list
        ]);
    }

    public function import() {
        $this->load->library('ci_spreadsheet');
        $this->load->helper('hash');
        // reading
        $tmp = isset($_FILES['file']['tmp_name']) ? $_FILES['file']['tmp_name'] : null;
        $data = $this->ci_spreadsheet->read($tmp, ['calculate' => true]);
        // filtering
        $filtered = array_filter($data, function ($row) {
            return isset($row['B']) && !empty($row['B']) && $row['B'] != 'nama' && $row['B'] != 'Name' && $row['A'] != 'SID';
        });
        // processing
        Capsule::beginTransaction();
        if ($filtered) {
            foreach ($filtered as $res) {
                $e_user = $this->_get_user_from_excel($res);
                $user_data = [];
                if (!$e_user) {
                    // save user data
                    $e_user = new User_model();
                    $user_data = [
                        'username' => trim(strtolower($res['B'])),
                        'status' => User_model::STATUS_ACTIVE,
                    ];
                }
                if ($res['C']) {
                    $user_data['password'] = run_hash(trim(strtolower($res['C'])));
                    $user_data['password_default'] = strtolower($res['C']);
                }
                $e_user->save_update($user_data);
                // save role
                User_role_model::arrange($e_user->id, [3]);
                // save profile user
                $e_user_profile = User_profile_model::get_dbo()->where('user_id', $e_user->id)->first();
                if (!$e_user_profile) {
                    $e_user_profile = new User_profile_model();
                    $e_user_profile->user_id = $e_user->id;
                }
                $e_user_profile->save_update([
                    'name' => trim($res['D']),
                    'location' => trim($res['E']),
                    'card_name' => trim($res['F']),
                    'info_tambahan' => trim($res['G']),
                    'email' => trim($res['I']),
                    'optic' => trim($res['J']),
                    'province' => trim($res['K']),
                    'city' => trim($res['L']),
                    'district' => trim($res['M']),
                    'sub_district' => trim($res['N']),
                    'poscode' => trim($res['O']),
                    'address' => trim($res['P']),
                    'pax' => trim($res['Q']),
                    'pax_name' => trim($res['R']),
                    'pax_phone' => trim($res['S']),
                    'pax_email' => trim($res['T']),
                    'table' => trim($res['U']),
                    'seat' => trim($res['V']),
                    'main_course' => trim($res['W']),
                    'alergy' => trim($res['X']),
                ]);
            }
        }
        // Commit data
        Capsule::commit();
        $this->session->set_flashdata('success', 'Import data selesai');
        redirect($this->get_redir());
    }

    private function _get_user_from_excel($row) {
        $e_user = isset($row['B']) && !empty($row['B']) ? User_model::get_dbo()->where('username', trim(strtolower($row['B'])))->first() : null;
        if (!$e_user) {
            // coba sekali lgi langsung pake idnya
            $e_user = isset($row['A']) && !empty($row['A']) ? User_model::get_dbo()->where('id', trim($row['A']))->first() : null;
        }
        return $e_user;
    }

    public function excel() {
        $this->load->library('ci_spreadsheet');
        $spreadsheet = new Ci_spreadsheet();
        // sheet 1
        $sheet1 = [
            [
                'SID', 'Phone', 'Identity', 'Complete Name',
                'Location', 'Card Name', 'Other Info', 'Attended', 'Email', 'Optic Name',
                'Province', 'City', 'District', 'Sub District', 'Pos Code',
                'Address', 'Pax', 'Pax Name', 'Pax Phone', 'Pax Email','table', 
                'seat','main course', 'alergy','Privacy','Inform', 'Date'
            ]
        ];
        $users = User_model::get_dbo('users')
            ->select('users.*', 'user_profile.*', 'visitor_absen.absen_id')
            ->leftJoin('user_profile', 'users.id', '=', 'user_profile.user_id')
            ->leftJoin('user_roles', 'users.id', '=', 'user_roles.user_id')
            ->leftJoin('roles', 'user_roles.role_id', '=', 'roles.id')
            ->leftJoin('visitor_absen', 'users.id', '=', 'visitor_absen.visitor_id')
            ->where('roles.login_type', User_model::LOGIN_TYPE_VISITOR)
            ->where('roles.id', 3) // focus on visitor
            ->orderBy('users.id', 'ASC')
            ->get();
        if ($users->count() > 0) {
            foreach ($users as $k => $user) {
                $sheet1[] = [
                    $user->id,
                    $user->username,
                    $user->identity,
                    $user->name,
                    $user->location,
                    $user->card_name,
                    $user->info_tambahan,
                    $user->absen_id ? 'YES' : 'NO',
                    $user->email,
                    $user->optic,
                    $user->province,
                    $user->city,
                    $user->district,
                    $user->sub_district,
                    $user->poscode,
                    $user->address,
                    $user->pax,
                    $user->pax_name,
                    $user->pax_phone,
                    $user->pax_email,
                    $user->table,
                    $user->seat,
                    $user->main_course,
                    $user->alergy,
                    $user->privacy == 1 ? 'YES' : 'NO',
                    $user->inform == 1 ? 'YES' : 'NO',
                    $spreadsheet->excel_time($user->created_at),
                    $spreadsheet->excel_time($user->created_at),
                ];
            }
        }
//        echo "<pre>";
//        print_r($sheet1);
//        echo "</pre>";
//        exit;
        $sheet1_obj = $spreadsheet->prepare_user($spreadsheet->getActiveSheet(), [// createSheet()
            'num_row' => count($sheet1),
            'title' => 'Daftar Peserta'
        ]);
        $sheet1_obj->fromArray($sheet1);
        // generate
        $spreadsheet->generate('Peserta_' . date('Y-m-d'));
        exit;
    }

    public function pdf() {

        $users = User_model::get_dbo('users')
            ->select('users.*', 'user_profile.*')
            ->leftJoin('user_profile', 'users.id', '=', 'user_profile.user_id')
            ->leftJoin('user_roles', 'users.id', '=', 'user_roles.user_id')
            ->leftJoin('roles', 'user_roles.role_id', '=', 'roles.id')
            ->where('roles.login_type', User_model::LOGIN_TYPE_VISITOR)
            ->where('roles.id', 3) // focus on visitor
            ->orderBy('users.id', 'ASC')
            ->get();
        $defaultConfig = (new \Mpdf\Config\ConfigVariables())->getDefaults();
        $fontDirs = $defaultConfig['fontDir'];

        $defaultFontConfig = (new \Mpdf\Config\FontVariables())->getDefaults();
        $fontData = $defaultFontConfig['fontdata'];
        $mpdf = new \Mpdf\Mpdf([
            'fontDir' => array_merge($fontDirs, [
                dirname(STATIC_PATH) . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR
                . 'Roboto' . DIRECTORY_SEPARATOR,
            ]),
            'fontdata' => $fontData + [
            // lowercase letters only in font key
            'roboto' => [
                'R' => "Roboto-Regular.ttf",
                'B' => "Roboto-Bold.ttf",
                'I' => "Roboto-Italic.ttf",
                'BI' => "Roboto-BoldItalic.ttf",
            ]
            ],
            'default_font' => 'roboto'
        ]);

        if ($users->count() > 0) {
            foreach ($users as $user) {
                $html = Ci::partials(__METHOD__, ['user' => $user]);
                $mpdf = $this->_pdf_page($mpdf, $html);
            }
        }
        $mpdf->use_kwt = true;
        $mpdf->shrink_tables_to_fit = 1;
        // Output a PDF file directly to the browser
        $mpdf->Output('QR Code.pdf', 'I');
        exit;
    }

    private function _pdf_page($mpdf, $html) {
        $mpdf->AddPage(
            'P', // string $orientation:  L - landscape, P - portrait 
            '', // string $type
            '', // string $resetpagenum
            '', //  string $pagenumstyle
            '', // string $suppress
            0, // float $margin-left
            0, // float $margin-right
            0, // float $$margin-top
            0, // float $$margin-bottom
            0, // float $$margin-header
            0, // float $margin-footer
            '', // string $odd-header-name
            '', // string $even-header-name
            '', // string $$odd-footer-name
            '', // string $$even-footer-name
            '', // mixed $$odd-header-value
            '', // mixed $even-header-value
            '', // mixed $odd-footer-value
            '', // mixed $$even-footer-value
            '', // string $pageselector
            'A5-P', // mixed $sheet-size
        );
        $mpdf->WriteHTML($html);
        return $mpdf;
    }

    public function qr($id = null) {
        $this->granted_backoffice(User_model::ACCESS_ABSEN_QR);
        $this->load->library('qr');
        $user = $this->_find($id);
        $qrfile = QRPATH . $user->identity . '_share.png';

        if (!is_file(QRPATH . $user->identity . '.png')) {
            $this->load->library('qr2');
            // generate qr image
            $qr = new Qr2;
            $qr->with_logo($user->identity);
            // generate share image
            $qr->with_border($user->identity, $user->profile->name, $user->profile->optic, '0' . $user->profile->phone);
        }
        header('Pragma: public');   // required
        header('Expires: 0');       // no cache
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Cache-Control: private', false);
        header('Content-Type: image/png');
        header('Content-Disposition: attachment; filename="' . basename($qrfile) . '"');
        header('Content-Transfer-Encoding: binary');
        header('Content-Length: ' . filesize($qrfile));    // provide file size
        readfile($qrfile);       // push it out
        exit;
    }

    public function delete($id = null) {
        $this->granted_backoffice(User_model::ACCESS_USER_DELETE);
        $model = $this->_find($id);

        Capsule::beginTransaction();
        // delete user profile
        User_profile_model::get_dbo()->where('user_id', $id)->delete();
        // delete user roles
        User_role_model::get_dbo()->where('user_id', $id)->delete();
        // delete user
        $model->delete();
        // commit save data
        Capsule::commit();
        // default (false) = don't encode url (for redirect)
        redirect($this->get_redir());
    }

    protected function _delete_all($ids) {
        $this->granted_backoffice(User_model::ACCESS_USER_DELETE);
        Capsule::beginTransaction();
        // delete profiles
        User_profile_model::get_dbo()->whereIn('user_id', $ids)->delete();
        // delete roles
        User_role_model::get_dbo()->whereIn('user_id', $ids)->delete();
        // delete users
        User_model::get_dbo()->whereIn('id', $ids)->delete();
        // commit delete data
        Capsule::commit();
        // default (false) = don't encode url (for redirect)
        redirect($this->get_redir());
    }

    private function _find($id = null) {
        $model = User_model::get_dbo()->where('id', $id)->first();
        if (!$model || !$id) {
            // show err
            redirect($this->base);
        }
        return $model;
    }

}
