<?php
declare(strict_types=1);

namespace Celena\Module\Webhooks;

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\Security\Permission;
use Celena\Core\Template\Engine;
use Celena\Module\AdminBase\AdminController;
use Celena\Module\Settings\Options;

final class WebhooksController extends AdminController
{
    private const ALLOWED_EVENTS = [
        'news.published',
        'user.registered',
        'user.login.success',
        'comment.created',
    ];

    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 (!Permission::can($this->auth->user(), 'options.read')) {
            return $this->redirect('/admin', 'Доступ запрещён.', 'error');
        }
        $rows = $this->conn->builder('celena_webhooks')->orderBy('id', 'desc')->get();
        return $this->view('admin/webhooks/index', [
            'webhooks' => $rows,
            'events' => self::ALLOWED_EVENTS,
        ], 'settings', 'Webhooks');
    }

    public function store(Request $request): Response
    {
        if (!Permission::can($this->auth->user(), 'options.write')) {
            return $this->redirect('/admin/webhooks', 'Доступ запрещён.', 'error');
        }
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            return $this->redirect('/admin/webhooks', 'CSRF.', 'error');
        }
        $event = Filter::in($request->input('event'), self::ALLOWED_EVENTS, '');
        $url = Filter::url($request->input('url'));
        if ($url !== null) {
            $scheme = strtolower((string) parse_url($url, PHP_URL_SCHEME));
            if (!in_array($scheme, ['http', 'https'], true)) {
                $url = null;
            }
        }
        $secret = Filter::string($request->input('secret'), 128);
        $active = Filter::bool($request->input('is_active'));
        if ($event === '' || $url === null) {
            return $this->redirect('/admin/webhooks', 'Проверьте поля. URL должен быть http(s) и событие — из списка.', 'error');
        }
        $this->conn->builder('celena_webhooks')->insert([
            'event' => $event,
            'url' => $url,
            'secret' => $secret,
            'is_active' => $active,
            'created_at' => date('Y-m-d H:i:s'),
        ]);
        return $this->redirect('/admin/webhooks', 'Webhook добавлен.');
    }

    public function delete(Request $request, array $params): Response
    {
        if (!Permission::can($this->auth->user(), 'options.write')) {
            return $this->redirect('/admin/webhooks', 'Доступ запрещён.', 'error');
        }
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            return $this->redirect('/admin/webhooks', 'CSRF.', 'error');
        }
        $id = Filter::int($params['id'] ?? 0);
        $this->conn->builder('celena_webhooks')->where('id', '=', $id)->delete();
        return $this->redirect('/admin/webhooks', 'Webhook удалён.');
    }

    public function toggle(Request $request, array $params): Response
    {
        if (!Permission::can($this->auth->user(), 'options.write')) {
            return $this->redirect('/admin/webhooks', 'Доступ запрещён.', 'error');
        }
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            return $this->redirect('/admin/webhooks', 'CSRF.', 'error');
        }
        $id = Filter::int($params['id'] ?? 0);
        $row = $this->conn->builder('celena_webhooks')->where('id', '=', $id)->first();
        if ($row !== null) {
            $this->conn->builder('celena_webhooks')
                ->where('id', '=', $id)
                ->update(['is_active' => !$row['is_active']]);
        }
        return $this->redirect('/admin/webhooks');
    }
}
