<?php
declare(strict_types=1);

namespace Celena\Plugin\Shop\Admin;

use Celena\Core\Database\Connection;
use Celena\Core\Http\Pagination;
use Celena\Core\Http\Request;
use Celena\Core\Http\Response;
use Celena\Core\Security\Auth;
use Celena\Core\Security\Csrf;
use Celena\Core\Security\Filter;
use Celena\Core\Template\Engine;
use Celena\Module\AdminBase\AdminController;
use Celena\Module\Settings\Options;

final class ManufacturersAdminController 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,
        private readonly Connection $conn,
    ) {
        parent::__construct($engine, $auth, $options);
    }

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

        $page = Filter::int($request->query('page', 1), 1);
        $search = trim((string) $request->query('q', ''));

        $countQ = $this->conn->builder('shop_manufacturers');
        $listQ  = $this->conn->builder('shop_manufacturers');
        if ($search !== '') {
            $like = '%' . mb_strtolower($search, 'UTF-8') . '%';
            $countQ->whereRaw('LOWER(' . $this->conn->quoteId('title') . ') LIKE ?', [$like]);
            $listQ->whereRaw('LOWER(' . $this->conn->quoteId('title') . ') LIKE ?', [$like]);
        }
        $total = $countQ->count();
        $p = new Pagination($page, 25, $total);

        $rows = $listQ
            ->orderBy('sort_order', 'asc')
            ->orderBy('title', 'asc')
            ->limit($p->perPage)->offset($p->offset)
            ->get();

        // Кол-во товаров у каждого производителя.
        foreach ($rows as &$r) {
            $r['products_count'] = $this->conn->builder('shop_products')
                ->where('manufacturer_id', '=', (int) $r['id'])->count();
        }
        unset($r);

        return $this->view('plugins/shop/admin/manufacturers_index', [
            'manufacturers' => $rows,
            'pagination'    => $p->toArray('/admin/shop/manufacturers?page=:page' . ($search !== '' ? '&q=' . rawurlencode($search) : '')),
            'q'             => $search,
            'total'         => $total,
        ], 'shop-manufacturers', $this->tr()->translate('shop.manufacturers_list.title'));
    }

    public function create(Request $request): Response
    {
        if (!$this->auth->check()) return Response::redirect('/admin/login');
        return $this->view('plugins/shop/admin/manufacturers_form', [
            'row' => $this->emptyRow(),
            'form_action' => '/admin/shop/manufacturers/create',
        ], 'shop-manufacturers', $this->tr()->translate('shop.manufacturers_list.new'));
    }

    public function store(Request $request): Response
    {
        if (!$this->auth->check()) return Response::redirect('/admin/login');
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            return $this->redirect('/admin/shop/manufacturers/create', $this->tr()->translate('shop.flash.csrf'), 'error');
        }
        $data = $this->extract($request);
        if ($data['title'] === '') {
            return $this->redirect('/admin/shop/manufacturers/create', $this->tr()->translate('shop.flash.title_required'), 'error');
        }
        if ($data['slug'] === '') $data['slug'] = Filter::slug($data['title']);
        if ($this->slugExists($data['slug'])) {
            return $this->redirect('/admin/shop/manufacturers/create', $this->tr()->translate('shop.flash.slug_taken_already'), 'error');
        }
        $now = date('Y-m-d H:i:s');
        $data['created_at'] = $now;
        $data['updated_at'] = $now;
        $this->conn->builder('shop_manufacturers')->insert($data);
        return $this->redirect('/admin/shop/manufacturers', $this->tr()->translate('shop.flash.manufacturer_added'));
    }

    public function edit(Request $request, array $params): Response
    {
        if (!$this->auth->check()) return Response::redirect('/admin/login');
        $id = Filter::int($params['id'] ?? 0);
        $row = $this->conn->builder('shop_manufacturers')->where('id', '=', $id)->first();
        if ($row === null) return $this->redirect('/admin/shop/manufacturers', $this->tr()->translate('shop.flash.not_found'), 'error');
        return $this->view('plugins/shop/admin/manufacturers_form', [
            'row' => $row,
            'form_action' => '/admin/shop/manufacturers/' . $id . '/update',
        ], 'shop-manufacturers', 'Производитель: ' . $row['title']);
    }

    public function update(Request $request, array $params): Response
    {
        if (!$this->auth->check()) return Response::redirect('/admin/login');
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            return $this->redirect('/admin/shop/manufacturers', $this->tr()->translate('shop.flash.csrf'), 'error');
        }
        $id = Filter::int($params['id'] ?? 0);
        $existing = $this->conn->builder('shop_manufacturers')->where('id', '=', $id)->first();
        if ($existing === null) return $this->redirect('/admin/shop/manufacturers', $this->tr()->translate('shop.flash.not_found'), 'error');
        $data = $this->extract($request);
        if ($data['slug'] === '') $data['slug'] = Filter::slug($data['title']);
        if ($data['slug'] !== $existing['slug'] && $this->slugExists($data['slug'])) {
            return $this->redirect('/admin/shop/manufacturers/' . $id . '/edit', $this->tr()->translate('shop.flash.slug_taken'), 'error');
        }
        $data['updated_at'] = date('Y-m-d H:i:s');
        $this->conn->builder('shop_manufacturers')->where('id', '=', $id)->update($data);
        return $this->redirect('/admin/shop/manufacturers', $this->tr()->translate('shop.flash.saved'));
    }

    public function delete(Request $request, array $params): Response
    {
        if (!$this->auth->check()) return Response::redirect('/admin/login');
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            return $this->redirect('/admin/shop/manufacturers', $this->tr()->translate('shop.flash.csrf'), 'error');
        }
        $id = Filter::int($params['id'] ?? 0);
        // Отвязываем товары — не удаляем их.
        $this->conn->builder('shop_products')
            ->where('manufacturer_id', '=', $id)
            ->update(['manufacturer_id' => null]);
        $this->conn->builder('shop_manufacturers')->where('id', '=', $id)->delete();
        return $this->redirect('/admin/shop/manufacturers', $this->tr()->translate('shop.flash.deleted'));
    }

    private function emptyRow(): array
    {
        return [
            'id' => 0, 'slug' => '', 'title' => '', 'logo' => '', 'description' => '',
            'country' => '', 'website' => '', 'sort_order' => 0, 'is_active' => true,
        ];
    }

    private function extract(Request $request): array
    {
        return [
            'title'       => Filter::string($request->input('title'), 255),
            'slug'        => Filter::urlSlug($request->input('slug', '')),
            'logo'        => Filter::string($request->input('logo'), 500),
            'description' => Filter::string($request->input('description'), 5000),
            'country'     => Filter::string($request->input('country'), 100),
            'website'     => Filter::string($request->input('website'), 255),
            'sort_order'  => Filter::int($request->input('sort_order'), 0),
            'is_active'   => Filter::bool($request->input('is_active')),
        ];
    }

    private function slugExists(string $slug): bool
    {
        return $this->conn->builder('shop_manufacturers')->where('slug', '=', $slug)->first() !== null;
    }
}
