import type { GroupMemberAction } from '@/lib/groups/groupMemberRole'
import { persistAndPushUserNotification } from '@/lib/notifications/persistUserNotification'
import type { getDb } from '@/server/db'

type AppDb = Awaited<ReturnType<typeof getDb>>

type Delivery = {
    userId: string
    type: string
    params: { groupName: string; actorName: string; targetName?: string }
}

export async function notifyGroupMemberAction(
    db: AppDb,
    {
        groupId,
        action,
        targetUserId,
        actorUserId,
    }: {
        groupId: string
        action: GroupMemberAction
        targetUserId: string
        actorUserId: string
    }
): Promise<void> {
    const group = await db.get<{ name: string }>(
        `SELECT name FROM groups WHERE group_id = ?`,
        [groupId]
    )
    if (!group) return

    const actorRow = await db.get<{ displayName: string }>(
        `SELECT display_name AS displayName FROM users WHERE user_id = ?`,
        [actorUserId]
    )
    const targetRow = await db.get<{ displayName: string }>(
        `SELECT display_name AS displayName FROM users WHERE user_id = ?`,
        [targetUserId]
    )

    const groupName = String(group.name ?? '').trim() || groupId
    const actorName = String(actorRow?.displayName ?? '').trim() || actorUserId
    const targetName = String(targetRow?.displayName ?? '').trim() || targetUserId
    const redirectUrl = `/groups/${encodeURIComponent(groupId)}`

    const memberRows = await db.all<{ userId: string }>(
        `SELECT user_id AS userId FROM user_groups WHERE group_id = ?`,
        [groupId]
    ).catch(() => [])

    const deliveries: Delivery[] = []

    switch (action) {
        case 'transfer_leader':
            deliveries.push({
                userId: targetUserId,
                type: 'group_transfer_leader_target',
                params: { groupName, actorName, targetName },
            })
            for (const row of memberRows ?? []) {
                const uid = String(row.userId ?? '').trim()
                if (!uid || uid === targetUserId) continue
                deliveries.push({
                    userId: uid,
                    type: 'group_transfer_leader_broadcast',
                    params: { groupName, actorName, targetName },
                })
            }
            break
        case 'promote_deputy':
            deliveries.push({
                userId: targetUserId,
                type: 'group_promote_deputy',
                params: { groupName, actorName, targetName },
            })
            break
        case 'demote_member':
            deliveries.push({
                userId: targetUserId,
                type: 'group_demote_member',
                params: { groupName, actorName, targetName },
            })
            break
        case 'kick':
            deliveries.push({
                userId: targetUserId,
                type: 'group_kick',
                params: { groupName, actorName, targetName },
            })
            break
        default:
            return
    }

    await Promise.all(
        deliveries.map((d) =>
            persistAndPushUserNotification(db, d.userId, d.type, d.params, redirectUrl)
        )
    )
}
