-- name: CreateTransferSession :exec
INSERT INTO transfer_sessions (
    id, user_id, sender_name, receiver_name, state,
    file_name, file_size, file_sha256, created_at
)
VALUES (?, ?, ?, ?, 'PENDING', ?, ?, ?, ?);

-- name: GetTransferSession :one
SELECT id, user_id, sender_name, receiver_name, state, mode,
       file_name, file_size, file_sha256, bytes_transferred,
       created_at, finished_at, fail_reason
FROM transfer_sessions
WHERE id = ?;

-- name: UpdateTransferState :execrows
UPDATE transfer_sessions
SET state             = sqlc.arg('state'),
    mode              = COALESCE(sqlc.narg('mode'),              mode),
    fail_reason       = COALESCE(sqlc.narg('fail_reason'),       fail_reason),
    finished_at       = COALESCE(sqlc.narg('finished_at'),       finished_at),
    bytes_transferred = COALESCE(sqlc.narg('bytes_transferred'), bytes_transferred)
WHERE id = sqlc.arg('id');

-- name: ListPendingTransfersByReceiver :many
-- Still-PENDING transfers addressed to a receiver, bounded to recently created ones (the
-- sender's wait window). Re-delivered as transfer:incoming when that receiver (re)connects -
-- e.g. an offline iOS device just woken by the incoming-transfer push -so it arms its P2P
-- answerer for the waiting sender's offer.
SELECT id, sender_name, file_name, file_size, file_sha256
FROM transfer_sessions
WHERE user_id = ? AND receiver_name = ? AND state = 'PENDING' AND created_at > ?
ORDER BY created_at ASC;

-- name: ExpirePendingSessions :many
UPDATE transfer_sessions
SET state       = 'CANCELLED',
    fail_reason = 'pending_timeout',
    finished_at = sqlc.arg('finished_at')
WHERE state = 'PENDING' AND created_at < sqlc.arg('cutoff')
RETURNING id, user_id, sender_name, receiver_name;
