<?php

namespace App\Controllers\Panel\Ujian;

use App\Controllers\Panel\BC;
use App\Models\Panel\BankSoal;
use App\Models\Panel\Ujian\Draft as UjianDraft;
use App\Models\Panel\UserModel;
use CodeIgniter\API\ResponseTrait;

class Draft extends BC
{
    use ResponseTrait;
    private $draftModel;
    public function __construct()
    {
        parent::__construct();
        $this->draftModel = new UjianDraft();
    }
    public function index()
    {
        $data['page_title'] = "Draft Ujian";
        return view('Panel/Ujian/Draft/index', $data);
    }

    public function print($id)
    {
        $opt = [];
        if (!user()->hasRole('admin')) {
            $opt['user_id'] = user()->id;
        }
        $bank = $this->draftModel->findId($id, $opt);
        if (!$bank) return $this->failNotFound();
        if ($bank['visible_pg'] > $bank['count_soal_pg']) return $this->fail("Jumlah Soal PG Tampil Lebih Banyak Dari Soal Yang Tersedia");
        if ($bank['visible_pgmulti'] > $bank['count_soal_pgmulti']) return $this->fail("Jumlah Soal PG Multi Tampil Lebih Banyak Dari Soal Yang Tersedia");
        if ($bank['visible_pgtf'] > $bank['count_soal_pgtf']) return $this->fail("Jumlah Soal PG True False Tampil Lebih Banyak Dari Soal Yang Tersedia");
        if ($bank['visible_pgcouple'] > $bank['count_soal_pgcouple']) return $this->fail("Jumlah Soal PG pasangan Tampil Lebih Banyak Dari Soal Yang Tersedia");
        if ($bank['visible_esai'] > $bank['count_soal_esai']) return $this->fail("Jumlah Soal Esai Tampil Lebih Banyak Dari Soal Yang Tersedia");
        if ($bank['visible_shortentry'] > $bank['count_soal_shortentry']) return $this->fail("Jumlah Soal Isian Singkat Tampil Lebih Banyak Dari Soal Yang Tersedia");
        $soal_id = [];
        $soal = [];
        $opsi = [];
        $db = db_connect();
        for ($i = 0; $i < $bank['visible_pg']; $i++) {
            $builder = $db->table('soal_data')->orderBy('id', 'ASC')->where(['bank_id' => $bank['bank_soal_id'], 'jenis_soal' => (new BankSoal())->jenis('pg')]);
            $builder->join('draft_soal ds', 'ds.soal_id=soal_data.id');
            if ($soal_id) {
                $builder->whereNotIn('id', $soal_id);
            }
            if ($bank['acak_soal'] == '1') {
                $soal[] = $builder->get(1, rand(0, $bank['visible_pg'] - (count($soal_id) + 1)))->getRowArray();
            } else {
                $soal[] = $builder->get()->getRowArray();
            }
            $soal_id[] = end($soal)['id'];
            $o = $db->table('soal_opsi')->getWhere(['soal_id' => end($soal_id)])->getResultArray();
            if ($o && $bank['acak_opsi'] == '1') shuffle($o);
            $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['bank_soal_id'], 'jenis_soal' => (new BankSoal())->jenis('pgmulti')]);
            $builder->join('draft_soal ds', 'ds.soal_id=soal_data.id');
            if ($soal_id) {
                $builder->whereNotIn('id', $soal_id);
            }
            if ($bank['acak_soal'] == '1') {
                $soal[] = $builder->get(1, rand(0, $bank['visible_pgmulti'] - (count($soal_id) + 1)))->getRowArray();
            } else {
                $soal[] = $builder->get()->getRowArray();
            }
            $soal_id[] = end($soal)['id'];
            $o = $db->table('soal_opsi')->getWhere(['soal_id' => end($soal_id)])->getResultArray();
            if ($o && $bank['acak_opsi'] == '1') shuffle($o);
            $opsi[end($soal_id)] = $o;
        }
        $soal_id = [];
        for ($i = 0; $i < $bank['visible_pgtf']; $i++) {
            $builder = $db->table('soal_data')->orderBy('id', 'ASC')->where(['bank_id' => $bank['bank_soal_id'], 'jenis_soal' => (new BankSoal())->jenis('pgtf')]);
            $builder->join('draft_soal ds', 'ds.soal_id=soal_data.id');
            if ($soal_id) {
                $builder->whereNotIn('id', $soal_id);
            }
            if ($bank['acak_soal'] == '1') {
                $soal[] = $builder->get(1, rand(0, $bank['visible_pgtf'] - (count($soal_id) + 1)))->getRowArray();
            } else {
                $soal[] = $builder->get()->getRowArray();
            }
            $soal_id[] = end($soal)['id'];
            $o = $db->table('soal_opsi')->getWhere(['soal_id' => end($soal_id)])->getResultArray();
            if ($o && $bank['acak_opsi'] == '1') shuffle($o);
            $opsi[end($soal_id)] = $o;
        }
        $soal_id = [];
        $couples = [];
        $oi = ["A", "B", "C", "D", "E"];
        for ($i = 0; $i < $bank['visible_pgcouple']; $i++) {
            $builder = $db->table('soal_data')->orderBy('id', 'ASC')->where(['bank_id' => $bank['bank_soal_id'], 'jenis_soal' => (new BankSoal())->jenis('pgcouple')]);
            $builder->join('draft_soal ds', 'ds.soal_id=soal_data.id');
            if ($soal_id) {
                $builder->whereNotIn('id', $soal_id);
            }
            if ($bank['acak_soal'] == '1') {
                $s = $builder->get(1, rand(0, $bank['visible_pgcouple'] - (count($soal_id) + 1)))->getRowArray();
            } else {
                $s = $builder->get()->getRowArray();
            }
            $soal_id[] = $s['id'];
            $s['coupled'] = [];
            $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['bank_soal_id'], 'jenis_soal' => (new BankSoal())->jenis('shortentry')]);
            $builder->join('draft_soal ds', 'ds.soal_id=soal_data.id');
            if ($soal_id) {
                $builder->whereNotIn('id', $soal_id);
            }
            if ($bank['acak_soal'] == '1') {
                $soalshortentry[] = $builder->get(1, rand(0, $bank['visible_shortentry'] - (count($soal_id) + 1)))->getRowArray();
            } else {
                $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['bank_soal_id'], 'jenis_soal' => (new BankSoal())->jenis('esai')]);
            $builder->join('draft_soal ds', 'ds.soal_id=soal_data.id');
            if ($soal_id) {
                $builder->whereNotIn('id', $soal_id);
            }
            if ($bank['acak_soal'] == '1') {
                $soalesai[] = $builder->get(1, rand(0, $bank['visible_esai'] - (count($soal_id) + 1)))->getRowArray();
            } else {
                $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['bank_soal_id']])->first();

        $orders = explode(',', $bank['order_soal']);
        $tpg = [];
        // $tcp = [];
        $tesai = [];
        if ($bank['acak_soal'] == '1') {

            foreach ([...$soal,  ...$soalesai] as $k => $v) {
                foreach ($orders as $id) {
                    if ($id == $v['id']) {
                        // 1=Pilihan Ganda,2=Esai,3=Pilihan Ganda Multi,4=Pilihan Ganda Pasangan,5=Isian Singkat,6=Pilihan Ganda True False
                        if (in_array($v['jenis_soal'], [1, 3, 4, 6])) $tpg[] = $v;
                        // else if ($v['jenis_soal'] == 4) $tcp[] = $v;
                        else if ($v['jenis_soal'] == 2) $tesai[] = $v;
                    }
                }
            }
            $soal = $tpg;
            // $couples = $tcp;
            $soalesai = $tesai;
        }
        $v['index'] = ['text' => ["A", "B", "C", "D", "E"], 'num' => 0];
        $v['shortentry'] = $soalshortentry;
        $v['logo'] = logo();
        $v['creator'] = $user->fullname;
        $v['mapel'] = $bank['nama_mapel'];
        $v['pg'] = $soal;
        $v['couples'] = $couples;
        $v['opsi'] = $opsi;
        $v['esai'] = $soalesai;
        return view('Panel/Ujian/Draft/print', $v);
    }
    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['mapel'] = $this->request->getGet('mapel');
        if (!is_numeric($opt['mapel'])) unset($opt['mapel']);
        $opt['bank_soal'] = $this->request->getGet('bank_soal');
        if (!is_numeric($opt['bank_soal'])) unset($opt['bank_soal']);
        $opt['acak_soal'] = $this->request->getGet('acak_soal');
        if (!is_numeric($opt['acak_soal'])) unset($opt['acak_soal']);
        $opt['acak_opsi'] = $this->request->getGet('acak_opsi');
        if (!is_numeric($opt['acak_opsi'])) unset($opt['acak_opsi']);
        $opt['visible_pg'] = $this->request->getGet('visible_pg');
        if (!is_numeric($opt['visible_pg'])) unset($opt['visible_pg']);
        $opt['visible_pgmulti'] = $this->request->getGet('visible_pgmulti');
        if (!is_numeric($opt['visible_pgmulti'])) unset($opt['visible_pgmulti']);
        $opt['visible_pgcouple'] = $this->request->getGet('visible_pgcouple');
        if (!is_numeric($opt['visible_pgcouple'])) unset($opt['visible_pgcouple']);
        $opt['visible_shortentry'] = $this->request->getGet('visible_shortentry');
        if (!is_numeric($opt['visible_shortentry'])) unset($opt['visible_shortentry']);
        $opt['visible_esai'] = $this->request->getGet('visible_esai');
        if (!is_numeric($opt['visible_esai'])) unset($opt['visible_esai']);


        $data = $this->draftModel->getAll($opt);
        return $this->respond(['data' => $data, 'csrf' => ['name' => csrf_token(), 'value' => csrf_hash()]]);
    }

    public function detail($id)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $opt = [];
        if (!user()->hasRole('admin')) {
            $opt['user_id'] = user()->id;
        }
        $data = $this->draftModel->findId($id, $opt);
        return $this->respond(['data' => $data]);
    }
    public function edit($id)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $data = (array) $this->request->getVar('data');
        if ($data['bobot_tf'] <= 0 && $data['bobot_esai'] <= 0) return $this->fail(["csrf" => csrf_hash(), 'message' => "Bobot tidak boleh 0"]);
        if ($data['bobot_tf'] + $data['bobot_esai'] > 100) return $this->fail(["csrf" => csrf_hash(), 'message' => "Bobot tidak boleh lebih dari 100"]);
        if (isset($data['nama'])) {
            $duplicate = $this->draftModel->where(['nama' => $data['nama'], 'id !=' => $id])->first();
            if ($duplicate) return $this->fail(["csrf" => csrf_hash(), 'message' => 'Nama Sudah Ada'], 409);
        }
        $state = $this->draftModel->update($id, $data);
        if (!$state) return $this->fail(["csrf" => csrf_hash(), 'message' => 'Gagal Mengubah Draft']);
        return $this->respond(["csrf" => csrf_hash(), 'message' => 'Berhasil Mengubah Draft']);
    }

    public function add()
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $data = (array) $this->request->getVar('data');
        if ($data['bobot_tf'] == 0 && $data['bobot_esai'] == 0) return $this->fail(["csrf" => csrf_hash(), 'message' => "Bobot tidak boleh 0"]);
        if (isset($data['nama'])) {
            $duplicate = $this->draftModel->where(['nama' => $data['nama']])->first();
            if ($duplicate) return $this->fail(["csrf" => csrf_hash(), 'message' => 'Nama Sudah Ada'], 409);
        }
        $state = $this->draftModel->insert($data);
        if (!$state) return $this->fail(["csrf" => csrf_hash(), 'message' => 'Gagal Menambah Draft']);
        return $this->respond(["csrf" => csrf_hash(), 'message' => 'Berhasil Menambah Draft']);
    }

    public function soals($id)
    {

        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $opt = [];
        if (!user()->hasRole('admin')) {
            $opt['user_id'] = user()->id;
        }
        $draft = $this->draftModel->findId($id, $opt);
        if (!$draft) return $this->failNotFound();
        $soals = $this->draftModel->getSoals($id);
        $orders = explode(',', $draft['order_soal']);
        if (count($orders) == 0) $data = $soals;
        else {
            $d = [];
            foreach ($orders as $id) {
                foreach ($soals as $k => $s) {
                    if ($id == $s['id']) {
                        $d[] = $s;
                        unset($soals[$k]);
                    }
                }
            }
            $data = [...$d, ...$soals];
        }
        return $this->respond($data);
    }
    public function saveSoals($id)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $opt = [];
        if (!user()->hasRole('admin')) {
            $opt['user_id'] = user()->id;
        }
        $draft = $this->draftModel->findId($id, $opt);
        if (!$draft) return $this->failNotFound();
        $soals = (array) $this->request->getVar('soals');
        $order_soal = $this->request->getVar('orders') ?? [];
        $order_soal = implode(',', $order_soal);
        $draft_soal = [];
        foreach ($soals as $k => $v) {
            $draft_soal[] = (array)$v;
        }
        $db = db_connect();
        $db->transStart();
        $db->table('draft_soal')->where('draft_id', $id)->delete();
        if (count($draft_soal) > 0) $db->table('draft_soal')->insertBatch($draft_soal);
        $db->table('draft_ujian')->where('id', $id)->set('order_soal', $order_soal)->update();
        $db->transComplete();
        if ($db->transStatus() === FALSE) return $this->fail(['message' => 'Tidak Dapat Menyimpan Soal']);
        return $this->respond(['message' => 'Berhasil Menyimpan Soal']);
    }

    public function delete($id)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        if (!$this->request->getVar('force-delete')) {
            $runningUjian = db_connect()->table('jadwal_ujian')->where(['draft_id' => $id, 'status' => 1])->get()->getRowArray();
            if ($runningUjian) return $this->fail(["csrf" => csrf_hash(), 'message' => 'Draft ini terhubung ke jadwal ujian, data ujian akan ikut terhapus', 'confirmation' => true]);
        }
        $state = $this->draftModel->delete($id);
        return $this->respond(['deleted' => $state, 'message' => $state ? "Berhasil Menghapus" : "Gagal Menghapus"]);
    }

    public function mapel()
    {
        $builder = db_connect()->table('m_mapel mm');
        $builder->select('mm.*');
        // if (!user()->hasRole('admin')) {
        // $builder->join('jadwal_pelajaran jp', 'jp.mapel_id=mm.id');
        // $builder->where('jp.user_id', user()->id);
        // }
        return $this->respond(['data' => $builder->get()->getResultArray()]);
    }
}
