<?php
declare(strict_types=1);

namespace Celena\Plugin\Shop\Admin;

use Celena\Core\Http\Request;
use Celena\Core\Http\Response;
use Celena\Core\Security\Auth;
use Celena\Core\Security\Csrf;
use Celena\Core\Template\Engine;
use Celena\Module\AdminBase\AdminController;
use Celena\Module\Settings\Options;
use Celena\Plugin\Shop\Support\ShopSettings;

/**
 * Настройки магазина — единая страница со вкладками. Хранит ключи в
 * celena_options через Options::set() с префиксом `shop.*`.
 *
 * Список полей описан в массиве `fieldset()` — он же используется и
 * для рендера формы (без дублирования). Чтобы добавить настройку:
 * добавь её сюда и в ShopSettings::DEFAULTS — этого достаточно.
 */
final class ShopSettingsAdminController extends AdminController
{
    private function tr(): \Celena\Core\I18n\Translator
    {
        return \Celena\Core\Kernel::container()->make(\Celena\Core\I18n\Translator::class);
    }

    public function __construct(
        Engine $engine,
        Auth $auth,
        Options $options,
    ) {
        parent::__construct($engine, $auth, $options);
    }

    public function index(Request $request): Response
    {
        if (!$this->auth->check()) return Response::redirect('/admin/login');

        $shop = new ShopSettings($this->options);
        $values = $shop->all();
        $tab = (string) $request->query('tab', 'general');
        $allowed = ['general', 'currency', 'catalog', 'orders', 'checkout', 'tax'];
        if (!in_array($tab, $allowed, true)) $tab = 'general';

        // Готовим поля текущего таба для рендера, подставляем текущие значения.
        $tabFields = $this->fieldset()[$tab] ?? [];
        $rendered = [];
        foreach ($tabFields as $f) {
            $f['short'] = substr($f['key'], 5);
            $f['value'] = $values[$f['key']] ?? '';
            $f['checked'] = ($f['type'] === 'checkbox') && in_array($f['value'], ['1','true','yes','on'], true);
            $rendered[] = $f;
        }

        $tabs = [
            ['key' => 'general',  'label' => 'Общие',    'icon' => 'settings'],
            ['key' => 'currency', 'label' => 'Валюта',   'icon' => 'tag'],
            ['key' => 'catalog',  'label' => 'Каталог',  'icon' => 'box'],
            ['key' => 'orders',   'label' => 'Заказы',   'icon' => 'cart'],
            ['key' => 'checkout', 'label' => 'Оформление', 'icon' => 'check'],
            ['key' => 'tax',      'label' => 'Налоги',   'icon' => 'chart'],
        ];

        return $this->view('plugins/shop/admin/settings', [
            'tab'     => $tab,
            'tabs'    => $tabs,
            'fields'  => $rendered,
            'values'  => $values,
            'preview' => $shop->formatPrice(12345.67),
        ], 'shop-settings', $this->tr()->translate('shop.settings.title'));
    }

    public function save(Request $request): Response
    {
        if (!$this->auth->check()) return Response::redirect('/admin/login');
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            return $this->redirect('/admin/shop/settings', $this->tr()->translate('shop.flash.csrf'), 'error');
        }

        $tab = (string) $request->input('tab', 'general');
        $allowed = ['general', 'currency', 'catalog', 'orders', 'checkout', 'tax'];
        if (!in_array($tab, $allowed, true)) $tab = 'general';

        // Сохраняем только поля текущего таба, чтобы не затирать чужие пустыми значениями.
        $fields = $this->fieldset()[$tab] ?? [];
        $posted = (array) $request->input('shop', []);

        foreach ($fields as $field) {
            $key = $field['key'];
            $short = substr($key, 5); // отрезаем 'shop.'
            if ($field['type'] === 'checkbox') {
                $value = isset($posted[$short]) ? '1' : '0';
            } else {
                $value = (string) ($posted[$short] ?? '');
                $value = mb_substr($value, 0, (int) ($field['max'] ?? 1000));
            }
            $this->options->set($key, $value);
        }

        return $this->redirect('/admin/shop/settings?tab=' . rawurlencode($tab), $this->tr()->translate('shop.flash.settings_saved'));
    }

    /** Декларативное описание полей по табам — рендер формы и сохранение читают отсюда. */
    public static function fieldset(): array
    {
        return [
            'general' => [
                ['key' => 'shop.store_name',    'type' => 'text',    'label' => 'Название магазина',    'max' => 255],
                ['key' => 'shop.contact_email', 'type' => 'email',   'label' => 'Email для связи',      'max' => 255],
                ['key' => 'shop.contact_phone', 'type' => 'text',    'label' => 'Телефон',              'max' => 64],
                ['key' => 'shop.address',       'type' => 'textarea','label' => 'Юридический адрес',    'max' => 500],
            ],
            'currency' => [
                ['key' => 'shop.currency_code',     'type' => 'text',   'label' => 'Код валюты (ISO 4217)', 'help' => 'USD, EUR, UAH, GBP, PLN…', 'max' => 8],
                ['key' => 'shop.currency_symbol',   'type' => 'text',   'label' => 'Символ',                'help' => '$, €, ₴, £, zł…',          'max' => 8],
                ['key' => 'shop.currency_position', 'type' => 'select', 'label' => 'Позиция символа', 'options' => [
                    ['value' => 'before', 'label' => 'Перед суммой ($ 100)'],
                    ['value' => 'after',  'label' => 'После суммы (100 ₴)'],
                ]],
                ['key' => 'shop.price_decimals',    'type' => 'number', 'label' => 'Знаков после запятой', 'help' => '0 для цен без копеек'],
                ['key' => 'shop.thousands_sep',     'type' => 'text',   'label' => 'Разделитель тысяч',    'help' => 'Пробел, запятая или точка', 'max' => 4],
                ['key' => 'shop.decimal_sep',       'type' => 'text',   'label' => 'Десятичный разделитель', 'max' => 4],
            ],
            'catalog' => [
                ['key' => 'shop.products_per_page', 'type' => 'number', 'label' => 'Товаров на странице каталога'],
                ['key' => 'shop.show_out_of_stock', 'type' => 'checkbox', 'label' => 'Показывать товары без остатка'],
                ['key' => 'shop.show_sku',          'type' => 'checkbox', 'label' => 'Показывать SKU на карточке'],
                ['key' => 'shop.show_rating',       'type' => 'checkbox', 'label' => 'Показывать рейтинг и отзывы'],
                ['key' => 'shop.allow_guest_checkout', 'type' => 'checkbox', 'label' => 'Разрешить заказы без регистрации'],
            ],
            'orders' => [
                ['key' => 'shop.order_number_prefix', 'type' => 'text',   'label' => 'Префикс номера заказа', 'help' => 'Пример: ORD-, KZ-, INV-', 'max' => 16],
                ['key' => 'shop.order_initial_status','type' => 'select', 'label' => 'Начальный статус нового заказа', 'options' => [
                    ['value' => 'new',     'label' => 'Новый'],
                    ['value' => 'pending', 'label' => 'Ожидает оплаты'],
                    ['value' => 'paid',    'label' => 'Оплачен'],
                ]],
                ['key' => 'shop.min_order_amount',    'type' => 'number', 'label' => 'Минимальная сумма заказа', 'help' => '0 — без ограничений'],
                ['key' => 'shop.notify_email',        'type' => 'email',  'label' => 'Email для уведомлений админу о новых заказах', 'max' => 255],
            ],
            'checkout' => [
                ['key' => 'shop.checkout_require_phone',   'type' => 'checkbox', 'label' => 'Телефон обязателен'],
                ['key' => 'shop.checkout_require_email',   'type' => 'checkbox', 'label' => 'Email обязателен'],
                ['key' => 'shop.checkout_require_address', 'type' => 'checkbox', 'label' => 'Адрес обязателен'],
                ['key' => 'shop.checkout_thank_text',      'type' => 'textarea', 'label' => 'Текст страницы «Спасибо за заказ»', 'max' => 2000],
            ],
            'tax' => [
                ['key' => 'shop.tax_enabled',  'type' => 'checkbox', 'label' => 'Учитывать налог в цене'],
                ['key' => 'shop.tax_rate',     'type' => 'number',   'label' => 'Ставка налога, %'],
                ['key' => 'shop.tax_included', 'type' => 'checkbox', 'label' => 'Цена уже включает налог'],
            ],
        ];
    }
}
