<?php

use Acms\Services\Category\CategoryRepository;
use Acms\Services\Facades\Application as App;
use Acms\Services\Facades\Category;

class ACMS_POST_Category_Index_Status extends ACMS_POST
{
    public function post()
    {
        $categoryIds = array_map('intval', $this->Post->getArray('checks'));
        $status = $this->Post->get('status');

        $this->Post->reset(true);
        $this->Post->setMethod('category', 'operable', (
            Category::canUpdate(BID)
            && count($categoryIds) > 0
            && in_array($status, ['open', 'close', 'secret'], true)
        ));
        $this->Post->validate();

        if ($this->Post->isValidAll()) {
            /** @var CategoryRepository $repository */
            $repository = App::make('category.repository');
            $blogId = BID;
            $processedIds = [];

            while (($categoryId = (int) array_shift($categoryIds)) > 0) {
                if ($status !== '' && $status !== 'open') {
                    $descendantIds = $repository->findDescendantIdsInclusive($categoryId, $blogId);
                    if (count($descendantIds) > 0) {
                        // 同一ツリーに含まれる ID はキューから除外（重複処理回避）
                        foreach ($descendantIds as $coveredId) {
                            $key = array_search($coveredId, $categoryIds, true);
                            if ($key !== false) {
                                unset($categoryIds[$key]);
                            }
                        }
                        $repository->updateStatusBulk($descendantIds, $status);
                    }
                } else {
                    // open に戻すときは祖先に close がないことを確認
                    if ($repository->hasClosedAncestor($categoryId, $blogId)) {
                        continue;
                    }
                    $repository->update($categoryId, ['category_status' => $status]);
                }
                $processedIds[] = $categoryId;
            }
            $label = $status;
            if ($status === 'open') {
                $label = '公開';
            }
            if ($status === 'close') {
                $label = '非公開';
            }
            if ($status === 'secret') {
                $label = 'シークレット';
            }
            AcmsLogger::info('指定されたカテゴリーのステータスを「' . $label . '」に変更', [
                'targetCIDs' => implode(',', $processedIds),
            ]);
        }
        Cache::flush('temp');

        return $this->Post;
    }
}
