import { pool } from "../config/db.js";
import { ensureAuditTable } from "../utils/audit.js";

function parseDetails(value) {
  if (!value) return null;
  if (typeof value === "object") return value;
  try {
    return JSON.parse(value);
  } catch {
    return value;
  }
}

export async function getAuditLogs(req, res, next) {
  try {
    await ensureAuditTable();

    const { search = "", action = "" } = req.query;
    const page = Math.max(Number(req.query.page) || 1, 1);
    const limit = Math.min(Math.max(Number(req.query.limit) || 100, 1), 300);
    const offset = (page - 1) * limit;
    const where = [];
    const params = {};

    if (search.trim()) {
      where.push("(username LIKE :search OR entity LIKE :search OR entity_id LIKE :search OR details LIKE :search)");
      params.search = `%${search.trim()}%`;
    }

    if (action) {
      where.push("action = :action");
      params.action = action;
    }

    const [[countRow]] = await pool.query(
      `
      SELECT COUNT(*) AS total
      FROM audit_logs
      ${where.length ? `WHERE ${where.join(" AND ")}` : ""}
      `,
      params
    );

    const [rows] = await pool.query(
      `
      SELECT id, user_id, username, action, entity, entity_id, details, ip_address, user_agent, created_at
      FROM audit_logs
      ${where.length ? `WHERE ${where.join(" AND ")}` : ""}
      ORDER BY created_at DESC, id DESC
      LIMIT ${limit} OFFSET ${offset}
      `,
      params
    );

    const total = Number(countRow.total || 0);
    res.json({
      success: true,
      pagination: {
        page,
        limit,
        total,
        totalPages: Math.max(Math.ceil(total / limit), 1)
      },
      data: rows.map(row => ({
        id: row.id,
        userId: row.user_id,
        username: row.username,
        action: row.action,
        entity: row.entity,
        entityId: row.entity_id,
        details: parseDetails(row.details),
        ipAddress: row.ip_address,
        userAgent: row.user_agent,
        createdAt: row.created_at
      }))
    });
  } catch (err) {
    next(err);
  }
}
