const { query } = require('../../utils/db')

const COLS = 'id, user_id, transport, endpoint, platform, created_at, last_seen_at'

// Register (idempotent upsert on the UNIQUE user_id+endpoint). Re-registering the
// same endpoint refreshes transport/platform and bumps last_seen_at.
async function upsert({ userId, transport, endpoint, platform }) {
  await query(
    `INSERT INTO push_devices (user_id, transport, endpoint, platform)
     VALUES (?, ?, ?, ?)
     ON DUPLICATE KEY UPDATE transport = VALUES(transport), platform = VALUES(platform), last_seen_at = CURRENT_TIMESTAMP`,
    [userId, transport, endpoint, platform || null],
  )
  return getByUserEndpoint(userId, endpoint)
}

async function getByUserEndpoint(userId, endpoint) {
  const rows = await query(`SELECT ${COLS} FROM push_devices WHERE user_id = ? AND endpoint = ? LIMIT 1`, [userId, endpoint])
  return rows[0] || null
}

const listByUser = (userId) =>
  query(`SELECT ${COLS} FROM push_devices WHERE user_id = ? ORDER BY created_at DESC`, [userId])

async function remove(id, userId) {
  const res = await query('DELETE FROM push_devices WHERE id = ? AND user_id = ?', [id, userId])
  return Number(res.affectedRows || 0)
}

// Endpoints of every device whose user subscribes to `streamId` (public fan-out).
const endpointsForStream = (streamId) =>
  query(
    `SELECT d.endpoint, d.transport
       FROM push_devices d
       JOIN notification_subscriptions s ON s.user_id = d.user_id
      WHERE s.stream_id = ?`,
    [streamId],
  )

// Endpoints of ONE user's devices, only if that user subscribes to `streamId`
// (personal / owner-keyed fan-out).
const endpointsForUserStream = (userId, streamId) =>
  query(
    `SELECT d.endpoint, d.transport
       FROM push_devices d
       JOIN notification_subscriptions s ON s.user_id = d.user_id
      WHERE d.user_id = ? AND s.stream_id = ?`,
    [userId, streamId],
  )

module.exports = { upsert, getByUserEndpoint, listByUser, remove, endpointsForStream, endpointsForUserStream }
