import { NextRequest, NextResponse } from 'next/server'
import { getUserIdFromRequest } from '@/app/api/_helpers/session'
import { GROUP_MEMBERS_LIST_ORDER_SQL } from '@/lib/groups/groupMemberRole'
import { resolveMediaUrl } from '@/lib/media/resolveMediaUrl'
import { getGroupApplyContext, isGroupMember } from '@/server/groups/groupApply'
import {
    assertGroupLeader,
    updateGroupByLeader,
    UpdateGroupError,
} from '@/server/groups/updateGroupByLeader'
import { GROUP_LOG_ACTION } from '@/lib/groups/groupLogActions'
import { getDb } from '@/server/db'
import { isGroupLeaderRole } from '@/lib/groups/groupMemberRole'
import { logGroupAction } from '@/server/groups/insertGroupLog'
import { resolveGroupIdFromParam } from '@/server/groups/groupIdUtils'

export const runtime = 'nodejs'
export const dynamic = 'force-dynamic'

export async function GET(
    request: NextRequest,
    { params }: { params: { id: string } }
) {
    try {
        const routeParam = String(params?.id ?? '').trim()
        if (!routeParam) {
            return NextResponse.json(
                { ok: false, message: 'Group ID is required' },
                { status: 400 }
            )
        }

        const db = await getDb()
        const groupId = await resolveGroupIdFromParam(db, routeParam)
        if (!groupId) {
            return NextResponse.json({ ok: false, message: 'Group not found' }, { status: 404 })
        }

        const viewerUserId = await getUserIdFromRequest(request)

        // 获取家族基本信息
        const group = await db.get<{
            id: string
            name: string
            avatar: string | null
            banner: string | null
            isVerified: number
            isCanApplicapplication: number
            groupLevelExp: number
            createdAt: number
            updatedAt: number
            artistsCount: number
            membersCount: number
        }>(
            `SELECT
                g.display_id AS id,
                g.name,
                g.avatar_url AS avatar,
                g.banner_url AS banner,
                g.is_verified AS isVerified,
                g.is_can_application AS isCanApplicapplication,
                g.group_level_exp AS groupLevelExp,
                g.created_at AS createdAt,
                g.updated_at AS updatedAt,
                (SELECT COUNT(1) FROM user_groups ug WHERE ug.group_id = g.group_id AND ug.role = 'artist') AS artistsCount,
                (SELECT COUNT(1) FROM user_groups ug WHERE ug.group_id = g.group_id) AS membersCount
             FROM groups g WHERE g.group_id = ?`,
            [groupId]
        )
        if (!group) {
            return NextResponse.json({ ok: false, message: 'Group not found' }, { status: 404 })
        }

        const viewerIsMember = viewerUserId
            ? await isGroupMember(db, groupId, viewerUserId)
            : false

        type GroupMemberRow = {
            id: string
            displayName: string
            avatar: string | null
            followersCount: number
            totalViewsCount: number
            role: string
            contribution: number
            joinAt: number
        }

        // 僅家族成員可查看成員列表
        const members: GroupMemberRow[] = viewerIsMember
            ? await db
                  .all<GroupMemberRow>(
                      `SELECT u.user_id AS id, u.display_name AS displayName, u.avatar_url AS avatar,
                    (SELECT COUNT(1) FROM user_actions f WHERE f.target_id = u.user_id AND f.action_type = 'follow') AS followersCount,
                    0 AS totalViewsCount, ug.role, ug.contribution, ug.join_at AS joinAt
             FROM users u
             INNER JOIN user_groups ug ON u.user_id = ug.user_id
             WHERE ug.group_id = ?
             ORDER BY ${GROUP_MEMBERS_LIST_ORDER_SQL}`,
                      [groupId]
                  )
                  .catch(() => [] as GroupMemberRow[])
            : []

        type GroupLiveStreamRow = {
            roomId: string
            userId: string
            displayId: string | null
            title: string
            viewers: number
            thumbnail: string | null
            startedAt: string | number | null
            streamStatus: string | null
            displayName: string
            avatar: string | null
        }

        // 获取家族相关的直播
        const liveStreams = await db
            .all<GroupLiveStreamRow>(
                `SELECT rs.room_id AS roomId, rs.room_id AS userId, NULLIF(TRIM(u.display_id), '') AS displayId, rs.title, 0 AS viewers,
                    rs.thumbnail_url AS thumbnail, rs.started_at AS startedAt, rs.stream_status AS streamStatus,
                    u.display_name AS displayName, u.avatar_url AS avatar
             FROM room_streams rs
             INNER JOIN users u ON rs.room_id = u.user_id
             INNER JOIN user_groups ug ON u.user_id = ug.user_id
             WHERE ug.group_id = ? AND rs.stream_status IN ('ready', 'initializing', 'connected', 'streaming', 'live', 'live-inprogress', 'reconnected')
             ORDER BY (SELECT COUNT(1) FROM room_stream_likes l WHERE l.room_id = rs.room_id) DESC,
                      COALESCE(rs.started_at, rs.created_at) DESC
             LIMIT 10`,
                [groupId]
            )
            .catch(() => [] as GroupLiveStreamRow[])

        const applyContext = await getGroupApplyContext(db, groupId, viewerUserId)

        let canManageGroupSettings = false
        if (viewerUserId) {
            const leaderRow = await db.get<{ role: string }>(
                `SELECT role FROM user_groups WHERE group_id = ? AND user_id = ?`,
                [groupId, viewerUserId]
            )
            canManageGroupSettings = Boolean(leaderRow && isGroupLeaderRole(leaderRow.role))
        }

        return NextResponse.json({
            ok: true,
            data: {
                id: group.id,
                name: group.name,
                avatar: resolveMediaUrl(group.avatar) || null,
                banner: resolveMediaUrl(group.banner) || null,
                description: null,
                isVerified: Boolean(group.isVerified),
                isCanApplicapplication: applyContext.isCanApplicapplication,
                groupLevelExp: group.groupLevelExp ?? 0,
                artistsCount: group.artistsCount,
                membersCount: group.membersCount,
                createdAt: group.createdAt,
                updatedAt: group.updatedAt,
                canManageGroupSettings,
                canReviewApplications: applyContext.canReviewApplications,
                pendingApplications: applyContext.pendingApplications,
                members: members.map((m) => ({
                    ...m,
                    avatar: resolveMediaUrl(m.avatar) || null,
                    contribution: Number(m.contribution) || 0,
                    joinAt: m.joinAt ?? 0,
                })),
                liveStreams: liveStreams.map((ls) => ({
                    ...ls,
                    roomId: ls.displayId || ls.roomId,
                })),
            },
        })
    } catch (error: any) {
        console.error('Failed to fetch family data:', error)
        return NextResponse.json(
            { ok: false, message: error?.message || 'Failed to fetch family data' },
            { status: 500 }
        )
    }
}

export async function PATCH(
    request: NextRequest,
    { params }: { params: { id: string } }
) {
    try {
        const routeParam = String(params?.id ?? '').trim()
        const actorId = await getUserIdFromRequest(request)

        if (!routeParam) {
            return NextResponse.json({ ok: false, message: 'Invalid group id' }, { status: 400 })
        }
        if (!actorId) {
            return NextResponse.json({ ok: false, message: 'Unauthorized' }, { status: 401 })
        }

        const db = await getDb()
        const groupId = await resolveGroupIdFromParam(db, routeParam)
        if (!groupId) {
            return NextResponse.json({ ok: false, message: 'Group not found' }, { status: 404 })
        }

        await assertGroupLeader(db, groupId, actorId)

        const body = (await request.json().catch(() => ({}))) as Record<string, unknown>
        await updateGroupByLeader(db, groupId, {
            name: body.name,
            isCanApplicapplication: body.isCanApplicapplication,
            avatarUrl: body.avatarUrl,
            bannerUrl: body.bannerUrl,
            removeBanner: body.removeBanner,
        })

        if (body.name !== undefined) {
            logGroupAction(db, {
                groupId,
                userId: actorId,
                actionContent: GROUP_LOG_ACTION.SETTINGS_NAME,
            })
        }
        if (body.isCanApplicapplication !== undefined) {
            logGroupAction(db, {
                groupId,
                userId: actorId,
                actionContent: GROUP_LOG_ACTION.SETTINGS_APPLICATION,
            })
        }
        if (body.avatarUrl !== undefined) {
            logGroupAction(db, {
                groupId,
                userId: actorId,
                actionContent: GROUP_LOG_ACTION.SETTINGS_AVATAR,
            })
        }
        if (body.bannerUrl !== undefined) {
            logGroupAction(db, {
                groupId,
                userId: actorId,
                actionContent: GROUP_LOG_ACTION.SETTINGS_BANNER,
            })
        }
        if (body.removeBanner === true) {
            logGroupAction(db, {
                groupId,
                userId: actorId,
                actionContent: GROUP_LOG_ACTION.SETTINGS_BANNER_REMOVED,
            })
        }

        const row = await db.get<{
            id: string
            name: string
            avatar: string | null
            banner: string | null
            isCanApplicapplication: number
        }>(
            `SELECT
                display_id AS id,
                name,
                avatar_url AS avatar,
                banner_url AS banner,
                is_can_application AS isCanApplicapplication
             FROM groups WHERE group_id = ?`,
            [groupId]
        )

        return NextResponse.json({
            ok: true,
            data: {
                id: row?.id,
                name: row?.name,
                avatar: resolveMediaUrl(row?.avatar) || null,
                banner: resolveMediaUrl(row?.banner) || null,
                isCanApplicapplication: Boolean(row?.isCanApplicapplication),
            },
        })
    } catch (error: unknown) {
        if (error instanceof UpdateGroupError) {
            const status =
                error.code === 'FORBIDDEN'
                    ? 403
                    : error.code === 'NOT_FOUND'
                      ? 404
                      : error.code === 'NO_CHANGES'
                        ? 400
                        : 400
            return NextResponse.json({ ok: false, message: error.message }, { status })
        }
        console.error('Failed to update family settings:', error)
        return NextResponse.json(
            {
                ok: false,
                message: error instanceof Error ? error.message : 'Failed to update family settings',
            },
            { status: 500 }
        )
    }
}

