<?php

namespace brain\data;

use Carbon\Carbon;
use brain\utility\DocTools;
use brain\utility\StringTools;

use function _\find;
use function _\filter;

class Book
{
    public function __construct()
    {
    }

    public function findPageById(string $uuid)
    {
        $content = $this->getContents();
        $page    = find($content, ['uuid' => $uuid]);

        return $page;
    }

    public function findPageBySlug(string $slug = null)
    {
        $content = $this->getContents();
        if (isset($slug)) {
            $page = find($content, ['slug' => $slug]);
        } else {
            $page = find($content, ['layout' => 'index']);
        }

        return $page;
    }

    public function editPage($task, $request)
    {
        $content = $this->getContents();
        $body    = json_decode(file_get_contents("php://input"), true);
        //$body = find($content, ["uuid" => $parsed["id"]]);

        $page  = find($content, ['uuid' => $body['uuid']]);
        $files = $request->getUploadedFiles();

        $member = Session::get('member');

        if ($task != 'create') {
            $path = date('Y', date($page['rawCreated'])) .
            '/' .
            date('m', date($page['rawCreated']));
        } else {
            $path = date('Y') . '/' . date('m');
        }

        $page_feature = '';
        $page_files   = '';

        if ($task == 'delete') {
            $deleted           = 'true';
            $body['menu']      = 'false';
            $body['published'] = 'false';
            $body['featured']  = 'false';
        } else {
            $deleted = isset($page['deleted']) ? $page['deleted'] : 'false';
        }

        $created = $task != 'create' ? new Carbon($page['rawCreated']) : Carbon::now();
        $updated = Carbon::now();

        // grab current index from settings and update
        $id   = $task != 'create' ? $body['id'] : Settings::getCurrentIndex();
        $uuid = $task != 'create' ? $body['uuid'] : StringTools::createUUID();
        // now that variables are done, set to body object and then convert to markdown to save

        $body['id']   = $id;
        $body['uuid'] = $uuid;
        //$body['feature'] = $page_feature;
        //$body['files']   = $page_files;
        $body['path']    = $path;
        $body['author']  = $member['handle'];
        $body['created'] = $created->format("Y-m-d\TH:i:sP");
        $body['updated'] = $updated->format("Y-m-d\TH:i:sP");
        $body['deleted'] = $deleted;

        $write = DocTools::objectToMD($body);

        // if layout is index, change path to file

        if ($body['layout'] == 'index') {
            $writePath = '../content/pages/start/index.md';
        } else {
            $writePath = '../content/pages/' . $path . '/' . $body['slug'] . '.md';
        }

        $status = DocTools::writePages($task, $path, $writePath, $write);

        if ($status) {
            $config   = new Settings();
            $settings = $config->getSettings();
            $message  = '';

            if (
                $settings['global']['renderOnSave'] == 'true' &&
                $settings['global']['dynamicRender'] == 'false'
            ) {
                $render = new Render();
                $render->renderTags();
                $render->renderArchive();
                $render->renderPages();
                $message = 'Filed edited and rendered. NOICE.';
            } else {
                $message = 'File edited. Nice work';
            }

            $response = [
                'message' => $message,
                'type'    => $task == 'write' ? 'postUpdated' : 'postAdded',
                'id'      => $uuid,
            ];

            // TODO: When form submission is successful, make new form token
            // Session token doesn't reset on the front end, so turning this off for now
            // $form_token = md5(uniqid(microtime(), true));
            // Session::set("form_token", $form_token);

            // once saved, update menu
            $body['path'] = $path;
            Settings::updateMenu($body);
            Settings::updateTags();
            // if new page added, update current index in Settings file
            if ($task == 'create') {
                Settings::updateIndex();
            }
        } else {
            $response = [
                'message' => "Uh oh. File save problem. Don't panic",
                'type'    => 'postError',
                'id'      => $uuid,
            ];
        }

        return $response;
    }

    public function getPages(int $page, int $limit, string $sort = null)
    {
        $content = $this->getContents();

        $published = filter($content, function ($item) {
            return $item['published'] == true && $item['deleted'] == false;
        });
        $deleted = filter($content, function ($item) {
            return $item['deleted'] == true;
        });

        // $all = $content;
        $all = filter($content, function ($item) {
            return $item['deleted'] == false;
        });
        $filter = isset($sort) ? $sort : 'all';
        switch ($filter) {
            case 'published':
                $filtered = $published;
                break;
            case 'deleted':
                $filtered = $deleted;
                break;
            default:
                $filtered = $all;
                break;
        }
        $numOfPages = ceil(count($filtered) / ($limit + 1));
        $folder     = [];

        if (count($filtered) != 0) {
            if (count($filtered) < $limit) {
                $limit = count($filtered) - 1;
            }
            $range = $page * $limit - $limit;

            if ($range != 0) {
                $range = $range + 1;
            }
            for ($i = 0; $i <= $limit; ++$i) {
                if (isset($filtered[$i + $range])) {
                    array_push($folder, $filtered[$i + $range]);
                } else {
                    // chill out
                }
            }
        }

        $prev = $page - 1;
        if ($prev <= 0) {
            $prev = $numOfPages;
        }

        $next = $page + 1;
        if ($next > $numOfPages) {
            $next = 1;
        }

        return [
            'pages'      => $folder,
            'numOfPages' => $numOfPages,
            'entryCount' => count($filtered),
            'paginate'   => [
                'sort'     => $sort,
                'nextPage' => $next,
                'prevPage' => $prev,
            ],
            'stats' => [
                'all'       => count($all),
                'published' => count($published),
                'deleted'   => count($deleted),
            ],
        ];
    }

    public function getContents()
    {
        // test new contents data class
        // $new = (new Contents("../content/pages"))->getAll();
        $contents = (new Contents('../content/pages'))->getAll();

        return $contents;
    }
}