<?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 Dashboard
 *
 * @author Andhy Taslin <andhy@earworks.co.id>
 * @since 1.0
 */
class Dashboard extends MY_Controller {

    public $base = 'dashboard/index';

    public function __construct() {
        parent::__construct();
        $this->load->helper(['form', 'pagination', 'slug']);
    }

    public function index() {
        if (!$this->user) {
            redirect('login');
        }
        $user_absen = User_absen_model::get_dbo()->where('user_id', $this->user['user']['id'])->first();
        if (!$user_absen) {
            redirect('dashboard/not-have-absen');
        }

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

    public function history($pages = 1) {
        if (!$this->user) {
            redirect('login');
        }
        $user_absen = User_absen_model::get_dbo()->where('user_id', $this->user['user']['id'])->first();
        if (!$user_absen) {
            redirect('dashboard/not-have-absen');
        }
        $query = Visitor_absen_model::get_dbo('visitor_absen')
            ->select('visitor_absen.*', 'user_profile.name as nama_user', 'visitor_profile.name as nama_visitor', 'visitor_profile.optic as nama_optic', 'visitor_profile.table as table_number', 'visitor_profile.card_name as card')
            ->leftJoin('users', 'visitor_absen.user_id', '=', 'users.id')
            ->leftJoin('user_profile', 'users.id', '=', 'user_profile.user_id')
            ->leftJoin('users as visitors', 'visitor_absen.visitor_id', '=', 'visitors.id')
            ->leftJoin('user_profile as visitor_profile', 'visitors.id', '=', 'visitor_profile.user_id')
            ->where('visitor_absen.absen_id', $user_absen->absen_id);

        $query_pagination = query_pagination($query, [
            'per_page' => $this->get('show', 20),
            'pages' => $pages,
            'order' => $this->get('order', '-visitor_absen.created_at'),
            'keyword' => $this->get('keyword'),
            'search_field' => ['visitor_profile.name', 'visitor_profile.optic', 'visitor_profile.table', 'visitor_profile.card_name'],
            'uri_segment' => 3,
            'base_url' => base_url('dashboard/history'),
        ]);

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

    public function visitor_list($pages = 1) {
        if (!$this->user) {
            redirect('login');
        }
        $user_absen = User_absen_model::get_dbo()->where('user_id', $this->user['user']['id'])->first();
        if (!$user_absen) {
            redirect('dashboard/not-have-absen');
        }
        $query = User_model::get_dbo('users')
            ->leftJoin('user_profile', 'users.id', '=', 'user_profile.user_id')
            ->leftJoin('user_roles', 'users.id', '=', 'user_roles.user_id')
            ->leftJoin('visitor_absen', 'users.id', '=', 'visitor_absen.visitor_id')
            ->where('user_roles.role_id', 3);

        $query_pagination = query_pagination($query, [
            'per_page' => $this->get('show', 50),
            'pages' => $pages,
            'order' => $this->get('order', '-users.identity'),
            'keyword' => $this->get('keyword'),
            'search_field' => ['users.identity', 'visitor_absen.absen_id', 'users.username', 'user_profile.name', 'user_profile.email', 'user_profile.phone', 'user_profile.optic'],
            'uri_segment' => 3,
            'base_url' => base_url('dashboard/visitor-list'),
        ]);
        $user_absen = User_absen_model::get_dbo()->where('user_id', $this->user['user']['id'])->first();
        if (!$user_absen) {
            redirect('dashboard/not-have-absen');
        }
        $counter = Visitor_absen_model::get_dbo()
                ->where('visitor_absen.absen_id', $user_absen->absen_id)->count();
        Ci::view(__METHOD__, [
            'user_absen' => $user_absen,
            'user' => $this->user,
            'counter' => $counter,
            'query_pagination' => $query_pagination,
            'pagination' => create_pagination($query_pagination),
            'redir' => '?redir=' . urlencode(current_url() . url_query())
        ]);
    }

    public function not_have_absen() {
        if (!$this->user) {
            redirect('login');
        }
        Ci::view(__METHOD__);
    }

    public function visitor_check() {
        if (!$this->user) {
            redirect('login');
        }
        $user_absen = User_absen_model::get_dbo()->where('user_id', $this->user['user']['id'])->first();
        if (!$user_absen) {
            redirect('dashboard/not-have-absen');
        }
        $data = [
            'scan_code' => $this->post('scan_code'),
            'souvenir' => $this->post('souvenir')
        ];

        $validate = $this->validate_form(['scan_code'], false);
        if ($validate === true) {
            $scan_visitor = User_model::get_dbo()->where('identity', $data['scan_code'])->first();
            if (!$scan_visitor) {
                $this->session->set_flashdata('danger', 'Visitor tidak terdaftar');
                redirect($this->get_redir());
            } else {
                Ci::view(__METHOD__, [
                    'redir' => '?redir=' . $this->get_redir(true),
                    'data' => $data,
                    'visitor' => $scan_visitor
                ]);
            }
        } elseif ($validate[static::$field_status] === static::CODE_INVALID_PARAMETER) {
            $this->_show_alert($validate);
            redirect($this->get_redir());
        }
    }

    public function visitor_absen() {
        if (!$this->user) {
            redirect('login');
        }
        $user_absen = User_absen_model::get_dbo()->where('user_id', $this->user['user']['id'])->first();
        if (!$user_absen) {
            redirect('dashboard/not-have-absen');
        }
        $data = ['scan_code' => $this->post('scan_code'), 'souvenir' => $this->post('souvenir')];

        $validate = $this->validate_form(['scan_code'], false);
        if ($validate === true) {
            $scan_visitor = User_model::get_dbo()->where('identity', $data['scan_code'])->first();
            if (!$scan_visitor) {
                $this->session->set_flashdata('danger', 'Visitor tidak terdaftar');
            }
            $result = $user_absen->do_absen_visitor($scan_visitor, $this->user, $data);
            if ($result['status'] == 1) {
                $this->session->set_flashdata('success', $result['msg']);
            } else {
                $error = $result['data'] ? $result['msg'] . "<br />- " . implode("<br />- ", $result['data']) : $result['msg'];
                $this->session->set_flashdata('danger', $error);
            }
        } elseif ($validate[static::$field_status] === static::CODE_INVALID_PARAMETER) {
            $this->_show_alert($validate);
        }
        redirect($this->get_redir());
    }

    public function ajax_visitor_detail() {
        if (!$this->user) {
            exit("<p>Not logged in.</p>");
        }
        $user_absen = User_absen_model::get_dbo()->where('user_id', $this->user['user']['id'])->first();
        if (!$user_absen) {
            exit("<p>Not have absen.</p>");
        }
        $data = ['identity' => $this->post('id')];

        $validate = $this->validate_form(['id'], false);
        if ($validate === true) {
            $user = User_model::get_dbo()->where('identity', $data['identity'])->first();
            $views = Ci::partials(__METHOD__, ['user' => $user]);
            exit($views);
        } elseif ($validate[static::$field_status] === static::CODE_INVALID_PARAMETER) {
            $message = 'Terjadi Kesalahan:<br />';
            $i = 1;
            foreach ($validate['data'] as $k => $v) {
                $message .= $i . '. ' . $v . '<br />';
                $i++;
            }
            exit("<p>{$message}</p>");
        }
    }

    public function change_profile() {
        if (!$this->user) {
            redirect('login');
        }
        $this->load->helper('form');
        $user = User_model::get_dbo()->where('id', $this->user['user']['id'])->first(); // because stored as array in session

        $profile_model = $user->profile;
        // post data
        $data_user = [
            'username' => $user->username,
            'old_password' => $this->post('old_password'),
            'new_password' => $this->post('new_password'),
            'confirm_password' => $this->post('confirm_password')
        ];
        $data_profile = [
            'name' => $this->post('name', $profile_model->name),
            'email' => $this->post('email', $profile_model->email),
            'phone' => $this->post('phone', $profile_model->phone)
        ];
        $data = array_merge($data_user, $data_profile);
        // validate data
        $data_validate = [
            'name' => [
                'rules' => 'trim|required',
                'message' => ['required' => lang('%s_reqired')]
            ],
            'email' => [
                'rules' => 'trim|valid_email',
                'message' => ['valid_email' => lang('%s_not_valid_email')]
            ]
        ];
        if ($data['old_password']) {
            $data_validate = array_merge($data_validate, [
                'old_password' => [
                    'rules' => 'trim|required',
                    'message' => ['required' => lang('%s_reqired')]
                ],
                'new_password' => [
                    'rules' => 'trim|required',
                    'message' => ['required' => lang('%s_reqired')]
                ],
                'confirm_password' => [
                    'rules' => 'trim|required|matches[new_password]',
                    'message' => [
                        'required' => lang('%s_reqired'),
                        'matches' => lang('%s_not_match')
                    ]
                ]
            ]);
        }
        $validate = $this->validate_form($data_validate, false);
        // prosessing data
        if ($validate === true) {
            $this->load->helper('hash');
            Capsule::beginTransaction();
            // we can save profile information directly
            $profile_model->save_update($data_profile);
            // checking old password
            if ($data['old_password']) { // if old_password entered
                if (run_verify($data['old_password'], $user->password)) {
                    $user->save_update([
                        'password' => run_hash($data['new_password']),
                        'password_default' => ''
                    ]);
                    Capsule::commit();
                    $this->session->set_flashdata('changed_password', 1);
                    $this->session->set_flashdata('success', lang('update_profile_success'));
                    redirect($this->get_redir());
                } else {
                    $this->session->set_flashdata('danger', lang('old_password_not_match'));
                    Capsule::rollback();
                }
            } else {
                // assumtion is only change the profile information
                Capsule::commit();
                $this->session->set_flashdata('success', lang('update_profile_success'));
                redirect($this->get_redir());
            }
        } elseif ($validate[static::$field_status] === static::CODE_INVALID_PARAMETER) {
            $this->_show_alert($validate);
        }

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

    public function excel($id = null) {
        $this->load->library('ci_spreadsheet');
        $spreadsheet = new Ci_spreadsheet();
        $model = $this->_find_absen($id);
        $visitors = Visitor_absen_model::get_dbo()->where('absen_id', $model->id)->orderBy('created_at', 'ASC')->get();
        // sheet 1
        $sheet1 = [
            [''],
            [
                '', $model->nama, '', $visitors->count() . ' Data',
            ],
            [''],
            [
                'No', 'Nama', 'Optic', 'Tanggal'
            ]
        ];
        if ($visitors->count() > 0) {
            foreach ($visitors as $k => $visitor) {
                $sheet1[] = [
                    $k + 1, $visitor->visitor->profile->name,
                    $visitor->visitor->profile->optic,
                    date('d-m-Y', strtotime($visitor->created_at)),
                    date('H:i', strtotime($visitor->created_at))
                ];
            }
        }
        $sheet1_obj = $spreadsheet->prepare_absen_gate($spreadsheet->getActiveSheet(), [// createSheet()
            'num_row' => count($sheet1),
            'title' => 'Histori Absen'
        ]);
        $sheet1_obj->fromArray($sheet1);
        // generate
        $spreadsheet->generate('History_absen');
        exit;
    }

    public function excel_visitor() {
        $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,
                    '+62-'.$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 update($absen_id = null, $user_id = null, $visitor_id = null) {
//        $this->granted_backoffice(User_model::ACCESS_ABSEN_UPDATE);
        $model = $this->_find($absen_id, $user_id, $visitor_id);

        $data = [
            'souvenir' => $this->post('souvenir', $model->souvenir),
        ];

        $validate = $this->validate_form(['nama' => 'trim'], false);

        if ($validate === true) {
            Capsule::beginTransaction();
            $model->save_update($data);
            Capsule::commit();
            $this->session->set_flashdata('success', 'Ubah data berhasil');
            redirect($this->get_redir());
        } elseif ($validate[static::$field_status] === static::CODE_INVALID_PARAMETER) {
            $this->_show_alert($validate);
        }

        Ci::view(__METHOD__, [
            'data' => $data,
            'model' => $model,
            'redir' => $this->get_redir(true),
        ]);
    }

    public function delete($absen_id = null, $user_id = null, $visitor_id = null) {
//        $this->granted_backoffice(User_model::ACCESS_ABSEN_DELETE);
        $model = $this->_find($absen_id, $user_id, $visitor_id);
        // delete absen
        $model->delete();
        // result
        $this->session->set_flashdata('success', 'Hapus data berhasil');
        redirect($this->get_redir());
    }

    protected function _delete_all($ids) {
//        $this->granted_backoffice(User_model::ACCESS_ABSEN_DELETE);
        Capsule::beginTransaction();
        // delete user absen
        User_absen_model::get_dbo()->whereIn('absen_id', $ids)->delete();
        // delete absen
        Absen_model::get_dbo()->whereIn('id', $ids)->delete();
        // commit
        Capsule::commit();
        // result
//        $this->session->set_flashdata('success', 'Hapus data berhasil, Nama: ' . $model->nama);
        redirect($this->get_redir());
    }

    private function _find_absen($id = null) {
        $model = Absen_model::get_dbo()->where('id', $id)->first();
        if (!$model || !$id) {
            $this->session->set_flashdata('danger', 'Data tidak ditemukan');
            redirect($this->base);
        }
        return $model;
    }

    private function _find($absen_id = null, $user_id = null, $visitor_id = null) {
        $model = Visitor_absen_model::get_dbo()->where_key($absen_id, $user_id, $visitor_id)->first();
        if (!$model || !$absen_id || !$user_id || !$visitor_id) {
            $this->session->set_flashdata('danger', 'Data tidak ditemukan');
            redirect($this->base);
        }
        return $model;
    }

}
