import type { PayloadRequest } from 'payload'
import { AuditAction } from '@/types/audit'

interface AuditLogData {
  action: AuditAction
  collection: string
  documentId?: string
  documentTitle?: string
  userId: string
  userName?: string
  userEmail?: string
  userRole?: string
  ipAddress?: string
  userAgent?: string
  changes?: Record<string, unknown>
}

/**
 * 建立稽核日誌
 * 此函數用於記錄系統中的重要操作，包括登入/登出、內容變更等
 */
export const auditLogger = async (req: PayloadRequest, data: AuditLogData): Promise<void> => {
  try {
    // 從請求中獲取 IP 和 User Agent
    const ipAddress = req.headers?.get('x-forwarded-for')?.split(',')[0] ||
                      req.headers?.get('x-real-ip') ||
                      undefined
    const userAgent = req.headers?.get('user-agent') || undefined

    await req.payload.create({
      collection: 'audit',
      data: {
        action: data.action,
        collection: data.collection,
        documentId: data.documentId,
        documentTitle: data.documentTitle,
        userId: data.userId,
        userName: data.userName,
        userEmail: data.userEmail,
        userRole: data.userRole,
        ipAddress,
        userAgent,
        changes: data.changes,
      },
      // 不觸發稽核日誌的稽核日誌（避免無限循環）
      depth: 0,
    })
  } catch (error) {
    // 記錄錯誤但不中斷主要流程
    console.error('Audit log creation failed:', error)
  }
}

/**
 * 記錄登入事件
 */
export const logLogin = async (req: PayloadRequest, userId: string): Promise<void> => {
  const user = await req.payload.findByID({
    collection: 'users',
    id: userId,
  })

  await auditLogger(req, {
    action: 'login',
    collection: 'users',
    documentId: userId,
    userId,
    userName: user.name as string,
    userEmail: user.email as string,
    userRole: String(user.role ?? ''),
  })
}

/**
 * 記錄登出事件
 */
export const logLogout = async (req: PayloadRequest, userId: string): Promise<void> => {
  await auditLogger(req, {
    action: 'logout',
    collection: 'users',
    documentId: userId,
    userId,
  })
}

/**
 * 記錄文件變更（創建、更新、刪除）
 */
export const logDocumentChange = async (
  req: PayloadRequest,
  operation: 'create' | 'update' | 'delete',
  collection: string,
  docId?: string,
  docTitle?: string,
  changes?: Record<string, unknown>,
): Promise<void> => {
  if (!req.user) return

  await auditLogger(req, {
    action: operation,
    collection,
    documentId: docId,
    documentTitle: docTitle,
    userId: req.user.id,
    userName: req.user.name as string,
    userEmail: req.user.email as string,
    userRole: String(req.user.role ?? ''),
    changes,
  })
}
