/**
 * Phoenix Audit Service
 * Immutable audit logs, WORM archive, PII boundaries, compliance
 */

import { getDb } from '../../db/index.js'
import { logger } from '../../lib/logger.js'

export interface AuditLog {
  logId: string
  userId: string | null
  action: string
  resourceType: string
  resourceId: string
  details: Record<string, any>
  timestamp: Date
  ipAddress?: string
  userAgent?: string
}

export interface AuditQuery {
  userId?: string
  action?: string
  resourceType?: string
  resourceId?: string
  startDate?: Date
  endDate?: Date
  limit?: number
}

class AuditService {
  /**
   * Create immutable audit log
   */
  async log(
    action: string,
    resourceType: string,
    resourceId: string,
    details: Record<string, any>,
    userId?: string,
    ipAddress?: string,
    userAgent?: string
  ): Promise<AuditLog> {
    const db = getDb()
    
    // Scrub PII from details
    const scrubbedDetails = this.scrubPII(details)
    
    const result = await db.query(
      `INSERT INTO audit_logs (
        user_id, action, resource_type, resource_id, details, ip_address, user_agent, timestamp
      ) VALUES ($1, $2, $3, $4, $5, $6, $7, NOW())
      RETURNING *`,
      [
        userId || null,
        action,
        resourceType,
        resourceId,
        JSON.stringify(scrubbedDetails),
        ipAddress || null,
        userAgent || null
      ]
    )

    logger.info('Audit log created', { logId: result.rows[0].id, action })
    
    // Archive to WORM storage if needed
    await this.archiveToWORM(result.rows[0])

    return this.mapAuditLog(result.rows[0])
  }

  /**
   * Query audit logs
   */
  async query(query: AuditQuery): Promise<AuditLog[]> {
    const db = getDb()
    
    const conditions: string[] = []
    const params: any[] = []
    let paramIndex = 1

    if (query.userId) {
      conditions.push(`user_id = $${paramIndex++}`)
      params.push(query.userId)
    }

    if (query.action) {
      conditions.push(`action = $${paramIndex++}`)
      params.push(query.action)
    }

    if (query.resourceType) {
      conditions.push(`resource_type = $${paramIndex++}`)
      params.push(query.resourceType)
    }

    if (query.resourceId) {
      conditions.push(`resource_id = $${paramIndex++}`)
      params.push(query.resourceId)
    }

    if (query.startDate) {
      conditions.push(`timestamp >= $${paramIndex++}`)
      params.push(query.startDate)
    }

    if (query.endDate) {
      conditions.push(`timestamp <= $${paramIndex++}`)
      params.push(query.endDate)
    }

    const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : ''
    const limit = query.limit || 1000

    params.push(limit)
    const result = await db.query(
      `SELECT * FROM audit_logs 
       ${whereClause}
       ORDER BY timestamp DESC 
       LIMIT $${paramIndex}`,
      params
    )

    return result.rows.map(this.mapAuditLog)
  }

  /**
   * Export audit logs for compliance
   */
  async exportForCompliance(
    startDate: Date,
    endDate: Date,
    format: 'JSON' | 'CSV' = 'JSON'
  ): Promise<string> {
    const logs = await this.query({ startDate, endDate, limit: 1000000 })
    
    if (format === 'JSON') {
      return JSON.stringify(logs, null, 2)
    } else {
      // CSV format
      const headers = ['logId', 'userId', 'action', 'resourceType', 'resourceId', 'timestamp']
      const rows = logs.map(log => [
        log.logId,
        log.userId || '',
        log.action,
        log.resourceType,
        log.resourceId,
        log.timestamp.toISOString()
      ])
      
      return [headers.join(','), ...rows.map(row => row.join(','))].join('\n')
    }
  }

  private scrubPII(data: Record<string, any>): Record<string, any> {
    // Placeholder - would implement actual PII scrubbing
    // Remove SSNs, credit cards, etc. based on PII boundaries
    const scrubbed = { ...data }
    
    // Example: remove credit card numbers
    if (scrubbed.cardNumber) {
      scrubbed.cardNumber = '***REDACTED***'
    }
    
    return scrubbed
  }

  private async archiveToWORM(log: any): Promise<void> {
    // Archive to WORM (Write Once Read Many) storage for compliance
    // This would write to immutable storage (S3 with object lock, etc.)
    logger.info('Archiving to WORM storage', { logId: log.id })
    // Placeholder - would implement actual WORM archiving
  }

  private mapAuditLog(row: any): AuditLog {
    return {
      logId: row.id,
      userId: row.user_id,
      action: row.action,
      resourceType: row.resource_type,
      resourceId: row.resource_id,
      details: typeof row.details === 'string' ? JSON.parse(row.details) : row.details,
      timestamp: row.timestamp,
      ipAddress: row.ip_address,
      userAgent: row.user_agent
    }
  }
}

export const auditService = new AuditService()
