<?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\Materi as JadwalMengajarMateri;
use CodeIgniter\API\ResponseTrait;

class Materi extends BC
{
    use ResponseTrait;
    private $JModel, $JMMModel;
    private $allowed_mime = [
        'application/msword',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        'application/vnd.ms-excel',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'application/vnd.ms-powerpoint',
        'application/vnd.openxmlformats-officedocument.presentationml.presentation',
        'application/pdf',
        'application/zip',
        'application/x-rar-compressed',
        'application/x-7z-compressed',
        'application/x-tar',
        'application/x-bzip',
        'application/x-bzip2',
        'application/x-gzip',
        'application/x-compressed',
        'application/x-zip-compressed',
        'application/x-zip',
        'application/x-rar'
    ];
    public function __construct()
    {
        parent::__construct();
        $this->JModel = new Jadwal();
        $this->JMMModel = new JadwalMengajarMateri();
    }
    public function index($jadwalID)
    {
        $isExist = $this->JModel->getJadwalMengajar(base64_decode($jadwalID));
        if (!$isExist) return view("Utils/404");
        return view('Panel/Elearning/JadwalMengajar/materi', ['page_title' => "Materi - $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();
        return $this->respond(['materi' => $this->JMMModel->getAllByTahunKelas($isExist['id'], $isExist['tahun_id'], $isExist['kelas_id']), 'csrf' => ['name' => csrf_token(), 'value' => csrf_hash()], 'kode_mapel' => $isExist['kode_mapel'], 'nama_kelas' => $isExist['nama_kelas']]);
    }
    public function viewed($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();
        $data = $this->JMMModel->getViewedMateriByTahunKelas($isExist['id'], $isExist['tahun_id'], $isExist['kelas_id'], strtotime('-1 day'), time());
        return $this->respond($data);
    }
    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(['materi' => $this->JMMModel->related($isExist['id']), '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->JMMModel->getMateri($id));
    }
    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->JMMModel->delete($id);
        return $this->respond(['deleted' => $state, 'message' => $state ? "Berhasil Menghapus" : "Gagal Menghapus"]);
    }
    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();
        $cm = $this->request->getVar('cm');
        $nm = $this->request->getVar('nm');
        if ($cm === null) return $this->fail(["csrf" => csrf_hash(), 'message' => "Current Materi dibutuhkan"]);
        if ($nm === null) return $this->fail(["csrf" => csrf_hash(), 'message' => "New Materi dibutuhkan"]);
        $db = db_connect();
        $db->transStart();
        if ($nm) {
            $sql = "INSERT INTO jadwal_materi(jadwal_id,kompetensi_id,judul,is_active,isi,file) SELECT $isExist[id] jadwal_id,kompetensi_id,judul,is_active,isi,file FROM jadwal_materi WHERE id IN(" . implode(',', $nm) . ") AND jadwal_id != $isExist[id]";
            $db->query($sql);
            if ($db->affectedRows()) {
                $index = $db->insertID();
                for ($i = $index; $i < $index + count($nm); $i++) {
                    $cm[] = $i;
                }
            }
        }
        if ($cm) $db->table('jadwal_materi')->whereNotIn('id', $cm)->where('jadwal_id', $isExist['id'])->delete();
        if (!$cm) $db->table('jadwal_materi')->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 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();
        $file = $this->request->getFile('file');

        $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['judul'] = [
            "alias" => "Judul",
            'rules' => 'string|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'),
            "kompetensi_id" => $this->request->getVar('kompetensi_id'),
            "is_active" => $this->request->getVar('is_active'),
            "isi" => $this->request->getVar('isi'),
        ];
        try {
            if ($file) {
                if ($file->isValid()) {
                    if (!in_array($file->getMimeType(), $this->allowed_mime)) return $this->fail(["csrf" => csrf_hash(), 'message' => "Berkas tidak di izinkan"]);
                    $name = $file->getRandomName();
                    $path = FCPATH . "assets/other/materi";
                    if (!file_exists($path)) {
                        mkdir($path, 0777, true);
                    }
                    if ($file->move($path, $name)) $data['file'] = $name;
                    rmbfe('php', $path);
                }
            }
        } 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->JMMModel->update($id, $data);
        if (!$updated) return $this->fail(["csrf" => csrf_hash(), 'message' => 'Gagal Mengubah Materi']);
        return $this->respond(["csrf" => csrf_hash(), 'message' => 'Berhasil Mengubah Materi']);
    }
    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();
        $file = $this->request->getFile('file');

        $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['judul'] = [
            "alias" => "Judul",
            'rules' => 'string|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 = [
            "jadwal_id" => base64_decode($jadwalID),
            "judul" => $this->request->getVar('judul'),
            "kompetensi_id" => $this->request->getVar('kompetensi_id'),
            "is_active" => $this->request->getVar('is_active'),
            "isi" => $this->request->getVar('isi'),
        ];
        try {
            if ($file) {
                if ($file->isValid()) {
                    if (!in_array($file->getMimeType(), $this->allowed_mime)) return $this->fail(["csrf" => csrf_hash(), 'message' => "Berkas tidak di izinkan"]);
                    $name = $file->getRandomName();
                    $path = FCPATH . "assets/other/materi";
                    if (!file_exists($path)) {
                        mkdir($path, 0777, true);
                    }
                    if ($file->move($path, $name)) $data['file'] = $name;
                    rmbfe('php', $path);
                }
            }
        } 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);
        $id = $this->JMMModel->insert($data);
        if (!$id) return $this->fail(["csrf" => csrf_hash(), 'message' => 'Gagal Menambah Materi']);
        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 = "Materi \"$data[judul]\" telah ditambahkan, segera lihat agar tidak tertinggal";
                $heading = "Materi 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 Materi']);
    }

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

    public function audioUploader()
    {
        $app = config('app');
        $audio = $this->request->getFile('audio');
        $allowed_mime = ['audio/mpeg'];
        if (!$audio->isValid()) return $this->failForbidden();
        if (!in_array($audio->getClientMimeType(), $allowed_mime)) $this->failForbidden();
        if ($audio->hasMoved()) return $this->failNotFound();
        $audioName = $audio->getRandomName();
        $materiPath = "$app->audioPath/elearning/materi";
        $audio->move(FCPATH . $materiPath, $audioName);
        rmbfe('php', FCPATH . $materiPath);
        return $this->respond(['location' => base_url("$materiPath/$audioName")]);
    }
    public function videoUploader()
    {
        set_time_limit(0);
        $app = config('app');
        $video = $this->request->getFile('video');
        $allowed_mime = [
            'video/x-flv', 'video/mp4', 'application/x-mpegURL',
            'video/MP2T', 'video/3gpp', 'video/quicktime',
            'video/x-msvideo', 'video/x-ms-wmv'
        ];
        if (!$video->isValid()) return $this->failForbidden();
        if (!in_array($video->getClientMimeType(), $allowed_mime)) $this->failForbidden();
        if ($video->hasMoved()) return $this->failNotFound();
        $videoName = $video->getRandomName();
        $materiPath = "$app->videoPath/elearning/materi";
        $video->move(FCPATH . $materiPath, $videoName);
        rmbfe('php', FCPATH . $materiPath);
        return $this->respond(['location' => base_url("$materiPath/$videoName")]);
    }
}
