import type { Request } from 'express'
import type { JsonObject } from '../../types/json.js'

import { createAdminLoginLog, listAdminLoginLogs } from '../../repositories/admin-login-log-repo.js'
import { logWarn } from '../../utils/logger.js'
import { nowIso } from '../../utils/time.js'
import { normalizeDateQuery, normalizePage, normalizePageSize } from './admin-query-utils.js'

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

export async function recordAdminLoginLog(input: RecordAdminLoginInput = {}) {
  try {
    return await createAdminLoginLog({
      userId: input.userId ?? null,
      username: String(input.username || '').trim(),
      role: String(input.role || '').trim(),
      ip: String(input.ip || '').trim(),
      location: String(input.location || '').trim(),
      userAgent: String(input.userAgent || '').trim(),
      success: input.success !== false,
      failureReason: String(input.failureReason || '').trim(),
      createdAt: nowIso(),
    })
  } catch (error) {
    logWarn('[admin/login-log]', '写入登录记录失败，已跳过', {
      username: input.username,
      error,
    })
    return null
  }
}

export async function recordAdminLoginFromRequest(
  req: Request,
  input: Omit<RecordAdminLoginInput, 'ip' | 'userAgent' | 'location'> = {},
) {
  return recordAdminLoginLog({
    ...input,
    ip: resolveClientIp(req),
    userAgent: resolveUserAgent(req),
    location: resolveClientLocation(req),
  })
}

export async function getAdminLoginLogs(query: JsonObject = {}) {
  const page = normalizePage(query.page)
  const pageSize = normalizePageSize(query.pageSize)
  const { items, total } = await listAdminLoginLogs({
    page,
    pageSize,
    username: String(query.username || '').trim(),
    dateFrom: normalizeDateQuery(query.dateFrom),
    dateTo: normalizeDateQuery(query.dateTo, true),
  })

  return {
    items: items.map((item) => ({
      logId: Number(item.id),
      userId: Number(item.user_id || 0) || null,
      username: String(item.username || '').trim(),
      role: String(item.role || '').trim(),
      ip: String(item.ip || '').trim(),
      location: String(item.location || '').trim(),
      userAgent: String(item.user_agent || '').trim(),
      success: item.success !== false,
      failureReason: String(item.failure_reason || '').trim(),
      createdAt: item.created_at,
    })),
    pagination: { page, pageSize, total },
  }
}

export function resolveClientIp(req: Request) {
  const forwarded = String(req.headers['x-forwarded-for'] || '')
    .split(',')
    .map((item) => item.trim())
    .find(Boolean)
  const realIp = String(req.headers['x-real-ip'] || '').trim()
  const ip = String(forwarded || realIp || req.ip || req.socket?.remoteAddress || '').trim()
  return ip.replace(/^::ffff:/, '')
}

export function resolveUserAgent(req: Request) {
  return String(req.headers['user-agent'] || '').trim()
}

/** 优先读常见代理/CDN 地理位置头，没有则留空。 */
export function resolveClientLocation(req: Request) {
  const country = firstHeader(req, [
    'cf-ipcountry',
    'x-vercel-ip-country',
    'cloudfront-viewer-country',
    'x-country-code',
  ])
  const city = firstHeader(req, ['cf-ipcity', 'x-vercel-ip-city', 'x-city'])
  const region = firstHeader(req, ['cf-region', 'x-vercel-ip-country-region', 'x-region'])

  return [country, region, city].filter(Boolean).join(' · ')
}

function firstHeader(req: Request, names: string[]) {
  for (const name of names) {
    const value = String(req.headers[name] || '').trim()
    if (value && value.toUpperCase() !== 'XX') {
      return value
    }
  }
  return ''
}
