import { query } from "../../db/pool.js";
import { recordAppEvent } from "../../lib/app-log.js";

export interface SecurityIncidentRow {
  id: number;
  severity: "low" | "medium" | "high" | "critical";
  title: string;
  status: "open" | "investigating" | "contained" | "resolved" | "closed";
  detected_at: string;
  resolved_at: string | null;
  reported_by: string;
  summary: string;
  response: string;
  created_at: string;
  updated_at: string;
}

export interface SecurityIncidentFilters {
  q?: string;
  status?: SecurityIncidentRow["status"];
  severity?: SecurityIncidentRow["severity"];
  page: number;
  pageSize: number;
}

export async function listSecurityIncidents(filters: SecurityIncidentFilters) {
  const whereParts: string[] = [];
  const params: unknown[] = [];
  if (filters.q?.trim()) {
    params.push(`%${filters.q.trim()}%`);
    whereParts.push(`(title ILIKE $${params.length} OR summary ILIKE $${params.length} OR response ILIKE $${params.length})`);
  }
  if (filters.status) {
    params.push(filters.status);
    whereParts.push(`status = $${params.length}`);
  }
  if (filters.severity) {
    params.push(filters.severity);
    whereParts.push(`severity = $${params.length}`);
  }
  const where = whereParts.length ? `WHERE ${whereParts.join(" AND ")}` : "";
  const countRows = await query<{ count: string }>(`SELECT COUNT(*)::int AS count FROM security_incidents ${where}`, params);
  const total = Number(countRows[0]?.count ?? 0);
  const offset = (filters.page - 1) * filters.pageSize;
  const pageParams = [...params, filters.pageSize, offset];
  const items = await query<SecurityIncidentRow>(`
    SELECT *
    FROM security_incidents
    ${where}
    ORDER BY created_at DESC
    LIMIT $${pageParams.length - 1}
    OFFSET $${pageParams.length}
  `, pageParams);
  return { items, total, page: filters.page, pageSize: filters.pageSize, totalPages: Math.max(1, Math.ceil(total / filters.pageSize)) };
}

export async function createSecurityIncident(input: {
  severity: SecurityIncidentRow["severity"];
  title: string;
  status?: SecurityIncidentRow["status"];
  detectedAt?: string;
  reportedBy?: string;
  summary?: string;
  response?: string;
}): Promise<SecurityIncidentRow> {
  const rows = await query<SecurityIncidentRow>(`
    INSERT INTO security_incidents (severity, title, status, detected_at, reported_by, summary, response)
    VALUES ($1, $2, $3, COALESCE($4::timestamptz, NOW()), $5, $6, $7)
    RETURNING *
  `, [
    input.severity,
    input.title,
    input.status ?? "open",
    input.detectedAt ?? null,
    input.reportedBy ?? "system",
    input.summary ?? "",
    input.response ?? "",
  ]);
  const item = rows[0]!;
  await recordAppEvent({
    level: item.severity === "critical" || item.severity === "high" ? "warning" : "info",
    source: "security.incident",
    message: `Brecha creada: ${item.title}`,
    details: {
      id: item.id,
      severity: item.severity,
      status: item.status,
      reportedBy: item.reported_by,
    },
  });
  return item;
}

export async function updateSecurityIncident(
  id: number,
  input: {
    status?: SecurityIncidentRow["status"];
    response?: string;
    summary?: string;
    resolvedAt?: string | null;
  }
): Promise<SecurityIncidentRow | null> {
  const rows = await query<SecurityIncidentRow>(`
    UPDATE security_incidents
    SET
      status = COALESCE($2, status),
      response = COALESCE($3, response),
      summary = COALESCE($4, summary),
      resolved_at = CASE
        WHEN $5::timestamptz IS NOT NULL THEN $5::timestamptz
        WHEN $2 = 'resolved' AND resolved_at IS NULL THEN NOW()
        ELSE resolved_at
      END,
      updated_at = NOW()
    WHERE id = $1
    RETURNING *
  `, [
    id,
    input.status ?? null,
    input.response ?? null,
    input.summary ?? null,
    input.resolvedAt ?? null,
  ]);
  const item = rows[0] ?? null;
  if (item) {
    await recordAppEvent({
      level: item.status === "resolved" || item.status === "closed" ? "info" : "warning",
      source: "security.incident",
      message: `Brecha actualizada: ${item.title}`,
      details: {
        id: item.id,
        severity: item.severity,
        status: item.status,
      },
    });
  }
  return item;
}
