import { NextRequest, NextResponse } from 'next/server'
import type { AvatarFramePayload } from '@/lib/avatarFrames/types'
import { setUserEquippedAvatarFrame } from '@/server/avatarFrames/mutate'
import { fetchUserAvatarFrames } from '@/server/avatarFrames/query'
import { getUserIdFromRequest } from '@/app/api/_helpers/session'
import { getDb } from '@/server/db'
import { resolveUserKeyToUserId } from '@/server/userIdUtils'

function serializeActiveFrame(frame: AvatarFramePayload | null) {
    if (!frame) return null
    return { id: frame.id, image: frame.image }
}

export const runtime = 'nodejs'

async function resolveTargetUserId(userKey: string) {
    const key = String(userKey ?? '').trim()
    if (!key) return null
    const db = await getDb()
    const userId = await resolveUserKeyToUserId(db, key)
    return userId ? { db, userId } : null
}

export async function GET(_request: Request, ctx: { params: { id: string } }) {
    const resolved = await resolveTargetUserId(ctx?.params?.id ?? '')
    if (!resolved) {
        return NextResponse.json({ ok: false, error: 'NOT_FOUND' }, { status: 404 })
    }

    const frames = await fetchUserAvatarFrames(resolved.db, resolved.userId)
    return NextResponse.json({
        ok: true,
        data: {
            frames,
            total: frames.length,
        },
    })
}

export async function PATCH(request: NextRequest, ctx: { params: { id: string } }) {
    const sessionUserId = await getUserIdFromRequest(request)
    if (!sessionUserId) {
        return NextResponse.json({ ok: false, error: 'UNAUTHORIZED' }, { status: 401 })
    }

    const resolved = await resolveTargetUserId(ctx?.params?.id ?? '')
    if (!resolved) {
        return NextResponse.json({ ok: false, error: 'NOT_FOUND' }, { status: 404 })
    }

    if (sessionUserId !== resolved.userId) {
        return NextResponse.json({ ok: false, error: 'FORBIDDEN' }, { status: 403 })
    }

    let body: { frameId?: string | null }
    try {
        body = await request.json()
    } catch {
        return NextResponse.json({ ok: false, error: 'INVALID_BODY' }, { status: 400 })
    }

    const frameId =
        body.frameId === null || body.frameId === undefined ? null : String(body.frameId).trim()
    if (frameId !== null && !frameId) {
        return NextResponse.json({ ok: false, error: 'INVALID_FRAME' }, { status: 400 })
    }

    const result = await setUserEquippedAvatarFrame(resolved.db, resolved.userId, frameId)
    if (!result.ok) {
        return NextResponse.json({ ok: false, error: result.error }, { status: 400 })
    }

    const frames = await fetchUserAvatarFrames(resolved.db, resolved.userId)
    return NextResponse.json({
        ok: true,
        data: {
            frames,
            activeFrame: serializeActiveFrame(result.activeFrame),
            total: frames.length,
        },
    })
}
