<?php
declare(strict_types=1);

namespace App\Controllers;

require_once BASE_PATH . '/app/helpers/permissions.php';

use App\Core\Controller;
use App\Core\Database;
use App\Services\AuditService;
use App\Services\MailerService;
use App\Services\CronLogService;

final class SystemController extends Controller
{
    public function auditIndex(): void
    {
        require_permission('audit.view');
        $db = Database::getInstance();

        $q = trim((string)($_GET['q'] ?? ''));
        $sql = "SELECT * FROM audit_logs";
        $params = [];
        if ($q !== '') {
            $sql .= " WHERE action LIKE :q OR actor_email LIKE :q OR message LIKE :q OR entity_type LIKE :q";
            $params[':q'] = '%' . $q . '%';
        }
        $sql .= " ORDER BY id DESC LIMIT 300";

        $st = $db->prepare($sql);
        $st->execute($params);
        $rows = $st->fetchAll();

        $this->view('admin/system/audit', ['rows' => $rows, 'q' => $q]);
    }

    public function rbacIndex(): void
    {
        require_permission('rbac.manage');

        $db = Database::getInstance();
        $roles = $db->query("SELECT * FROM roles ORDER BY id ASC")->fetchAll();
        $perms = $db->query("SELECT * FROM permissions ORDER BY group_name, id ASC")->fetchAll();
        $rp = $db->query("SELECT role_id, permission_id FROM role_permissions")->fetchAll();

        $map = [];
        foreach ($rp as $r) {
            $map[(int)$r['role_id']][(int)$r['permission_id']] = true;
        }

        $this->view('admin/system/rbac', [
            'roles' => $roles,
            'perms' => $perms,
            'map' => $map,
        ]);
    }

    public function rbacSave(): void
    {
        require_permission('rbac.manage');
        if (!$this->isPost()) redirect('admin/rbac');

        csrf_check();
        $db = Database::getInstance();

        $roleId = (int)($_POST['role_id'] ?? 0);
        $selected = $_POST['perm'] ?? [];
        $selected = is_array($selected) ? array_map('intval', $selected) : [];

        $db->prepare("DELETE FROM role_permissions WHERE role_id = :rid")->execute([':rid' => $roleId]);

        $ins = $db->prepare("INSERT INTO role_permissions (role_id, permission_id) VALUES (:rid, :pid)");
        foreach ($selected as $pid) {
            $ins->execute([':rid' => $roleId, ':pid' => $pid]);
        }

        AuditService::log('rbac.update', 'role', $roleId, 'Updated role permissions', ['count' => count($selected)]);

        flash('success', trans('save'));
        redirect('admin/rbac');
    }

    public function settingsIndex(): void
    {
        require_permission('system.manage');
        $db = Database::getInstance();

        $rows = $db->query("SELECT * FROM system_settings ORDER BY setting_key ASC")->fetchAll();

        $mailCfg = require __DIR__ . '/../../config/mail.php';

        $this->view('admin/system/settings', [
            'rows' => $rows,
            'mail' => $mailCfg,
        ]);
    }

    public function settingsSave(): void
    {
        require_permission('system.manage');
        if (!$this->isPost()) redirect('admin/system-settings');

        csrf_check();

        $key = trim((string)($_POST['setting_key'] ?? ''));
        $val = trim((string)($_POST['setting_value'] ?? ''));

        if ($key === '') {
            flash('danger', trans('required_fields'));
            redirect('admin/system-settings');
        }

        $db = Database::getInstance();
        $st = $db->prepare("
            INSERT INTO system_settings (setting_key, setting_value, updated_by)
            VALUES (:k,:v,:u)
            ON DUPLICATE KEY UPDATE setting_value=VALUES(setting_value), updated_by=VALUES(updated_by)
        ");
        $st->execute([':k'=>$key, ':v'=>$val ?: null, ':u'=>auth_id()]);

        AuditService::log('settings.save', 'system_setting', null, "Saved setting $key");

        flash('success', trans('save'));
        redirect('admin/system-settings');
    }

    public function testSmtp(): void
    {
        require_permission('system.manage');
        if (!$this->isPost()) redirect('admin/system-settings');

        csrf_check();

        $to = trim((string)($_POST['to'] ?? ''));
        if ($to === '') {
            flash('danger', trans('required_fields'));
            redirect('admin/system-settings');
        }

        $ok = MailerService::send($to, 'SMTP Test - EasyChair', '<p>SMTP test email sent successfully.</p>');

        AuditService::log('smtp.test', 'mail', null, $ok ? 'SMTP test success' : 'SMTP test failed', ['to' => $to]);

        flash($ok ? 'success' : 'danger', $ok ? trans('sent') : trans('failed'));
        redirect('admin/system-settings');
    }

    public function cronIndex(): void
    {
        require_permission('cron.view');
        $db = Database::getInstance();
        $rows = $db->query("SELECT * FROM cron_runs ORDER BY id DESC LIMIT 200")->fetchAll();
        $this->view('admin/system/cron', ['rows' => $rows]);
    }
}
