import { getDb } from '@/server/db'
import { USER_AUTH_SQL } from '@/server/userAuthSql'
import {
    CREATE_LIVE_INPUT_HASH_ACTION,
    createDashboardActionHash,
} from '@/lib/api/dashboardActionHash'
import {
    fetchCloudflareLiveInput,
    mapLiveInputToRoomStreamFields,
    parseLiveInputApiId,
    syncRoomStreamFromCloudflareLiveInput,
} from '@/lib/streams/cloudflareLiveInput'
import { resolveStreamPublishUrl } from '@/lib/streams/cloudflareStreamUrls'
import { isStreamLiveByLifecycleStatus } from '@/lib/streams/lifecycleStatus'
import { sanitizeStreamTitleForDashboard } from '@/lib/streams/streamTitle'
import DashboardPageClient from './DashboardPageClient'
import { cookies, headers } from 'next/headers'
import { redirect } from 'next/navigation'
import { SESSION_ID_COOKIE } from '@/app/_helpers/constants'
import { buildLoginUrl, getAppOriginFromEnv, getAppOriginFromHeaders } from '@/lib/url/appUrl'
import { pickRowString, readDisplayName } from '@/server/pgRow'

const DASHBOARD_PATH = '/room/dashboard'
export const runtime = 'nodejs'
export const dynamic = 'force-dynamic'

type DbUserRow = {
    id: string
    displayName: string
    avatar: string | null
}

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

export default async function DashboardPage() {
    const db = await getDb()

    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 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 user_id AS id, 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)
    }

    if (!currentUserId) {
        const sessionId = cookies().get(SESSION_ID_COOKIE)?.value
        const appOrigin =
            getAppOriginFromEnv() || getAppOriginFromHeaders(headers())
        if (sessionId) {
            const clearPath = `/api/auth/clear-session?redirect=${encodeURIComponent(DASHBOARD_PATH)}`
            redirect(appOrigin ? `${appOrigin}${clearPath}` : clearPath)
        }
        redirect(buildLoginUrl(DASHBOARD_PATH, appOrigin))
    }

    const roomId = currentUserId
    const ownerRow = await db.get<{ displayId: string | null }>(
        `SELECT display_id AS displayId FROM users WHERE user_id = ?`,
        [roomId]
    )
    const roomPublicId = String(ownerRow?.displayId ?? '').trim() || 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,
            rs.started_at AS startedAt,
            rs.updated_at AS uploadedAt,
            rs.thumbnail_url AS thumbnail,
            rs.category,
            rs.attribute,
            rs.stream_token AS src,
            rs.live_input_identifier AS liveInputIdentifier
         FROM room_streams rs WHERE rs.room_id = ?`,
        [roomId]
    )

    let liveInputIdentifier = String(streamRow?.liveInputIdentifier ?? '').trim()
    let webrtcPublishUrl: string | null = null

    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,
                    rs.started_at AS startedAt,
                    rs.updated_at AS uploadedAt,
                    rs.thumbnail_url AS thumbnail,
                    rs.category,
                    rs.attribute,
                    rs.stream_token AS src,
                    rs.live_input_identifier AS liveInputIdentifier
                 FROM room_streams rs WHERE rs.room_id = ?`,
                [roomId]
            )
            liveInputIdentifier = String(streamRow?.liveInputIdentifier ?? '').trim()
        } else {
            console.error('[dashboard] Cloudflare live input sync failed:', syncResult.error)
        }

        const apiId = parseLiveInputApiId(liveInputIdentifier)
        if (apiId) {
            const fetched = await fetchCloudflareLiveInput(apiId)
            if (fetched.ok) {
                const cfPublish =
                    mapLiveInputToRoomStreamFields(fetched.result).webrtc_publish_url
                webrtcPublishUrl =
                    resolveStreamPublishUrl(liveInputIdentifier) ||
                    cfPublish
            }
        }

        if (!webrtcPublishUrl && liveInputIdentifier) {
            webrtcPublishUrl = resolveStreamPublishUrl(liveInputIdentifier) || null
        }
    }

    const streamToken = (streamRow?.src ?? '').trim()

    const initialData = {
        roomId,
        roomPublicId,
        title: sanitizeStreamTitleForDashboard(streamRow?.title, roomId, roomPublicId),
        description: String(streamRow?.description ?? '').trim(),
        streamToken,
        liveInputIdentifier,
        webrtcPublishUrl,
        createLiveInputHash: createDashboardActionHash(roomId, CREATE_LIVE_INPUT_HASH_ACTION),
        thumbnail: streamRow?.thumbnail ?? '',
        category: streamRow?.category ?? '',
        attribute: streamRow?.attribute ?? '',
        startedAt: String(streamRow?.startedAt ?? '').trim(),
        isLive: isStreamLiveByLifecycleStatus(streamRow?.streamStatus),
    }

    return (
        <DashboardPageClient
            initialData={initialData}
            currentUserId={currentUserId}
            currentUserDisplayName={currentUserDisplayName}
            currentUserAvatar={currentUserAvatar}
        />
    )
}

