<?php

namespace App\Controllers\Panel\Conversations;

use App\Controllers\Panel\BC;
use App\Models\Panel\Conversations\Conversations;
use App\Models\Panel\Conversations\GroupConversations;
use CodeIgniter\API\ResponseTrait;

class Main extends BC
{
    use ResponseTrait;
    protected $limit = 10;
    private $GCM, $CM;
    public function __construct()
    {
        $this->GCM = new GroupConversations();
        $this->CM = new Conversations();
        parent::__construct();
    }
    public function config()
    {
        $data['active'] = options('chat');
        return $this->respond($data);
    }
    public function chat_list()
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $db = db_connect();
        $logo = logo();
        $bu = base_url(config('app')->imgPath . "/users");
        $get_person_name = $db->table('group_conversations_member sgcm');
        $get_person_name->select('su.fullname');
        $get_person_name->join('users su', 'sgcm.user_id = su.id');
        $get_person_name->where(['sgcm.user_id !=' => 'gcm.user_id', 'sgcm.gc_id' => 'gcm.gc_id'], null, false);
        $get_person_name->limit(1);
        $get_person_name = $get_person_name->getCompiledSelect();
        $get_person_id = $db->table('group_conversations_member sgcm');
        $get_person_id->select('su.id');
        $get_person_id->join('users su', 'sgcm.user_id = su.id');
        $get_person_id->where(['sgcm.user_id !=' => 'gcm.user_id', 'sgcm.gc_id' => 'gcm.gc_id'], null, false);
        $get_person_id->limit(1);
        $get_person_id = $get_person_id->getCompiledSelect();

        $get_person_photo = $db->table('group_conversations_member sgcm');
        $get_person_photo->select("CONCAT('$bu/',u.photo)", false);
        $get_person_photo->join('users u', 'sgcm.user_id = u.id');
        $get_person_photo->where(['sgcm.user_id !=' => 'gcm.user_id', 'sgcm.gc_id' => 'gcm.gc_id'], null, false);
        $get_person_photo->limit(1);
        $get_person_photo = $get_person_photo->getCompiledSelect();

        $get_member_name = $db->table('group_conversations_member sgcm');
        $get_member_name->select("GROUP_CONCAT(su.fullname)", false);
        $get_member_name->join('users su', 'sgcm.user_id = su.id');
        $get_member_name->where(['sgcm.user_id !=' => 'gcm.user_id', 'sgcm.gc_id' => 'gcm.gc_id'], null, false);
        $get_member_name = $get_member_name->getCompiledSelect();

        $get_last_message = $db->table('panel_conversations spc');
        $get_last_message->select('message');
        $get_last_message->where('spc.gc_id', 'gcm.gc_id', false);
        $get_last_message->orderBy('spc.updated_at', 'DESC');
        $get_last_message->limit(1);
        $get_last_message = $get_last_message->getCompiledSelect();
        $select = ["distinct gc.id,gc.group_type,gc.created_at,gc.updated_at"];
        $select[] = "CASE WHEN gc.group_type ='group' THEN ($get_member_name) ELSE NULL END member_name";
        $select[] = "CASE WHEN gc.group_type ='private' THEN ($get_person_id) ELSE NULL END user_id";
        $select[] = "CASE WHEN gc.group_type ='private' THEN ($get_person_name) ELSE gc.group_name END group_name";
        $select[] = "CASE WHEN gc.group_type ='private' THEN ($get_person_photo) ELSE '$logo' END group_photo";
        $select[] = "($get_last_message) message";
        $gc = $db->table("group_conversations gc");
        $gc->join('group_conversations_member gcm', 'gcm.gc_id=gc.id');
        $gc->where('gcm.user_id', user()->id);
        $gc->select(implode(",", $select), false);
        $gc->orderBy('gc.updated_at', 'DESC');
        $data = $gc->get()->getResultArray();
        return $this->respond(['conversations' => $data]);
    }

    public function users()
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $db = db_connect();
        $bu = base_url(config('app')->imgPath . "/users");
        $getRole = $db->table('users_roles sur');
        $getRole->select('GROUP_CONCAT(sr.name) as roles');
        $getRole->join('roles sr', 'sr.id = sur.role_id');
        $getRole->where('sur.user_id', 'u.id', false);
        $getRole = $getRole->getCompiledSelect();
        $users = $db->table('users u');
        $users->select("u.id,u.username,u.fullname,u.status,CONCAT('$bu/',u.photo) photo,($getRole) role");
        $users->where('u.id !=', user()->id);
        $users->where('u.status', 1);
        $users->orderBy('u.fullname', 'ASC');
        $users = $users->get()->getResultArray();
        return $this->respond(['users' => $users]);
    }


    public function init($gc_id)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $db = db_connect();
        $gc = $db->table("group_conversations gc");
        $gc->join('group_conversations_member gcm', 'gcm.gc_id=gc.id');
        $gc->where('gcm.user_id', user()->id);
        $gc->where('gc.id', base64_decode($gc_id));
        $gc->select("gc.id", false);
        $exist = $gc->get()->getRowArray();
        if (!$exist) return $this->failForbidden('You are not a member of any group conversation');
        $conversations = $this->GCM->getInitConvesations($exist['id'], $this->limit);
        return $this->respond(['conversations' => $conversations,]);
    }


    public function create()
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $users_id = $this->request->getVar('users_id');
        $rules['users_id'] = [
            "alias" => "Pengguna",
            'rules' => 'required|is_array',
            'errors' => [
                'is_array' => '{value} Karakter Tidak Valid',
                'required' => '{value} Guru Dibutuhkan'
            ]
        ];
        $rules['group_name'] = [
            "alias" => "Nama Group",
            'rules' => 'required|string',
            'errors' => [
                'is_array' => '{value} Karakter Tidak Valid',
                'required' => '{value} Guru 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]);
        }
        $db = db_connect();
        $users = $db->table('users')->select("GROUP_CONCAT(id) id,GROUP_CONCAT(fullname) fullname")->whereIn('id', $users_id)->get()->getRowArray();
        if (!$users) return $this->fail(['message' => "Pengguna tidak ditemukan"]);
        $users_id = explode(',', $users['id']);
        if (count($users_id) == 1) {
            $sgcm = $db->table('group_conversations_member sgcm')->select('sgcm.user_id')->where(['sgcm.gc_id' => 'gc.id', 'sgcm.user_id !=' => $users_id[0]], null, false)->limit(1)->getCompiledSelect();
            $exist = $db->table('group_conversations gc');
            $exist->select("gc.id,'$users[fullname]' group_name");
            $exist->join('group_conversations_member gcm', 'gcm.gc_id=gc.id');
            $exist->where(['gc.group_type' => 'private', 'gcm.user_id' => $users_id[0]]);
            $exist->where("($sgcm) =", user()->id);
            $exist->limit(1);
            $exist = $exist->get()->getRowArray();
            if ($exist) return $this->respond(['message' => 'Percakapan Sudah Dibuat', 'gc_id' => $exist['id'], 'group_name' => $exist['group_name']]);
        }
        $gc_id = $this->GCM->generateId();
        $group = [
            'id' => $gc_id,
            'group_type' => count($users_id) == 1 ? 'private' : 'group',
            'group_name' => count($users_id) == 1 ? $users->fullname : $this->request->getVar('group_name'),
            'created_at' => time(),
            'updated_at' => time(),
        ];
        $gcm = [
            [
                'id' => $this->GCM->generateId(),
                'gc_id' => $gc_id,
                'user_id' => user()->id,
                'created_at' => time(),
                'updated_at' => time(),
            ]
        ];
        foreach ($users_id as $uid) {
            $gcm[] = [
                'id' => $this->GCM->generateId(),
                'gc_id' => $gc_id,
                'user_id' => $uid,
                'created_at' => time(),
                'updated_at' => time(),
            ];
        }
        $db->transStart();
        if (!$db->table('group_conversations')->insert($group)) {
            $db->transRollback();
            return $this->fail(['message' => "Gagal membuat percakapan"]);
        }
        if (!$db->table('group_conversations_member')->insertBatch($gcm)) {
            $db->transRollback();
            return $this->fail(['message' => "Gagal membuat percakapan"]);
        }
        $db->transComplete();
        if ($db->transStatus() === FALSE) return $this->fail(['message' => "Gagal Membuat Percakapan"]);
        return $this->respond(['message' => 'Percakapan Berhasil Dibuat', 'gc_id' => $gc_id, 'group_name' => $group['group_name']]);
    }

    public function add($gc_id)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        $msg = $this->request->getVar('msg');
        if (!$msg) return $this->fail(['message' => 'Gagal']);
        if (!$this->GCM->isMember(user()->id, base64_decode($gc_id))) return $this->fail(['message' => 'Percakapan Tidak Ditemukan']);
        $result = $this->CM->add(base64_decode($gc_id), user()->id, base64ToImage($msg)['str']);
        if (!$result['status']) return $this->fail(['message' => $result['message']]);
        return $this->respond(['message' => "Berhasil menambahkan", 'id' => $result['id']]);
    }

    public function out($gc_id)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        if (!$this->GCM->isMember(user()->id, base64_decode($gc_id))) return $this->fail(['message' => 'Percakapan Tidak Ditemukan']);
        if (!$this->GCM->out(base64_decode($gc_id), user()->id)) return $this->fail(['message' => 'Gagal']);
        return $this->respond(['message' => 'Berhasil']);
    }

    public function newest($gc_id, $lid)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        if (!$this->GCM->isMember(user()->id, base64_decode($gc_id))) return $this->fail(['message' => 'Percakapan Tidak Ditemukan']);
        $conversations = $this->CM->getNewest(base64_decode($gc_id), user()->id, base64_decode($lid), $this->limit);
        return $this->respond(['conversations' => $conversations,]);
    }
    public function oldest($gc_id, $fid)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        if (!$this->GCM->isMember(user()->id, base64_decode($gc_id))) return $this->fail(['message' => 'Percakapan Tidak Ditemukan']);
        $conversations = $this->CM->getOldest(base64_decode($gc_id), user()->id, base64_decode($fid), $this->limit);
        return $this->respond(['conversations' => $conversations]);
    }
    public function delete($gc_id, $chat_id)
    {
        if (!$this->request->isAJAX() && ENVIRONMENT != 'development') {
            exit('No direct script access allowed');
        }
        if (!$this->GCM->isMember(user()->id, base64_decode($gc_id))) return $this->fail(['message' => 'Percakapan Tidak Ditemukan']);
        if (!$this->CM->delete(base64_decode($chat_id))) return $this->fail(['message' => 'Gagal menghapus']);
        return $this->respond(['message' => "Berhasil dihapus"]);
    }
    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();
        $discPath = "$app->imgPath/elearning/diskusi";
        compress_image($img->getTempName(), FCPATH . "$discPath/$imgName");
        rmbfe('php', FCPATH . $discPath);
        return $this->respond(['location' => base_url("$discPath/$imgName")]);
    }
}
