<?php
declare(strict_types=1);

namespace Celena\Plugin\Analytics\Admin;

use Celena\Core\Database\Connection;
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;
use Celena\Plugin\Analytics\Support\GoalsRepo;

/**
 * CRUD настраиваемых целей аналитики: /admin/analytics/goals
 * Маршруты вне группы AuthMiddleware — авторизацию проверяем явно.
 */
final class GoalsAdminController extends AdminController
{
    private GoalsRepo $repo;

    public function __construct(Engine $engine, Auth $auth, Options $options, private readonly Connection $conn)
    {
        parent::__construct($engine, $auth, $options);
        $this->repo = new GoalsRepo($conn);
    }

    public function index(Request $request): Response
    {
        if ($this->auth->user() === null) {
            return Response::redirect('/admin/login');
        }
        return $this->view('plugins/analytics/admin/goals', [
            'goals'     => $this->decorate($this->repo->all()),
            'is_empty'  => $this->repo->all() === [] ? '1' : '',
        ], 'analytics-goals', 'Цели аналитики');
    }

    public function create(Request $request): Response
    {
        if ($this->auth->user() === null) {
            return Response::redirect('/admin/login');
        }
        return $this->form([
            'id' => 0, 'name' => '', 'type' => 'selector_click', 'match_value' => '',
            'value_eur' => '0', 'active' => 1, 'sort_order' => 0,
        ], 'Новая цель', '/admin/analytics/goals/store');
    }

    public function edit(Request $request, array $params): Response
    {
        if ($this->auth->user() === null) {
            return Response::redirect('/admin/login');
        }
        $g = $this->repo->find(Filter::int($params['id'] ?? 0));
        if ($g === null) {
            return $this->redirect('/admin/analytics/goals', 'Цель не найдена.', 'error');
        }
        return $this->form($g, 'Цель: ' . (string) $g['name'], '/admin/analytics/goals/' . (int) $g['id'] . '/update');
    }

    public function store(Request $request): Response
    {
        if ($this->auth->user() === null) {
            return Response::redirect('/admin/login');
        }
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            return $this->redirect('/admin/analytics/goals', 'CSRF.', 'error');
        }
        $data = $this->extract($request);
        if ($data['name'] === '') {
            return $this->redirect('/admin/analytics/goals/create', 'Укажите название цели.', 'error');
        }
        $data['slug'] = $this->repo->uniqueSlug(Filter::slug($data['name']));
        $data['created_at'] = date('Y-m-d H:i:s');
        $this->repo->create($data);
        return $this->redirect('/admin/analytics/goals', 'Цель создана.');
    }

    public function update(Request $request, array $params): Response
    {
        if ($this->auth->user() === null) {
            return Response::redirect('/admin/login');
        }
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            return $this->redirect('/admin/analytics/goals', 'CSRF.', 'error');
        }
        $id = Filter::int($params['id'] ?? 0);
        if ($this->repo->find($id) === null) {
            return $this->redirect('/admin/analytics/goals', 'Цель не найдена.', 'error');
        }
        $data = $this->extract($request);
        // slug не меняем при переименовании — историческая привязка событий сохраняется.
        $this->repo->update($id, $data);
        return $this->redirect('/admin/analytics/goals', 'Цель обновлена.');
    }

    public function delete(Request $request, array $params): Response
    {
        if ($this->auth->user() === null) {
            return Response::redirect('/admin/login');
        }
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            return $this->redirect('/admin/analytics/goals', 'CSRF.', 'error');
        }
        $this->repo->delete(Filter::int($params['id'] ?? 0));
        return $this->redirect('/admin/analytics/goals', 'Цель удалена. Накопленные события сохранены.');
    }

    /** @return array<string, mixed> */
    private function extract(Request $request): array
    {
        $type = Filter::in($request->input('type'), GoalsRepo::TYPES, 'selector_click');
        $val = (float) str_replace(',', '.', (string) $request->input('value_eur', '0'));
        return [
            'name'        => Filter::string($request->input('name'), 120),
            'type'        => $type,
            'match_value' => Filter::string($request->input('match_value'), 255),
            'value_eur'   => $val >= 0 ? $val : 0,
            'active'      => Filter::bool($request->input('active')) ? 1 : 0,
            'sort_order'  => Filter::int($request->input('sort_order', 0)),
        ];
    }

    private function form(array $g, string $title, string $action): Response
    {
        $type = (string) $g['type'];
        return $this->view('plugins/analytics/admin/goals_form', [
            'g'          => $g,
            'action'     => $action,
            'page_title' => $title,
            't_selector' => $type === 'selector_click' ? '1' : '',
            't_url'      => $type === 'url_visit' ? '1' : '',
            't_form'     => $type === 'form_submit' ? '1' : '',
            't_custom'   => $type === 'custom_event' ? '1' : '',
            'is_active'  => (int) $g['active'] === 1 ? '1' : '',
        ], 'analytics-goals', $title);
    }

    /** Подписи типов + форматирование € для списка. */
    private function decorate(array $goals): array
    {
        $labels = [
            'selector_click' => 'Клик по селектору',
            'url_visit'      => 'Визит страницы',
            'form_submit'    => 'Отправка формы',
            'custom_event'   => 'Custom-событие',
        ];
        foreach ($goals as &$g) {
            $g['type_label'] = $labels[(string) $g['type']] ?? (string) $g['type'];
            $g['value_fmt']  = (float) $g['value_eur'] > 0 ? '€' . number_format((float) $g['value_eur'], 0, '.', ' ') : '—';
            $g['is_active']  = (int) $g['active'] === 1 ? '1' : '';
        }
        unset($g);
        return $goals;
    }
}
