<?php

use Acms\Services\Facades\Application as App;
use Acms\Services\Facades\Category;
use Acms\Services\Facades\Field as FieldFacade;

class ACMS_POST_Category_Insert extends ACMS_POST
{
    public function post()
    {
        $workflowData = null;
        $Category = $this->extract('category');
        $Category->setMethod('name', 'required');
        $Category->setMethod('name', 'maxlength', '255');
        $Category->setMethod('code', 'required');
        $Category->setMethod('code', 'maxlength', '255');
        $Category->setMethod('code', 'double', [$Category->get('scope'),  $Category->get('parent')]);
        $Category->setMethod('code', 'reserved', !isReserved($Category->get('code')));
        if ($Category->get('code') !== '') {
            $Category->setMethod('code', 'string', isValidCode($Category->get('code')));
        }
        $Category->setMethod('status', 'required');
        $Category->setMethod('status', 'in', ['open', 'close', 'secret']);
        // Insert では「親が非公開なら親の status に自動コーリス」する設計のため、
        // 親非公開時の公開指定をエラー扱いせず常に true を返す。
        // テンプレート側の `validator-result-{status:validator#status}` プレースホルダを
        // 確実に埋めるためにも、明示的に登録しておく必要がある。
        $Category->setMethod('status', 'status', true);
        $Category->setMethod('scope', 'required');
        $Category->setMethod('indexing', 'required');
        $Category->setMethod('indexing', 'in', ['on', 'off']);
        $Category->setMethod('config_set_id', 'value', $this->checkConfigSetScope($Category->get('config_set_id')));
        $Category->setMethod('config_set_scope', 'in', ['local', 'global']);
        $Category->setMethod('theme_set_id', 'value', $this->checkConfigSetScope($Category->get('theme_set_id')));
        $Category->setMethod('theme_set_scope', 'in', ['local', 'global']);
        $Category->setMethod('editor_set_id', 'value', $this->checkConfigSetScope($Category->get('editor_set_id')));
        $Category->setMethod('editor_set_scope', 'in', ['local', 'global']);
        $Category->setMethod('category', 'operable', Category::canCreate(BID));

        if (sessionWithEnterpriseAdministration()) {
            $workflowData = $this->extractWorkflow();
        }

        // parentを指定時に、scopeがparentと同じに設定されていなければinvalid
        $Category->setMethod(
            'scope',
            'tree',
            !($pid = $Category->get('parent')) ? true : $Category->get('scope') == ACMS_RAM::categoryScope($pid)
        );

        $Category->validate(new \Acms\Services\Validator\Category());
        $Field = $this->extract('field', new ACMS_Validator());

        if ($this->Post->isValidAll()) {
            /** @var \Acms\Services\Category\CategoryRepository $repository */
            $repository = App::make('category.repository');

            if ($row = $repository->findMaxRightCategoryInBlog(BID)) {
                $sort  = (int) $row['category_sort'] + 1;
                $left  = (int) $row['category_right'] + 1;
                $right = (int) $row['category_right'] + 2;
            } else {
                $sort  = 1;
                $left  = 1;
                $right = 2;
            }

            $categoryId = $repository->nextCategoryId();
            $code   = $Category->get('code');
            $name   = $Category->get('name');
            $parent = $Category->get('parent');

            $parentStatus = ACMS_RAM::categoryStatus($parent);
            if ($parentStatus !== null && $parentStatus !== '' && $parentStatus !== 'open') {
                $Category->set('status', $parentStatus);
            }

            $status = $Category->get('status');

            $configSetId = $Category->get('config_set_id') ?: null;
            $themeSetId = $Category->get('theme_set_id') ?: null;
            $editorSetId = $Category->get('editor_set_id') ?: null;

            if ($configSetId === null || $configSetId === '') {
                $Category->set('config_set_scope', 'local');
            }
            if ($themeSetId === null || $themeSetId === '') {
                 $Category->set('theme_set_scope', 'local');
            }
            if ($editorSetId === null || $editorSetId === '') {
                $Category->set('editor_set_scope', 'local');
            }

            $repository->insert([
                'category_id' => $categoryId,
                'category_parent' => 0,
                'category_sort' => $sort,
                'category_left' => $left,
                'category_right' => $right,
                'category_blog_id' => BID,
                'category_status' => $status,
                'category_name' => $name,
                'category_scope' => $Category->get('scope'),
                'category_indexing' => $Category->get('indexing'),
                'category_code' => $code,
                'category_config_set_id' => $configSetId,
                'category_config_set_scope' => $Category->get('config_set_scope', 'local'),
                'category_theme_set_id' => $themeSetId,
                'category_theme_set_scope' => $Category->get('theme_set_scope', 'local'),
                'category_editor_set_id' => $editorSetId,
                'category_editor_set_scope' => $Category->get('editor_set_scope', 'local'),
            ]);
            FieldFacade::save('cid', $categoryId, $Field);

            //----------
            // geometry
            $this->saveGeometry('cid', $categoryId, $this->extract('geometry'));

            //----------
            // workflow
            if ($workflowData !== null) {
                $this->saveWorkflow($workflowData, BID, $categoryId);
            }

            $repository->changeParent($categoryId, (int) $parent, BID);

            $Category->set('id', $categoryId);

            Fulltext::saveFulltext('cid', $categoryId, Fulltext::loadCategoryFulltext($categoryId));

            AcmsLogger::info('「' . $name . '」カテゴリーの作成をしました', [
                'status' => $status,
                'name' => $name,
                'scope' => $Category->get('scope'),
                'indexing' => $Category->get('indexing'),
                'code' => $code,
                'configSetId' => $configSetId,
                'themeSetId' => $themeSetId,
                'editorSetId' => $editorSetId,
                'field' => $Field,
            ]);

            $this->addMessage('カテゴリーを作成しました');

            // PRG: 作成したカテゴリーの編集画面へリダイレクトする（リロードによる二重登録を防ぐ）
            $this->redirect(acmsLink([
                'bid' => BID,
                'cid' => $categoryId,
                'admin' => 'category_edit',
                'query' => [],
            ]));
        } else {
            AcmsLogger::info('カテゴリーの作成に失敗しました', [
                'category' => $Category->_aryV,
                'field' => $Field->_aryV,
            ]);
        }

        return $this->Post;
    }
}
