/**
 * SQLite Database for Push Notifications Subscriptions
 * Stores user push subscription data for Web Push notifications
 */

import Database from 'better-sqlite3'
import path from 'path'
import fs from 'fs'

// Database file path
const dbPath = path.join(process.cwd(), 'data', 'push-subscriptions.db')

// Ensure data directory exists
const dataDir = path.dirname(dbPath)
if (!fs.existsSync(dataDir)) {
  fs.mkdirSync(dataDir, { recursive: true })
}

// Initialize database
const db = new Database(dbPath)

// Enable WAL mode for better concurrency
db.pragma('journal_mode = WAL')

// Create table on startup
db.exec(`
  CREATE TABLE IF NOT EXISTS push_subscriptions (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    user_id INTEGER NOT NULL,
    role_id INTEGER NOT NULL,
    endpoint TEXT UNIQUE NOT NULL,
    p256dh TEXT NOT NULL,
    auth TEXT NOT NULL,
    user_agent TEXT,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    last_used DATETIME DEFAULT CURRENT_TIMESTAMP
  );

  CREATE INDEX IF NOT EXISTS idx_push_user ON push_subscriptions(user_id);
  CREATE INDEX IF NOT EXISTS idx_push_role ON push_subscriptions(role_id);
  CREATE INDEX IF NOT EXISTS idx_push_endpoint ON push_subscriptions(endpoint);
`)

console.log('[PushDB] ✅ SQLite database initialized at:', dbPath)

/**
 * Save or update a push subscription
 */
export const savePushSubscription = (userId: number, roleId: number, subscription: any, userAgent?: string) => {
  const stmt = db.prepare(`
    INSERT INTO push_subscriptions (user_id, role_id, endpoint, p256dh, auth, user_agent, last_used)
    VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
    ON CONFLICT(endpoint) DO UPDATE SET
      user_id = excluded.user_id,
      role_id = excluded.role_id,
      last_used = CURRENT_TIMESTAMP
  `)

  try {
    const result = stmt.run(
      userId,
      roleId,
      subscription.endpoint,
      subscription.keys.p256dh,
      subscription.keys.auth,
      userAgent || null
    )
    console.log('[PushDB] ✅ Subscription saved:', { userId, roleId, endpoint: subscription.endpoint })
    return result
  } catch (error: any) {
    console.error('[PushDB] ❌ Error saving subscription:', error.message)
    throw error
  }
}

/**
 * Get all push subscriptions for a specific user
 */
export const getPushSubscriptionsByUser = (userId: number) => {
  const stmt = db.prepare(`
    SELECT * FROM push_subscriptions WHERE user_id = ? ORDER BY last_used DESC
  `)
  return stmt.all(userId)
}

/**
 * Get all push subscriptions for a specific role
 */
export const getPushSubscriptionsByRole = (roleId: number) => {
  const stmt = db.prepare(`
    SELECT * FROM push_subscriptions WHERE role_id = ? ORDER BY last_used DESC
  `)
  return stmt.all(roleId)
}

/**
 * Get all push subscriptions for multiple roles
 */
export const getPushSubscriptionsByRoles = (roleIds: number[]) => {
  if (roleIds.length === 0) return []

  const placeholders = roleIds.map(() => '?').join(',')
  const stmt = db.prepare(`
    SELECT * FROM push_subscriptions
    WHERE role_id IN (${placeholders})
    ORDER BY last_used DESC
  `)
  return stmt.all(...roleIds)
}

/**
 * Delete a push subscription by endpoint
 */
export const deletePushSubscription = (endpoint: string) => {
  const stmt = db.prepare('DELETE FROM push_subscriptions WHERE endpoint = ?')
  try {
    const result = stmt.run(endpoint)
    if (result.changes > 0) {
      console.log('[PushDB] ✅ Subscription deleted:', endpoint)
    }
    return result
  } catch (error: any) {
    console.error('[PushDB] ❌ Error deleting subscription:', error.message)
    throw error
  }
}

/**
 * Delete all subscriptions for a user
 */
export const deletePushSubscriptionsByUser = (userId: number) => {
  const stmt = db.prepare('DELETE FROM push_subscriptions WHERE user_id = ?')
  const result = stmt.run(userId)
  console.log('[PushDB] Deleted', result.changes, 'subscriptions for user', userId)
  return result
}

/**
 * Get statistics about subscriptions
 */
export const getPushSubscriptionStats = () => {
  const stmt = db.prepare(`
    SELECT
      COUNT(*) as total,
      COUNT(DISTINCT user_id) as unique_users,
      COUNT(DISTINCT role_id) as unique_roles
    FROM push_subscriptions
  `)
  return stmt.get()
}

/**
 * Clean up old subscriptions (older than 90 days)
 */
export const cleanupOldSubscriptions = () => {
  const stmt = db.prepare(`
    DELETE FROM push_subscriptions
    WHERE last_used < datetime('now', '-90 days')
  `)
  const result = stmt.run()
  if (result.changes > 0) {
    console.log('[PushDB] Cleaned up', result.changes, 'old subscriptions')
  }
  return result
}

// Export database instance for advanced queries
export const pushDb = db
