import { NextRequest, NextResponse } from 'next/server'
import { getDb } from '@/server/db'
import { getUserIdFromRequest } from '../../../_helpers/session'

export const runtime = 'nodejs'

function json(data: unknown, init?: ResponseInit) {
    return NextResponse.json(data, init)
}

export async function POST(req: NextRequest, ctx: { params: { id: string } }) {
    try {
        const roomId = String(ctx?.params?.id ?? '').trim()
        if (!roomId) return json({ ok: false, error: 'BAD_REQUEST' }, { status: 400 })

        const moderatorId = await getUserIdFromRequest(req)
        if (!moderatorId) {
            return json({ ok: false, error: 'UNAUTHORIZED', message: '請先登入' }, { status: 401 })
        }

        const body = await req.json()
        const { userId, durationMs, reason } = body

        if (!userId || typeof userId !== 'string') {
            return json({ ok: false, error: 'BAD_REQUEST', message: '缺少 userId' }, { status: 400 })
        }

        const db = await getDb()

        const stream = await db.get<{ userId: string }>(
            `SELECT room_id AS userId FROM room_streams WHERE room_id = ?`,
            [roomId]
        )
        if (!stream) {
            return json({ ok: false, error: 'NOT_FOUND', message: '房間不存在' }, { status: 404 })
        }

        const isStreamer = stream.userId === moderatorId
        const isMod = false

        if (!isStreamer && !isMod) {
            return json({ ok: false, error: 'FORBIDDEN', message: '沒有權限' }, { status: 403 })
        }

        if (userId === moderatorId) {
            return json({ ok: false, error: 'BAD_REQUEST', message: '不能禁言自己' }, { status: 400 })
        }

        if (userId === stream.userId) {
            return json({ ok: false, error: 'BAD_REQUEST', message: '不能禁言主播' }, { status: 400 })
        }

        const nowMs = Date.now()
        const nowSec = Math.floor(nowMs / 1000)
        const expiresAtSec =
            durationMs === null || durationMs === undefined ? null : Math.floor((nowMs + durationMs) / 1000)

        await db.run(
            `INSERT OR REPLACE INTO room_bans (room_id, user_id, banned_by, reason, duration_ms, banned_at, expires_at)
             VALUES (?, ?, ?, ?, ?, ?, ?)`,
            [roomId, userId, moderatorId, reason || null, durationMs || null, nowSec, expiresAtSec]
        )

        const bannedUser = await db.get<{ displayName: string }>(
            `SELECT display_name AS displayName FROM users WHERE user_id = ?`,
            [userId]
        )
        const bannedUserName = bannedUser?.displayName || userId

        const adminUser = await db.get<{ displayName: string }>(
            `SELECT display_name AS displayName FROM users WHERE user_id = ?`,
            [moderatorId]
        )
        const adminName = adminUser?.displayName || moderatorId

        const isPermanent = durationMs === null || durationMs === undefined
        const expiresAtMs = expiresAtSec === null ? null : expiresAtSec * 1000
        const remainingMs = isPermanent || expiresAtMs === null ? null : expiresAtMs - nowMs

        const targetModRow = await db.get<{ userId: string }>(
            `SELECT user_id AS userId FROM room_mods WHERE room_id = ? AND user_id = ?`,
            [roomId, userId]
        )
        const targetIsStreamer = stream.userId === userId
        const targetIsMod = !!targetModRow
        const targetUserType = targetIsStreamer ? 'streamer' : targetIsMod ? 'manager' : 'viewer'

        try {
            const wsPort = process.env.WS_PORT || '3001'
            const wsHost = process.env.WS_HOST || 'localhost'
            const notifyUrl = `http://${wsHost}:${wsPort}/notify-ban`
            await fetch(notifyUrl, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    roomId,
                    userId,
                    banInfo: {
                        isPermanent,
                        expiresAt: expiresAtMs,
                        remainingMs,
                        reason: reason || null,
                    },
                    systemMessage: {
                        bannedUserId: userId,
                        bannedUserName,
                        adminUserId: moderatorId,
                        adminName,
                        adminUserType: isStreamer ? 'streamer' : 'manager',
                        bannedAt: nowMs,
                        targetIsStreamerOrMod: false,
                        durationMs: durationMs || null,
                        reason: reason || null,
                        targetUserType,
                    },
                }),
            })
        } catch (error) {
            console.error('Failed to notify user about ban:', error)
        }

        return json({
            ok: true,
            data: {
                roomId,
                userId,
                bannedBy: moderatorId,
                reason: reason || null,
                durationMs: durationMs || null,
                bannedAt: nowSec,
                expiresAt: expiresAtSec,
                isPermanent,
            },
        })
    } catch (error: any) {
        console.error('Failed to ban user:', error)
        return json({ ok: false, error: 'INTERNAL_ERROR', message: error?.message || '操作失敗' }, { status: 500 })
    }
}

export async function DELETE(req: NextRequest, ctx: { params: { id: string } }) {
    try {
        const roomId = String(ctx?.params?.id ?? '').trim()
        if (!roomId) return json({ ok: false, error: 'BAD_REQUEST' }, { status: 400 })

        const moderatorId = await getUserIdFromRequest(req)
        if (!moderatorId) {
            return json({ ok: false, error: 'UNAUTHORIZED', message: '請先登入' }, { status: 401 })
        }

        const { searchParams } = new URL(req.url)
        const userId = searchParams.get('userId')

        if (!userId) {
            return json({ ok: false, error: 'BAD_REQUEST', message: '缺少 userId' }, { status: 400 })
        }

        const db = await getDb()

        const stream = await db.get<{ userId: string }>(
            `SELECT room_id AS userId FROM room_streams WHERE room_id = ?`,
            [roomId]
        )
        if (!stream) {
            return json({ ok: false, error: 'NOT_FOUND', message: '房間不存在' }, { status: 404 })
        }

        // 檢查是否有權限（主播或MOD）
        const isStreamer = stream.userId === moderatorId
        const isMod = false // TODO: 檢查是否為MOD

        if (!isStreamer && !isMod) {
            return json({ ok: false, error: 'FORBIDDEN', message: '沒有權限' }, { status: 403 })
        }

        const result = await db.run(`DELETE FROM room_bans WHERE room_id = ? AND user_id = ?`, [roomId, userId])

        const unbannedUser = await db.get<{ displayName: string }>(
            `SELECT display_name AS displayName FROM users WHERE user_id = ?`,
            [userId]
        )
        const unbannedUserName = unbannedUser?.displayName || userId

        const adminUser = await db.get<{ displayName: string }>(
            `SELECT display_name AS displayName FROM users WHERE user_id = ?`,
            [moderatorId]
        )
        const adminName = adminUser?.displayName || moderatorId

        const targetModRow = await db.get<{ userId: string }>(
            `SELECT user_id AS userId FROM room_mods WHERE room_id = ? AND user_id = ?`,
            [roomId, userId]
        )
        const targetIsStreamer = stream.userId === userId
        const targetIsMod = !!targetModRow
        const targetUserType = targetIsStreamer ? 'streamer' : targetIsMod ? 'manager' : 'viewer'

        try {
            const wsPort = process.env.WS_PORT || '3001'
            const wsHost = process.env.WS_HOST || 'localhost'
            const notifyUrl = `http://${wsHost}:${wsPort}/notify-ban`
            await fetch(notifyUrl, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    roomId,
                    userId,
                    banInfo: {
                        isPermanent: false,
                        expiresAt: null,
                        remainingMs: null,
                        unbanned: true,
                    },
                    systemMessage: {
                        unbannedUserId: userId,
                        unbannedUserName,
                        adminUserId: moderatorId,
                        adminName,
                        adminUserType: isStreamer ? 'streamer' : 'manager',
                        unbannedAt: Date.now(),
                        targetIsStreamerOrMod: false,
                        targetUserType,
                    },
                }),
            })
        } catch (error) {
            console.error('Failed to notify user about unban:', error)
        }

        return json({
            ok: true,
            data: {
                roomId,
                userId,
                unbanned: true,
            },
        })
    } catch (error: any) {
        console.error('Failed to unban user:', error)
        return json({ ok: false, error: 'INTERNAL_ERROR', message: error?.message || '操作失敗' }, { status: 500 })
    }
}

export async function GET(req: NextRequest, ctx: { params: { id: string } }) {
    try {
        const roomId = String(ctx?.params?.id ?? '').trim()
        if (!roomId) return json({ ok: false, error: 'BAD_REQUEST' }, { status: 400 })

        const { searchParams } = new URL(req.url)
        const userId = searchParams.get('userId')

        if (!userId) {
            return json({ ok: false, error: 'BAD_REQUEST', message: '缺少 userId' }, { status: 400 })
        }

        const db = await getDb()

        const ban = await db.get<{
            roomId: string
            userId: string
            bannedBy: string
            reason: string | null
            durationMs: number | null
            bannedAt: number
            expiresAt: number | null
        }>(
            `SELECT room_id AS roomId, user_id AS userId, banned_by AS bannedBy, reason,
                    duration_ms AS durationMs, banned_at AS bannedAt, expires_at AS expiresAt
             FROM room_bans WHERE room_id = ? AND user_id = ?`,
            [roomId, userId]
        )

        if (!ban) {
            return json({ ok: true, data: { isBanned: false } })
        }

        const nowSec = Math.floor(Date.now() / 1000)
        const isExpired = ban.expiresAt !== null && ban.expiresAt < nowSec

        if (isExpired) {
            await db.run(`DELETE FROM room_bans WHERE room_id = ? AND user_id = ?`, [roomId, userId])
            return json({ ok: true, data: { isBanned: false } })
        }

        return json({
            ok: true,
            data: {
                isBanned: true,
                roomId: ban.roomId,
                userId: ban.userId,
                bannedBy: ban.bannedBy,
                reason: ban.reason,
                durationMs: ban.durationMs,
                bannedAt: ban.bannedAt,
                expiresAt: ban.expiresAt,
                isPermanent: ban.expiresAt === null,
                remainingMs:
                    ban.expiresAt === null ? null : Math.max(0, ban.expiresAt * 1000 - Date.now()),
            },
        })
    } catch (error: any) {
        console.error('Failed to get ban status:', error)
        return json({ ok: false, error: 'INTERNAL_ERROR', message: error?.message || '操作失敗' }, { status: 500 })
    }
}

