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

export type AdminLoginLogRow = {
  [column: string]: unknown
  id: number
  user_id: number | null
  username: string
  role: string
  ip: string
  location: string
  user_agent: string
  success: boolean
  failure_reason: string
  created_at: string
}

type AdminLoginLogCreateInput = {
  userId?: number | string | null
  username?: string
  role?: string
  ip?: string
  location?: string
  userAgent?: string
  success?: boolean
  failureReason?: string
  createdAt: string
}

type AdminLoginLogListInput = {
  username?: string
  dateFrom?: string
  dateTo?: string
  page?: number | string
  pageSize?: number | string
}

export async function createAdminLoginLog(
  input: AdminLoginLogCreateInput,
): Promise<AdminLoginLogRow | null> {
  const result = await query<AdminLoginLogRow>(
    `
      INSERT INTO admin_login_logs (
        user_id,
        username,
        role,
        ip,
        location,
        user_agent,
        success,
        failure_reason,
        created_at
      ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
      RETURNING *
    `,
    [
      input.userId || null,
      String(input.username || '').trim(),
      String(input.role || '').trim(),
      String(input.ip || '').trim(),
      String(input.location || '').trim(),
      String(input.userAgent || '').trim(),
      input.success !== false,
      String(input.failureReason || '').trim(),
      input.createdAt,
    ],
  )

  return result.rows[0] || null
}

export async function listAdminLoginLogs(
  queryInput: AdminLoginLogListInput = {},
): Promise<{ items: AdminLoginLogRow[]; total: number }> {
  const conditions: string[] = []
  const params: unknown[] = []

  if (queryInput.username) {
    params.push(String(queryInput.username).trim())
    conditions.push(`username = $${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 = Math.max(1, Number(queryInput.page) || 1)
  const pageSize = Math.min(100, Math.max(1, Number(queryInput.pageSize) || 20))
  const offset = (page - 1) * pageSize

  const totalResult = await query<{ total: number }>(
    `SELECT COUNT(*)::int AS total FROM admin_login_logs ${whereClause}`,
    params,
  )

  params.push(pageSize)
  params.push(offset)
  const itemsResult = await query<AdminLoginLogRow>(
    `
      SELECT *
      FROM admin_login_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),
  }
}
