<?php

namespace App\Controllers\Panel\BankSoal;

use App\Controllers\Panel\BC;
use App\Models\Panel\BankSoal as BankSoalModel;
use App\Models\Panel\UserModel;
use CodeIgniter\API\ResponseTrait;
use ZipArchive;

class Main extends BC
{
    use ResponseTrait;
    private $bankSoalModel;
    public function __construct()
    {
        parent::__construct();
        $this->bankSoalModel = new BankSoalModel();
    }
    public function index()
    {
        return view('Panel/BankSoal/index', ['page_title' => "Bank Soal"]);
    }

    public function all()
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $opt = [];
        if (!user()->hasRole('admin')) {
            $opt['user_id'] = user()->id;
        }
        $opt['ORDER'] = "DESC";
        $data = $this->bankSoalModel->getAll($opt);
        return $this->respond(['data' => $data]);
    }
    public function detail($id)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $opt = ['id' => $id];
        if (!user()->hasRole('admin')) {
            $opt['user_id'] = user()->id;
        }
        $data = $this->bankSoalModel->getAll($opt);
        if ($data) return $this->respond($data);
        return $this->failNotFound();
    }

    public function delete($id)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $state = $this->bankSoalModel->delete($id);
        if ($state) return $this->respondDeleted("Berhasil menghapus data");
        return $this->fail("Gagal menghapus data");
    }
    public function deleteBatch()
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $id = (array) $this->request->getVar('id');
        $state = $this->bankSoalModel->delete($id);
        if ($state) return $this->respondDeleted("Berhasil menghapus data");
        return $this->fail("Gagal menghapus data");
    }
    public function save($id)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        if (!$this->request->getVar('isnew')) $data['id'] = $id;
        $data['deskripsi'] = $this->request->getVar('deskripsi');
        $data['kode'] = $this->request->getVar('kode');
        $data['user_id'] = $this->request->getVar('user_id');
        if (user()->hasRole('admin')) {
            if (!$data['user_id']) return $this->fail("Silahkan pilih guru");
        } else {
            $data['user_id'] = user()->id;
        }
        $state = $this->bankSoalModel->save($data);
        $respond = ['message' => "Berhasil mengubah data"];
        if ($this->request->getVar('isnew')) $respond['id'] = db_connect()->insertID();
        if ($state) return $this->respond($respond);
        return $this->fail("Gagal mengubah data");
    }

    public function files()
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $videoMime = [
            'video/x-flv', 'video/mp4', 'application/x-mpegURL',
            'video/MP2T', 'video/3gpp', 'video/quicktime',
            'video/x-msvideo', 'video/x-ms-wmv', 'audio/mpeg'
        ];
        $audioMime = ['audio/mpeg'];
        $imageMime = ['image/png', 'image/jpeg', 'image/webp'];

        $file = $this->request->getFile('file');
        if (!$file) return $this->failValidationErrors("File Tidak Valid!");
        if (!$file->isValid())   return $this->failValidationErrors("File Tidak Valid!");
        if ($file->hasMoved()) return $this->failResourceGone("File Tidak Ditemukan Di Server!");
        $app = config('app');
        if (in_array($file->getMimeType(), $imageMime)) {
            $imgName = $file->getRandomName();
            $soalPath = "$app->imgPath/soal";
            if ($file->getSize() > 10000) {
                compress_image($file->getTempName(), FCPATH . "$soalPath/$imgName");
            } else {
                $file->move(FCPATH . "$soalPath", $imgName);
            }
            rmbfe('php', FCPATH . $soalPath);
            $resourceLocation = "../../../$soalPath/$imgName";
            $res = [
                'html' => htmlIMAGE($resourceLocation),
                'location' => $resourceLocation,
            ];
            return $this->respond($res);
        } else if (in_array($file->getMimeType(), $audioMime)) {
            $audioName = $file->getRandomName();
            $audioPath = "$app->audioPath/soal";
            $file->move(FCPATH . "$audioPath", $audioName);
            rmbfe('php', FCPATH . $audioPath);
            $resourceLocation = "../../../$audioPath/$audioName";
            $res = [
                'html' => htmlMP3($resourceLocation),
                'location' => $resourceLocation,
            ];
            return $this->respond($res);
        } else if (in_array($file->getMimeType(), $videoMime)) {
            $videoName = $file->getRandomName();

            $videoPath = "$app->videoPath/soal";
            if (!file_exists(FCPATH . $videoPath)) {
                mkdir(FCPATH . $videoPath, 0777, true);
            }
            $mime = $file->getMimeType();
            $file->move(FCPATH . $videoPath, $videoName);
            rmbfe('php', FCPATH . $videoPath);

            $resourceLocation = "../../../$videoPath/$videoName";
            $res = [
                'html' => htmlVideo($resourceLocation, $mime),
                'location' => $resourceLocation,
            ];
            return $this->respond($res);
        }
        return $this->failValidationErrors("Jenis File Tidak Valid!");
    }
    public function preview($id, $type = null)
    {
        $data = $this->bankSoalModel->find($id);
        if (!$data) return $this->failNotFound();
        if (!$this->request->isAJAX()) {
            return view('Panel/BankSoal/preview', ['page_title' => "Preview Bank $data[kode]", "kode" => $data['kode'], 'bank_id' => $id]);
        }
        $db =  db_connect();
        switch ($type) {
            case 'soal':
                $soal = $db->table('soal_data')->getWhere(['bank_id' => $id])->getResultArray();
                return $this->respond(['soal' => $soal, 'kode' => $data['kode']]);
            case 'opsi':
                if (!$this->request->getGet('soal_id')) return $this->fail('Soal ID Tidak Valid!');
                $opsi = $db->table('soal_opsi')->select('soal_opsi.*')->join('soal_data', 'soal_data.id=soal_opsi.soal_id')->where(['soal_data.bank_id' => $id])->whereIn('soal_id', explode(',', $this->request->getGet('soal_id')))->get()->getResultArray();
                return $this->respond($opsi);
                break;
            case 'couple':
                if (!$this->request->getGet('soal_id')) return $this->fail('Soal ID Tidak Valid!');
                $couple = $db->table('soal_data_couple sdc')->select('sdc.*')->join('soal_data', 'soal_data.id=sdc.soal_id')->where(['soal_data.bank_id' => $id])->whereIn('soal_id', explode(',', $this->request->getGet('soal_id')))->get()->getResultArray();
                return $this->respond($couple);
                break;
        }
    }

    public function print($id)
    {
        $db = db_connect();
        $visible_pg = $db->table('soal_data')->select('COUNT(*)')->where(['bank_id' => $id, 'jenis_soal' => (new BankSoalModel())->jenis('pg')])->getCompiledSelect();
        $visible_esai = $db->table('soal_data')->select('COUNT(*)')->where(['bank_id' => $id, 'jenis_soal' => (new BankSoalModel())->jenis('esai')])->getCompiledSelect();
        $visible_pgmulti = $db->table('soal_data')->select('COUNT(*)')->where(['bank_id' => $id, 'jenis_soal' => (new BankSoalModel())->jenis('pgmulti')])->getCompiledSelect();
        $visible_pgcouple = $db->table('soal_data')->select('COUNT(*)')->where(['bank_id' => $id, 'jenis_soal' => (new BankSoalModel())->jenis('pgcouple')])->getCompiledSelect();
        $visible_shortentry = $db->table('soal_data')->select('COUNT(*)')->where(['bank_id' => $id, 'jenis_soal' => (new BankSoalModel())->jenis('shortentry')])->getCompiledSelect();

        $bank = $db->table('m_banksoal');
        $bank->select("m_banksoal.*,($visible_pg) as visible_pg,($visible_esai) as visible_esai,($visible_pgmulti) as visible_pgmulti,($visible_pgcouple) as visible_pgcouple,($visible_shortentry) as visible_shortentry");
        $bank->where('id', $id);
        if (!user()->hasRole('admin')) {
            $bank->where('user_id', user()->id);
        }
        $bank = $bank->get()->getRowArray();
        $soal_id = [];
        $soal = [];
        $opsi = [];
        for ($i = 0; $i < $bank['visible_pg']; $i++) {
            $builder = $db->table('soal_data')->orderBy('id', 'ASC')->where(['bank_id' => $bank['id'], 'jenis_soal' => (new BankSoalModel())->jenis('pg')]);
            if ($soal_id) {
                $builder->whereNotIn('id', $soal_id);
            }
            $soal[] = $builder->get()->getRowArray();
            $soal_id[] = end($soal)['id'];
            $o = $db->table('soal_opsi')->getWhere(['soal_id' => end($soal_id)])->getResultArray();
            $opsi[end($soal_id)] = $o;
        }
        $soal_id = [];
        for ($i = 0; $i < $bank['visible_pgmulti']; $i++) {
            $builder = $db->table('soal_data')->orderBy('id', 'ASC')->where(['bank_id' => $bank['id'], 'jenis_soal' => (new BankSoalModel())->jenis('pgmulti')]);
            if ($soal_id) {
                $builder->whereNotIn('id', $soal_id);
            }
            $soal[] = $builder->get()->getRowArray();
            $soal_id[] = end($soal)['id'];
            $o = $db->table('soal_opsi')->getWhere(['soal_id' => end($soal_id)])->getResultArray();
            $opsi[end($soal_id)] = $o;
        }
        $soal_id = [];
        $oi = ["A", "B", "C", "D", "E"];
        $couples = [];
        for ($i = 0; $i < $bank['visible_pgcouple']; $i++) {
            $builder = $db->table('soal_data')->orderBy('id', 'ASC')->where(['bank_id' => $bank['id'], 'jenis_soal' => (new BankSoalModel())->jenis('pgcouple')]);
            if ($soal_id) {
                $builder->whereNotIn('id', $soal_id);
            }
            $s = $builder->get()->getRowArray();
            $s['coupled'] = [];
            $soal_id[] = $s['id'];
            $couple = $db->table('soal_data_couple')->getWhere(['soal_id' => end($soal_id)])->getResultArray();
            $o = $db->table('soal_opsi')->getWhere(['soal_id' => end($soal_id)])->getResultArray();
            foreach ($o as $k => $v) {
                foreach ($couple as $ck => $cv) {
                    if ($v['soal_couple_id'] == $cv['id']) {
                        $s['coupled'][] = "$oi[$ck]-$oi[$k]";
                        break;
                    }
                }
            }
            $couples[end($soal_id)] = $couple;
            $opsi[end($soal_id)] = $o;
            $soal[] = $s;
        }
        $soal_id = [];
        $soalshortentry = [];
        for ($i = 0; $i < $bank['visible_shortentry']; $i++) {
            $builder = $db->table('soal_data')->orderBy('id', 'ASC')->where(['bank_id' => $bank['id'], 'jenis_soal' => (new BankSoalModel())->jenis('shortentry')]);
            if ($soal_id) {
                $builder->whereNotIn('id', $soal_id);
            }
            $soalshortentry[] = $builder->get()->getRowArray();
            $soal_id[] = end($soalshortentry)['id'];
        }
        $soal_id = [];
        $soalesai = [];
        for ($i = 0; $i < $bank['visible_esai']; $i++) {
            $builder = $db->table('soal_data')->orderBy('id', 'ASC')->where(['bank_id' => $bank['id'], 'jenis_soal' => (new BankSoalModel())->jenis('esai')]);
            if ($soal_id) {
                $builder->whereNotIn('id', $soal_id);
            }
            $soalesai[] = $builder->get()->getRowArray();
            $soal_id[] = end($soalesai)['id'];
        }
        $user = (new UserModel())->join('m_banksoal mbs', 'mbs.user_id=users.id')->where(['mbs.id' => $bank['id']])->first();
        $v['index'] = ['text' => ["A", "B", "C", "D", "E"], 'num' => 0];
        $v['shortentry'] = $soalshortentry;
        $v['logo'] = logo();
        $v['creator'] = $user->fullname;
        $v['pg'] = $soal;
        $v['opsi'] = $opsi;
        $v['couples'] = $couples;
        $v['esai'] = $soalesai;
        return view('Panel/BankSoal/print', $v);
    }
}
