import { query } from '../db/client.js'

type AdminAuditLogRow = {
  [column: string]: unknown
  id: number
  actor_user_id: number | null
  actor_username: string
  actor_role: string
  action: string
  target_type: string
  target_id: string
  payload_json: string | Record<string, unknown>
  created_at: string
}

type AdminAuditLogCreateInput = {
  actorUserId?: number | string | null
  actorUsername?: string
  actorRole?: string
  action: string
  targetType: string
  targetId: string
  payloadJson?: string
  createdAt: string
}

type AdminAuditLogListInput = {
  actorUsername?: string
  action?: string
  targetType?: string
  dateFrom?: string
  dateTo?: string
  page?: number | string
  pageSize?: number | string
}

type AdminAuditLogListResult = {
  items: AdminAuditLogRow[]
  total: number
}

export async function createAdminAuditLog(
  input: AdminAuditLogCreateInput,
): Promise<AdminAuditLogRow | null> {
  const result = await query<AdminAuditLogRow>(
    `
      INSERT INTO admin_audit_logs (
        actor_user_id,
        actor_username,
        actor_role,
        action,
        target_type,
        target_id,
        payload_json,
        created_at
      ) VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb, $8)
      RETURNING *
    `,
    [
      input.actorUserId || null,
      input.actorUsername || '',
      input.actorRole || '',
      input.action,
      input.targetType,
      input.targetId,
      input.payloadJson || '{}',
      input.createdAt,
    ],
  )

  return result.rows[0] || null
}

export async function getAdminAuditLogById(
  logId: number | string,
): Promise<AdminAuditLogRow | null> {
  const result = await query<AdminAuditLogRow>(
    'SELECT * FROM admin_audit_logs WHERE id = $1 LIMIT 1',
    [Number(logId)],
  )
  return result.rows[0] || null
}

export async function listAdminAuditLogs(
  queryInput: AdminAuditLogListInput = {},
): Promise<AdminAuditLogListResult> {
  const conditions: string[] = []
  const params: unknown[] = []

  if (queryInput.actorUsername) {
    params.push(queryInput.actorUsername)
    conditions.push(`actor_username = $${params.length}`)
  }

  if (queryInput.action) {
    params.push(queryInput.action)
    conditions.push(`action = $${params.length}`)
  }

  if (queryInput.targetType) {
    params.push(queryInput.targetType)
    conditions.push(`target_type = $${params.length}`)
  }

  if (queryInput.dateFrom) {
    params.push(queryInput.dateFrom)
    conditions.push(`created_at >= $${params.length}`)
  }

  if (queryInput.dateTo) {
    params.push(queryInput.dateTo)
    conditions.push(`created_at <= $${params.length}`)
  }

  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : ''
  const page = Number(queryInput.page) || 1
  const pageSize = Number(queryInput.pageSize) || 20
  const offset = (page - 1) * pageSize

  const totalResult = await query<{ [column: string]: unknown; total: number }>(
    `SELECT COUNT(*)::int AS total FROM admin_audit_logs ${whereClause}`,
    params,
  )

  params.push(pageSize)
  params.push(offset)
  const itemsResult = await query<AdminAuditLogRow>(
    `
      SELECT *
      FROM admin_audit_logs
      ${whereClause}
      ORDER BY id DESC
      LIMIT $${params.length - 1} OFFSET $${params.length}
    `,
    params,
  )

  return {
    items: itemsResult.rows,
    total: Number(totalResult.rows[0]?.total || 0),
  }
}
