<?php
declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;
use App\Core\Database;

final class AdminAuditController extends Controller
{
    private function ensureTable($db): void
    {
        $st = $db->query("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name='audit_logs'");
        if ((int)$st->fetchColumn() <= 0) {
            throw new \RuntimeException("audit_logs table missing");
        }
    }

    public function index(): void
    {
        require_admin_area();
        $db = Database::getInstance();
        $this->ensureTable($db);

        $q = trim((string)($_GET['q'] ?? ''));
        $action = trim((string)($_GET['action'] ?? ''));
        $entity = trim((string)($_GET['entity'] ?? ''));
        $from = trim((string)($_GET['from'] ?? ''));
        $to   = trim((string)($_GET['to'] ?? ''));
        $limit = (int)($_GET['limit'] ?? 200);
        if ($limit < 50) $limit = 50;
        if ($limit > 1000) $limit = 1000;

        $where = [];
        $params = [];

        if ($q !== '') {
            $where[] = "(actor_email LIKE :q OR message LIKE :q OR ip_address LIKE :q OR user_agent LIKE :q)";
            $params[':q'] = '%'.$q.'%';
        }
        if ($action !== '') {
            $where[] = "action = :a";
            $params[':a'] = $action;
        }
        if ($entity !== '') {
            $where[] = "entity_type = :e";
            $params[':e'] = $entity;
        }
        if ($from !== '') {
            $where[] = "created_at >= :f";
            $params[':f'] = $from . " 00:00:00";
        }
        if ($to !== '') {
            $where[] = "created_at <= :t";
            $params[':t'] = $to . " 23:59:59";
        }

        $sql = "SELECT * FROM audit_logs";
        if ($where) $sql .= " WHERE " . implode(" AND ", $where);
        $sql .= " ORDER BY id DESC LIMIT " . (int)$limit;

        $st = $db->prepare($sql);
        $st->execute($params);
        $rows = $st->fetchAll() ?: [];

        // distinct actions/entities for dropdowns
        $actions = [];
        $entities = [];
        try {
            $actions = $db->query("SELECT DISTINCT action FROM audit_logs WHERE action IS NOT NULL AND action<>'' ORDER BY action")->fetchAll() ?: [];
            $entities = $db->query("SELECT DISTINCT entity_type FROM audit_logs WHERE entity_type IS NOT NULL AND entity_type<>'' ORDER BY entity_type")->fetchAll() ?: [];
            $actions = array_values(array_filter(array_map(fn($r)=>(string)($r['action']??''), $actions)));
            $entities = array_values(array_filter(array_map(fn($r)=>(string)($r['entity_type']??''), $entities)));
        } catch (\Throwable $e) {}

        // KPIs
        $kpi = ['total'=>0,'today'=>0,'week'=>0];
        try {
            $kpi['total'] = (int)$db->query("SELECT COUNT(*) FROM audit_logs")->fetchColumn();
            $kpi['today'] = (int)$db->query("SELECT COUNT(*) FROM audit_logs WHERE created_at >= CURDATE()")->fetchColumn();
            $kpi['week']  = (int)$db->query("SELECT COUNT(*) FROM audit_logs WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)")->fetchColumn();
        } catch (\Throwable $e) {}

        $this->view('admin/audit/index', compact('rows','q','action','entity','from','to','limit','actions','entities','kpi'));
    }

    public function clear(): void
    {
        require_admin_area();
        $db = Database::getInstance();
        $this->ensureTable($db);

        // safety: only if confirmed
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
            http_response_code(405);
            return;
        }

        $confirm = trim((string)($_POST['confirm'] ?? ''));
        if ($confirm !== 'YES') {
            if (function_exists('flash_set')) flash_set('warning', 'Type YES to confirm clearing audit logs');
            header('Location: ' . base_path('admin/audit'));
            exit;
        }

        $db->exec("TRUNCATE TABLE audit_logs");
        if (function_exists('flash_set')) flash_set('success', 'Audit logs cleared');

        header('Location: ' . base_path('admin/audit'));
        exit;
    }

    public function show(): void
    {
        require_admin_area();
        $db = Database::getInstance();
        $this->ensureTable($db);

        $id = (int)($_GET['id'] ?? 0);
        if ($id <= 0) { http_response_code(400); echo "Bad request"; return; }

        $st = $db->prepare("SELECT * FROM audit_logs WHERE id=:id LIMIT 1");
        $st->execute([':id'=>$id]);
        $row = $st->fetch();
        if (!$row) { http_response_code(404); echo "Not found"; return; }

        $this->view('admin/audit/view', compact('row'));
    }
}
