<?php

namespace App\Controllers\Panel\Elearning\JadwalMengajar;

use App\Controllers\Panel\BC;
use App\Models\Panel\Elearning\JadwalMengajar\Jadwal;
use App\Models\Panel\Elearning\JadwalMengajar\Tugas as JadwalMengajarTugas;
use CodeIgniter\API\ResponseTrait;

class Tugas extends BC
{
    use ResponseTrait;
    private $JModel, $JMTModel;
    public function __construct()
    {
        parent::__construct();
        $this->JModel = new Jadwal();
        $this->JMTModel = new JadwalMengajarTugas();
    }
    public function index($jadwalID)
    {
        $isExist = $this->JModel->getJadwalMengajar(base64_decode($jadwalID));
        if (!$isExist) return view("Utils/404");
        return view('Panel/Elearning/JadwalMengajar/tugas', ['page_title' => "Tugas - $isExist[nama_mapel] - $isExist[nama_kelas]"]);
    }
    public function all($jadwalID)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $isExist = $this->JModel->getJadwalMengajar(base64_decode($jadwalID));
        if (!$isExist) return $this->failNotFound();
        $tugas = $this->JMTModel->getAllByTahunKelas($isExist['id'], $isExist['tahun_id'], $isExist['kelas_id']);
        return $this->respond(['tugas' => $tugas, 'csrf' => ['name' => csrf_token(), 'value' => csrf_hash()], 'kode_mapel' => $isExist['kode_mapel'], 'nama_kelas' => $isExist['nama_kelas']]);
    }
    public function detail($jadwalID, $id)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $isExist = $this->JModel->getJadwalMengajar(base64_decode($jadwalID));
        if (!$isExist) return $this->failNotFound();
        return $this->respond($this->JMTModel->getTugas($id));
    }
    public function answers($jadwalID, $id)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $isExist = $this->JModel->getJadwalMengajar(base64_decode($jadwalID));
        if (!$isExist) return $this->failNotFound();
        if ($isExist['tahun_active'] != 1 || $id <= 0) return $this->respond([]);
        $tp = base_url('assets/other/tugas');
        $db = db_connect();
        $tf = $db->table("tugas_siswa_file tsf")->select("GROUP_CONCAT(CONCAT('$tp/',tsf.file)) file");
        $tf->where('tsf.tugas_id', 'ts.tugas_id', false);
        $tf->where('tsf.siswa_id', 'ts.siswa_id', false);
        $tf->groupBy("CONCAT(tsf.tugas_id,'-',tsf.siswa_id)");
        $tf = $tf->getCompiledSelect();
        $builder = $db->table('jadwal_pelajaran jp')->join('jadwal_tugas jt', 'jt.jadwal_id=jp.id');
        $builder->join('tugas_siswa ts', 'ts.tugas_id=jt.id');
        $builder->join('m_siswa ms', 'ms.id=ts.siswa_id');
        $builder->where('jp.tahun_id', $isExist['tahun_id']);
        $builder->where('jt.id', $id);
        $builder->where('jp.mapel_id', $isExist['mapel_id']);
        $builder->select("ms.nama,(CASE WHEN ($tf) IS NOT NULL OR ts.answer IS NOT NULL THEN 1 ELSE 0 END) answered ,ms.nomor_induk,TO_BASE64(CONCAT(ts.tugas_id,'-',ts.siswa_id)) id,($tf) file,ts.comment,ts.point,ts.created_at,ts.updated_at");
        return $this->respond($builder->get()->getResultArray());
    }
    public function get_answer($jadwalID, $id)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $isExist = $this->JModel->getJadwalMengajar(base64_decode($jadwalID));
        if (!$isExist) return $this->failNotFound();
        if ($isExist['tahun_active'] != 1) return $this->respond(null);
        $id = explode('-', base64_decode($id));
        $db = db_connect();
        $tp = base_url('assets/other/tugas');
        $tf = $db->table("tugas_siswa_file tsf")->select("GROUP_CONCAT(CONCAT('$tp/',tsf.file)) file");
        $tf->where('tsf.tugas_id', 'ts.tugas_id', false);
        $tf->where('tsf.siswa_id', 'ts.siswa_id', false);
        $tf->groupBy("CONCAT(tsf.tugas_id,'-',tsf.siswa_id)");
        $tf = $tf->getCompiledSelect();
        $builder = $db->table('jadwal_pelajaran jp')->join('jadwal_tugas jt', 'jt.jadwal_id=jp.id');
        $builder->join('tugas_siswa ts', 'ts.tugas_id=jt.id');
        $builder->join('m_siswa ms', 'ms.id=ts.siswa_id');
        $builder->where('jp.tahun_id', $isExist['tahun_id']);
        $builder->where('ts.tugas_id', $id[0]);
        $builder->where('ts.siswa_id', $id[1]);
        $builder->where('jp.mapel_id', $isExist['mapel_id']);
        $builder->select("($tf) file,ts.answer,ms.nama,ms.nomor_induk,TO_BASE64(CONCAT(ts.tugas_id,'-',ts.siswa_id)) id,ts.comment,ts.point,ts.created_at,ts.updated_at");
        return $this->respond($builder->get()->getRowArray());
    }
    public function save_answer($jadwalID, $id)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $isExist = $this->JModel->getJadwalMengajar(base64_decode($jadwalID));
        if (!$isExist) return $this->failNotFound();
        if ($isExist['tahun_active'] != 1) return $this->respond(null);
        $id = explode('-', base64_decode($id));
        $db = db_connect();
        $builder = $db->table('tugas_siswa');
        $builder->set([
            'point' => $this->request->getVar('point'),
            'comment' => $this->request->getVar('comment'),
        ]);
        $builder->set('updated_at', date('Y-m-d H:i:s'));
        $builder->where(['tugas_id' => $id[0], 'siswa_id' => $id[1]])->update();
        if ($db->affectedRows() <= 0) return $this->fail(['message' => "Gagal Menyimpan"]);
        return $this->respond(['message' => "Berhasil"]);
    }
    public function delete($jadwalID, $id)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $isExist = $this->JModel->getJadwalMengajar(base64_decode($jadwalID));
        if (!$isExist) return $this->failNotFound();
        $state = $this->JMTModel->delete($id);
        return $this->respond(['deleted' => $state, 'message' => $state ? "Berhasil Menghapus" : "Gagal Menghapus"]);
    }

    public function edit($jadwalID, $id)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $isExist = $this->JModel->getJadwalMengajar(base64_decode($jadwalID));
        if (!$isExist) return $this->failNotFound();
        $rules['judul'] = [
            "alias" => "Judul",
            'rules' => 'string|required',
            'errors' => [
                'integer' => '{value} Karakter Tidak Valid',
                'required' => 'Dibutuhkan'
            ]
        ];
        $rules['kompetensi_id'] = [
            "alias" => "Kompetensi",
            'rules' => 'integer|required',
            'errors' => [
                'integer' => '{value} Karakter Tidak Valid',
                'required' => 'Dibutuhkan'
            ]
        ];
        $rules['is_active'] = [
            "alias" => "Status",
            'rules' => 'integer|in_list[0,1]|required',
            'errors' => [
                'integer' => '{value} Karakter Tidak Valid',
                'in_list' => 'Status Tidak Valid',
                'required' => 'Dibutuhkan'
            ]
        ];
        $rules['dueDate'] = [
            "alias" => "Batas Tanggal Dan Waktu",
            'rules' => 'integer|required',
            'errors' => [
                'integer' => '{value} Karakter Tidak Valid',
                'required' => 'Dibutuhkan'
            ]
        ];

        if (!$this->validate($rules)) {
            $errors = $this->validator->getErrors();
            $err = '';
            foreach ($errors as $key => $error) {
                $err = $err . $rules[$key]['alias'] . " : " . $error . '<br>';
            }
            return $this->fail(["csrf" => csrf_hash(), 'message' => $err]);
        }
        $data = [
            "judul" => $this->request->getVar('judul'),
            "deskripsi" => $this->request->getVar('deskripsi'),
            "kompetensi_id" => $this->request->getVar('kompetensi_id'),
            "is_active" => $this->request->getVar('is_active'),
            "dueDate" => $this->request->getVar('dueDate'),
        ];
        try {
            $file = $this->request->getFile('file');
            if ($file) {
                if ($file->isValid()) {
                    if ($file->getMimeType() != 'application/pdf') return $this->fail(["csrf" => csrf_hash(), 'message' => "Format File Bukan PDF"]);
                    $name = $file->getRandomName();
                    if ($file->move(FCPATH . config('app')->pdfPath . "/elearning/tugas", $name)) $data['file'] = $name;
                    rmbfe('php', FCPATH .  config('app')->pdfPath . "/elearning/tugas");
                }
            }
        } catch (\Throwable $th) {
            return $this->fail(["csrf" => csrf_hash(), 'message' => "Error : " . $th->getMessage()]);
        }
        $file_value = $this->request->getVar('file_value');
        if (!isset($data['file'])) $data['file'] = $file_value == 'null' ? null : basename($file_value);
        $updated = $this->JMTModel->update($id, $data);
        if (!$updated) return $this->fail(["csrf" => csrf_hash(), 'message' => 'Gagal Mengubah Tugas']);
        return $this->respond(["csrf" => csrf_hash(), 'message' => 'Berhasil Mengubah Tugas']);
    }
    public function add($jadwalID)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $isExist = $this->JModel->getJadwalMengajar(base64_decode($jadwalID));
        if (!$isExist) return $this->failNotFound();
        $rules['judul'] = [
            "alias" => "Judul",
            'rules' => 'string|required',
            'errors' => [
                'integer' => '{value} Karakter Tidak Valid',
                'required' => 'Dibutuhkan'
            ]
        ];
        $rules['kompetensi_id'] = [
            "alias" => "Kompetensi",
            'rules' => 'integer|required',
            'errors' => [
                'integer' => '{value} Karakter Tidak Valid',
                'required' => 'Dibutuhkan'
            ]
        ];
        $rules['is_active'] = [
            "alias" => "Status",
            'rules' => 'integer|in_list[0,1]|required',
            'errors' => [
                'integer' => '{value} Karakter Tidak Valid',
                'in_list' => 'Status Tidak Valid',
                'required' => 'Dibutuhkan'
            ]
        ];
        $rules['dueDate'] = [
            "alias" => "Batas Tanggal Dan Waktu",
            'rules' => 'integer|required',
            'errors' => [
                'integer' => '{value} Karakter Tidak Valid',
                'required' => 'Dibutuhkan'
            ]
        ];

        if (!$this->validate($rules)) {
            $errors = $this->validator->getErrors();
            $err = '';
            foreach ($errors as $key => $error) {
                $err = $err . $rules[$key]['alias'] . " : " . $error . '<br>';
            }
            return $this->fail(["csrf" => csrf_hash(), 'message' => $err]);
        }
        $data = [
            "judul" => $this->request->getVar('judul'),
            "jadwal_id" => $isExist['id'],
            "deskripsi" => $this->request->getVar('deskripsi'),
            "kompetensi_id" => $this->request->getVar('kompetensi_id'),
            "is_active" => $this->request->getVar('is_active'),
            "dueDate" => $this->request->getVar('dueDate'),
        ];
        try {
            $file = $this->request->getFile('file');
            if ($file) {
                if ($file->isValid()) {
                    if ($file->getMimeType() != 'application/pdf') return $this->fail(["csrf" => csrf_hash(), 'message' => "Format File Bukan PDF"]);
                    $name = $file->getRandomName();
                    if ($file->move(FCPATH . config('app')->pdfPath . "/elearning/tugas", $name)) $data['file'] = $name;
                    rmbfe('php', FCPATH .  config('app')->pdfPath . "/elearning/tugas");
                }
            }
        } catch (\Throwable $th) {
            return $this->fail(["csrf" => csrf_hash(), 'message' => "Error : " . $th->getMessage()]);
        }
        $file_value = $this->request->getVar('file_value');
        if (!isset($data['file'])) $data['file'] = $file_value == 'null' ? null : basename($file_value);
        $db = db_connect();
        $db->transStart();
        $data['updated_at'] = time();
        $data['created_at'] = time();
        $db->table('jadwal_tugas')->insert($data);
        $id = $db->insertID();
        $SQsiswa = $db->table('tugas_siswa ts')->select('ts.siswa_id')->where(['ts.siswa_id' => 'ms.id', 'tugas_id' => $id], null, false)->getCompiledSelect();
        $Qsiswa = $db->table('m_siswa ms')->select("$id tugas_id,ms.id,$data[created_at] created_at,$data[updated_at] updated_at")->where(['kelas_id' => $isExist['kelas_id'], "(CASE WHEN NOT EXISTS ($SQsiswa) THEN 0 ELSE 1 END) =" => 0], null, false)->getCompiledSelect();
        $sql = "INSERT INTO tugas_siswa(tugas_id,siswa_id,created_at,updated_at) $Qsiswa";
        $db->query($sql);
        $db->transComplete();
        if ($db->transStatus() === FALSE) return $this->fail(["csrf" => csrf_hash(), 'message' => 'Gagal Menambah Tugas']);
        if ($data['is_active'] == 1) {
            $audience = db_connect()->table('m_siswa ms')->select("GROUP_CONCAT(MD5(CONCAT('m',ms.id))) uid")->where('ms.kelas_id', $isExist['kelas_id'])->groupBy('ms.kelas_id')->get()->getRowArray();
            if ($audience) {
                $text = "Tugas \"$data[judul]\" telah ditambahkan, batas tugas sampai dengan $data[dueDate]";
                $heading = "Tugas Baru Telah Ditambahkan";
                $notif['contents'] = [
                    "en" => $text, "id" => $text,
                ];
                $notif['headings'] = [
                    "en" => $heading, "id" => $heading,
                ];
                $notif['url'] = base_url('kelas/materi/' . $jadwalID);
                $notif['channel_for_external_user_ids'] = "push";
                $notif['include_external_user_ids'] = explode(',', $audience['uid']);
                sendOneSignal($notif);
            }
        }
        return $this->respond(["csrf" => csrf_hash(), 'message' => 'Berhasil Menambah Tugas']);
    }
    public function save($jadwalID)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $isExist = $this->JModel->getJadwalMengajar(base64_decode($jadwalID));
        if (!$isExist) return $this->failNotFound();
        $ct = $this->request->getVar('ct');
        $nt = $this->request->getVar('nt');
        if ($ct === null) return $this->fail(["csrf" => csrf_hash(), 'message' => "Current Tugas dibutuhkan"]);
        if ($nt === null) return $this->fail(["csrf" => csrf_hash(), 'message' => "New Tugas dibutuhkan"]);
        $db = db_connect();
        $db->transStart();
        if ($nt) {
            $sql = "INSERT INTO jadwal_tugas(jadwal_id,kompetensi_id,judul,deskripsi,file,is_active,dueDate) SELECT $isExist[id] jadwal_id,kompetensi_id,judul,deskripsi,file,is_active,dueDate FROM jadwal_tugas WHERE id IN(" . implode(',', $nt) . ") AND jadwal_id != $isExist[id]";
            $db->query($sql);
            if ($db->affectedRows()) {
                $index = $db->insertID();
                for ($i = $index; $i < $index + count($nt); $i++) {
                    $SQsiswa = $db->table('tugas_siswa ts')->select('ts.siswa_id')->where('ts.siswa_id', 'ms.id', false)->where('tugas_id', $i)->getCompiledSelect();
                    $Qsiswa = $db->table('m_siswa ms')->select("$i tugas_id,ms.id")->where('kelas_id', $isExist['kelas_id'])->where("(CASE WHEN NOT EXISTS ($SQsiswa) THEN 0 ELSE 1 END) =", 0, false)->getCompiledSelect();
                    $sql = "INSERT INTO tugas_siswa(tugas_id,siswa_id) $Qsiswa";
                    $db->query($sql);
                    $ct[] = $i;
                }
            }
        }
        if ($ct) $db->table('jadwal_tugas')->whereNotIn('id', $ct)->where('jadwal_id', $isExist['id'])->delete();
        if (!$ct) $db->table('jadwal_tugas')->where('jadwal_id', $isExist['id'])->delete();
        $db->transComplete();
        if ($db->transStatus() === FALSE) {
            return $this->fail(["csrf" => csrf_hash(), 'message' => 'Gagal Menyimpan']);
        }
        return $this->respond(['csrf' => csrf_hash(), 'message' => 'Berhasil Menyimpan']);
    }
    public function related($jadwalID)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $isExist = $this->JModel->getJadwalMengajar(base64_decode($jadwalID));
        if (!$isExist) return $this->failNotFound();
        return $this->respond(['tugas' => $this->JMTModel->related($isExist['id']), 'csrf' => ['name' => csrf_token(), 'value' => csrf_hash()], 'kode_mapel' => $isExist['kode_mapel'], 'nama_kelas' => $isExist['nama_kelas']]);
    }
    public function imageUploader()
    {
        $app = config('app');
        $img = $this->request->getFile('file');
        $allowed_mime = ['image/png', 'image/jpg', 'image/jpeg'];
        if (!$img->isValid()) return $this->failForbidden();
        if (!in_array($img->getClientMimeType(), $allowed_mime)) $this->failForbidden();
        if ($img->hasMoved()) return $this->failNotFound();
        $imgName = $img->getRandomName();

        if ($img->getSize() > 10000) {
            compress_image($img->getTempName(), FCPATH . "$app->imgPath/elearning/tugas/$imgName");
        } else {
            $img->move(FCPATH . "$app->imgPath/elearning/tugas", $imgName);
        }
        rmbfe('php', FCPATH . "$app->imgPath/elearning/tugas");
        return $this->respond(['location' => base_url("$app->imgPath/elearning/tugas/$imgName")]);
    }
}
