import { cookies } from 'next/headers'
import { SESSION_ID_COOKIE } from '@/app/_helpers/constants'
import { syncRoomStreamFromCloudflareLiveInput } from '@/lib/streams/cloudflareLiveInput'
import { isStreamLiveByLifecycleStatus } from '@/lib/streams/lifecycleStatus'
import {
    parseRoomStreamCategory,
    roomStreamCategoryToTagIds,
} from '@/lib/streams/roomStreamCategory'
import { resolveRoomRouteParam } from '@/server/roomRoute'
import { getDb } from '@/server/db'
import { pickRowNumber, pickRowString, readDisplayName } from '@/server/pgRow'
import { USER_AUTH_SQL } from '@/server/userAuthSql'
import type { RoomStream } from '@/app/room/_components/types'

type DbUserRow = {
    id: string
    displayName: string
    avatar: string | null
    followersCount: number
    isVerified: number
    vipLevel: string
}

type DbStreamRow = {
    roomId: string
    userId: string
    streamStatus: string | null
    title: string
    description: string | null
    likes: number
    startedAt: string | number | null
    category: string | null
    thumbnail: string | null
    src: string | null
    liveInputIdentifier: string | null
}

export type LoadedRoomPlaybackData = {
    roomId: string
    publicRoomId: string
    shouldRedirect: boolean
    stream: RoomStream
    isLive: boolean
    playbackSrc: string
}

export async function loadRoomPlaybackData(routeParam: string): Promise<LoadedRoomPlaybackData | null> {
    const param = String(routeParam ?? '').trim()
    if (!param) return null

    const db = await getDb()
    const resolvedRoom = await resolveRoomRouteParam(db, param)
    if (!resolvedRoom) return null

    const roomId = resolvedRoom.roomId

    let streamRow = await db.get<DbStreamRow>(
        `SELECT 
            rs.room_id AS roomId,
            rs.room_id AS userId,
            rs.stream_status AS streamStatus,
            rs.title,
            rs.description,
            (SELECT COUNT(1) FROM room_stream_likes l WHERE l.room_id = rs.room_id) AS likes,
            rs.started_at AS startedAt,
            rs.category,
            rs.thumbnail_url AS thumbnail,
            rs.stream_token AS src,
            rs.live_input_identifier AS liveInputIdentifier
         FROM room_streams rs WHERE rs.room_id = ?`,
        [roomId]
    )

    const liveInputIdentifier = pickRowString(
        streamRow as Record<string, unknown> | undefined,
        'liveInputIdentifier',
        'live_input_identifier'
    )
    if (liveInputIdentifier) {
        const syncResult = await syncRoomStreamFromCloudflareLiveInput(db, roomId)
        if (syncResult.ok) {
            streamRow = await db.get<DbStreamRow>(
                `SELECT 
                    rs.room_id AS roomId,
                    rs.room_id AS userId,
                    rs.stream_status AS streamStatus,
                    rs.title,
                    rs.description,
                    (SELECT COUNT(1) FROM room_stream_likes l WHERE l.room_id = rs.room_id) AS likes,
                    rs.started_at AS startedAt,
                    rs.category,
                    rs.thumbnail_url AS thumbnail,
                    rs.stream_token AS src,
                    rs.live_input_identifier AS liveInputIdentifier
                 FROM room_streams rs WHERE rs.room_id = ?`,
                [roomId]
            )
        } else {
            console.error(`[room/${roomId}] Cloudflare live input sync failed:`, syncResult.error)
        }
    }

    const likesFromReactions = Number(streamRow?.likes ?? 0)
    const userId = pickRowString(streamRow as Record<string, unknown> | undefined, 'userId', 'user_id') || roomId
    const user = await db.get<DbUserRow & { ownerDisplayId: string | null }>(
        `SELECT u.user_id AS id, u.display_name AS displayName, u.avatar_url AS avatar,
                TRIM(u.display_id) AS ownerDisplayId,
                (SELECT COUNT(1) FROM user_actions f WHERE f.target_id = u.user_id AND f.action_type = 'follow') AS followersCount,
                u.is_verified AS isVerified, 'none' AS vipLevel
         FROM users u WHERE u.user_id = ?`,
        [userId]
    )

    const userIdFromRow = pickRowString(user as Record<string, unknown> | undefined, 'id', 'user_id')
    if (!userIdFromRow) return null

    const fallbackSrc = 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4'
    const streamSrc = (streamRow?.src ?? '').trim()
    const isLive = isStreamLiveByLifecycleStatus(streamRow?.streamStatus)
    const playbackSrc = streamSrc || fallbackSrc

    const row = user as Record<string, unknown>
    const rawVip = (row.vipLevel ?? row.viplevel ?? 'none').toString().trim().toLowerCase()
    const vipLevel: 'none' | 'vip' | 'vvip' =
        rawVip === 'vip' || rawVip === 'vvip' ? rawVip : 'none'

    const ownerDisplayId = String(user?.ownerDisplayId ?? '').trim() || null
    const stream: RoomStream = {
        id: roomId,
        userId,
        ownerDisplayId,
        title: streamRow?.title ?? '',
        description: String(streamRow?.description ?? '').trim(),
        category: parseRoomStreamCategory(streamRow?.category),
        channelName: readDisplayName(user as Record<string, unknown>),
        avatar: pickRowString(user as Record<string, unknown>, 'avatar', 'avatar_url'),
        viewers: 0,
        likes: likesFromReactions,
        followers: pickRowNumber(user as Record<string, unknown>, 'followersCount', 'followerscount'),
        startedAt: String(streamRow?.startedAt ?? '').trim(),
        tags: roomStreamCategoryToTagIds(streamRow?.category),
        isVerified: Boolean(user?.isVerified === 1),
        vipLevel,
    }

    return {
        roomId,
        publicRoomId: resolvedRoom.publicRoomId,
        shouldRedirect: resolvedRoom.shouldRedirect,
        stream,
        isLive,
        playbackSrc,
    }
}

export type RoomPageSessionUser = {
    currentUserId: string | null
    currentUserDisplayName: string | null
    currentUserAvatar: string | null
    initialIsLiked: boolean
    initialIsFollowing: boolean
}

/** 房間頁／儀表板用：讀取登入者與按讚／追蹤狀態 */
export async function loadRoomPageSessionUser(
    roomId: string,
    streamUserId: string
): Promise<RoomPageSessionUser> {
    let currentUserId: string | null = null
    let currentUserDisplayName: string | null = null
    let currentUserAvatar: string | null = null

    try {
        const sessionId = cookies().get(SESSION_ID_COOKIE)?.value
        if (sessionId) {
            const db = await getDb()
            const session = await db.get<Record<string, unknown>>(
                USER_AUTH_SQL.selectSessionUserId,
                [sessionId]
            )
            const sessionUserId = pickRowString(session, 'userId', 'user_id')
            if (sessionUserId) {
                currentUserId = sessionUserId
                const currentUser = await db.get<Record<string, unknown>>(
                    `SELECT display_name AS displayName, avatar_url AS avatar FROM users WHERE user_id = ?`,
                    [sessionUserId]
                )
                if (currentUser) {
                    currentUserDisplayName = readDisplayName(currentUser)
                    currentUserAvatar =
                        pickRowString(currentUser, 'avatar', 'avatar_url') || null
                }
            }
        }
    } catch (error) {
        console.error('Failed to get current user ID:', error)
    }

    let initialIsLiked = false
    let initialIsFollowing = false

    if (currentUserId) {
        const db = await getDb()
        initialIsLiked = Boolean(
            (
                await db.get<{ c: number }>(
                    `SELECT 1 as c FROM room_stream_likes WHERE room_id = ? AND user_id = ? LIMIT 1`,
                    [roomId, currentUserId]
                )
            )?.c
        )
        initialIsFollowing = Boolean(
            (
                await db.get<{ c: number }>(
                    `SELECT 1 AS c FROM user_actions WHERE user_id = ? AND target_id = ? AND action_type = 'follow' LIMIT 1`,
                    [currentUserId, streamUserId]
                )
            )?.c
        )
    }

    return {
        currentUserId,
        currentUserDisplayName,
        currentUserAvatar,
        initialIsLiked,
        initialIsFollowing,
    }
}
