<?php

namespace App\Controllers\Wiki;

use App\Controllers\BaseController;
use App\Models\Wiki\WikiContentModel;
use App\Models\Wiki\WikiFileModel;
use App\Models\Wiki\WikiPageModel;
use App\Models\Wiki\WikiSectionModel;
use App\Models\Wiki\WikiSectionRoleModel;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\I18n\Time;
use Psr\Log\LoggerInterface;
use Throwable;

class WikiController extends BaseController
{
    protected WikiSectionModel $wikiSectionModel;
    protected WikiContentModel $wikiContentModel;
    protected WikiPageModel $wikiPageModel;
    protected WikiFileModel $wikiFileModel;
    protected WikiSectionRoleModel $wikiSectionRoleModel;


    protected string $locale;
    protected array $viewData;

    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
    {
        $this->wikiSectionModel = model(WikiSectionModel::class);
        $this->wikiPageModel = model(WikiPageModel::class);
        $this->wikiContentModel = model(WikiContentModel::class);
        $this->wikiFileModel = model(WikiFileModel::class);
        $this->wikiSectionRoleModel = model(WikiSectionRoleModel::class);

        $sections = $this->wikiSectionModel->sections();
        $this->locale = session()->get('lang');

        $this->viewData['wiki_sections'] = $sections;
        parent::initController($request, $response, $logger);
    }
    public function index()
    {
        return view('themes/vuexy/wiki/pages/render', $this->viewData);
    }
    public function show_page(string $slug)
    {

        $section = $this->wikiSectionModel->where('slug', $slug)->first();
        if($section){
            if(auth()->user()->inGroup(...$section->roles_array()) || auth()->user()->inGroup('admin')){
                $this->viewData['slug'] = $slug;
                $this->viewData['section'] = $section->withAll($this->locale);
                $this->viewData['breadcrumb'] = [
                    ['title' => $section->name->{$this->locale}, 'route' => route_to('showWikiPage', $slug), 'active' => true],
                ];
                return view('themes/vuexy/wiki/pages/render', $this->viewData);
            }else{
                return $this->response->setStatusCode(403);
            }
        }else{
            return redirect_to('/');
        }
    }
    public function get_section(int $section_id)
    {
        $section = $this->wikiSectionModel->find($section_id)->withAll($this->locale);
        if(auth()->user()->inGroup(...$section->roles_array()) || auth()->user()->inGroup('admin')){

            return $this->response->setJSON(["data" => $section, "message" => lang("App.global_alert_fetch_success")]);
        }else{
            return $this->response->setStatusCode(403);
        }
    }
    public function store_save_page(int $section_id)
    {
        $bodyData = $this->request->getPost();
        $wikiSectionPage = $this->wikiSectionModel->find($section_id)->page();
        if ($wikiSectionPage) {
            $wikiPageId = $wikiSectionPage->id;
        } else {
            $wikiPageId = $this->wikiPageModel->insert(['section_id' => $section_id]);
        }
        $content = $this->wikiContentModel->where('locale', $this->locale)->where('page_id', $wikiPageId)->countAllResults();
        if ($content > 0) {
            $this->wikiContentModel->where('locale', $this->locale)->where('page_id', $wikiPageId)->delete();
        }

        $this->wikiContentModel->insert([
            "locale" => $this->locale,
            "page_id" => $wikiPageId,
            "last_edit_by" => auth()->user()->id,
            "editor_data" => json_encode($bodyData)
        ]);
        return $this->response->setJSON(["data" => [], "message" => lang("App.global_alert_save_success")]);
    }
    public function store_publish_page(int $section_id)
    {
        $bodyData = $this->request->getPost();
        $wikiSectionPage = $this->wikiSectionModel->find($section_id)->page();
        if ($wikiSectionPage) {
            $wikiPageId = $wikiSectionPage->id;
            $wikiContentId = $this->wikiContentModel->where("page_id", $wikiPageId)->where('locale', $this->locale)->first()->id;
            $this->wikiContentModel->update($wikiContentId, [
                "published_by" => auth()->user()->id,
                "last_edit_by" => auth()->user()->id,
                "editor_data" => json_encode($bodyData),
                "published_data" => json_encode($bodyData),
                "published_at" => Time::now()->format('Y-m-d H:i:s'),

            ]);
            $response = $this->response->setJSON(["data" => [], "message" => lang("App.global_alert_save_success")]);
        } else {
            $response = $this->response->setStatusCode(400)->setJSON(["data" => [], "error" => lang('Wiki.errors.publish_before_save')]);
        }
        return $response;
    }
    public function wiki_file_upload(int $section_id)
    {
        try {
            $file = $this->request->getFile('image');
            $section = $this->wikiSectionModel->find($section_id);
            $content = $section->content();
            $r = null;
            $fullpath = null;
            if ($file->isValid() && !$file->hasMoved()) {
                $fullpath = $file->store('wiki_images/' . $section->slug);
                $r = $this->wikiFileModel->insert(["content_id" => $content->id, "path" => $fullpath]);
                return $this->response->setJSON(["success" => 1, "file" => [
                    "url" => '/wiki/file/' . $r
                ]]);
            } else {
                return $this->response->setJSON(["success" => 0, "file" => [
                    "url" => null
                ]]);
            }
        } catch (\Throwable $th) {

            return $this->response->setJSON(["success" => 0, "error" => $th->getMessage()])->setStatusCode(403);
        }
    }
    public function get_wiki_file(int $wiki_file_id)
    {
        $wikiFile = $this->wikiFileModel->find($wiki_file_id);
        if ($wikiFile->path) {
            $filePath = WRITEPATH . 'uploads/' . $wikiFile->path;
            $mimeType = mime_content_type($filePath);
            return $this->response
                ->setHeader('Content-Type', $mimeType)
                ->setHeader('Content-Length', filesize($filePath))
                ->setBody(file_get_contents($filePath));
        } else {
            return $this->response->setJSON(["success" => 0, "error" => lang('Wiki.file_dont_exist')])->setStatusCode(400);
        }
    }
    public function wiki_section_update_order()
    {
        try {
            $bodyData = $this->request->getPost();
            $orders = $bodyData['orders'];
            foreach ($orders as $key => $section_id) {
                $this->wikiSectionModel->update($section_id, ['order' => $key]);
            }
            return $this->response->setJSON(["status" => 1, "message" => lang('Wiki.order_success')]);
        } catch (\Throwable $th) {
            return $this->response->setJSON(["status" => 0, "message" => lang('Wiki.order_error')])->setStatusCode(400);
        }
    }
    public function store_section()
    {
        try {
            $bodyData = $this->request->getPost();
            $sectionName = $bodyData['name'];
            $roles = $bodyData['roles'];
            $bodyData["slug"] = implode('-', array_map(fn($e) => strtolower($e), explode(' ', $sectionName['es'])));
            $bodyData["order"] = $this->wikiSectionModel->selectMax('order')->first()->order + 1;
            $bodyData['name'] = json_encode($sectionName);
            $wikiSectionId = $this->wikiSectionModel->insert($bodyData);
            if(count($roles) > 0){
                foreach ($roles as $key => $role) {
                    $this->wikiSectionRoleModel->insert(['wiki_section_id' => $wikiSectionId , 'role' => $role]);
                }
            }
            return $this->response->setJSON(["status" => 1, "message" => lang('Wiki.section_new_success')]);
        } catch (\Throwable $th) {
            return $this->response->setJSON(["status" => 0, "message" => $th->getMessage()])->setStatusCode(400);
        }
    }
    public function update_section()
    {
        try {
            $bodyData = $this->request->getPost();
            $wikiSectionId = $bodyData['wiki_section_id'];
            $roles = $bodyData['roles'];
            $this->wikiSectionModel->update($wikiSectionId, [
                "name" => json_encode($bodyData['name']),
                "icon" => $bodyData['icon']
            ]);
            $this->wikiSectionRoleModel->where('wiki_section_id',$wikiSectionId)->delete();
            if(count($roles) > 0){
                foreach ($roles as $key => $role) {
                    $this->wikiSectionRoleModel->insert(['wiki_section_id' => $wikiSectionId , 'role' => $role]);
                }
            }
            return $this->response->setJSON(["status" => 1, "message" => lang('Wiki.section_edit_success')]);
        } catch (\Throwable $th) {
            return $this->response->setJSON(["status" => 0, "message" => $th->getMessage()])->setStatusCode(400);
        }
    }
    public function delete_section(int $section_id)
    {
        try{
            $this->wikiSectionModel->delete($section_id);
            return $this->response->setJSON(["status" => 1, "message" => lang('Wiki.section_delete_success')]);
        }catch(Throwable $th){
            return $this->response->setJSON(["status" => 0, "message" => $th->getMessage()])->setStatusCode(400);
        }
    }
}
