import type { ChatMessage } from '../types'

/** 是否可見僅管理員／當事人可見的系統訊息 */
export function canViewModeratorOnlySystemMessage(
    message: ChatMessage,
    currentUserId: string | null | undefined,
    isModerator: boolean
): boolean {
    if (!message.isModeratorOnly) return true
    const uid = currentUserId
    // 當事人另有專屬訊息；略過管理端廣播版（含剛被指定為 Mod 者，避免與 isModerator 重複顯示）
    if (uid) {
        if (message.systemMessageType === 'modAdded' && message.moddedUserId === uid) {
            return false
        }
        if (message.systemMessageType === 'modRemoved' && message.unmoddedUserId === uid) {
            return false
        }
        if (message.systemMessageType === 'banAdded' && message.bannedUserId === uid) {
            return false
        }
        if (message.systemMessageType === 'banRemoved' && message.unbannedUserId === uid) {
            return false
        }
    }
    if (isModerator) return true
    if (!uid) return false
    return false
}

function banSystemMessageKey(message: ChatMessage): string | null {
    if (message.systemMessageType === 'banAdded' && message.bannedUserId) {
        return `banAdded:${message.bannedUserId}`
    }
    if (message.systemMessageType === 'banRemoved' && message.unbannedUserId) {
        return `banRemoved:${message.unbannedUserId}`
    }
    return null
}

/** 補齊舊版 WS 缺少的禁言 systemMessageType */
export function normalizeBanSystemMessage(message: ChatMessage): ChatMessage {
    if (message.systemMessageType || !message.isSystem) return message
    if (message.bannedUserId) {
        return { ...message, systemMessageType: 'banAdded' }
    }
    if (message.unbannedUserId) {
        return { ...message, systemMessageType: 'banRemoved' }
    }
    return message
}

export function buildOptimisticBanSystemMessage(params: {
    action: 'banAdded' | 'banRemoved'
    targetUserId: string
    targetUserName: string
    adminUserId: string
    adminUserName: string
    adminUserType: 'streamer' | 'manager' | 'superAdmin'
    durationMs?: number | null
    reason?: string | null
}): ChatMessage {
    const now = Date.now()
    const isPermanent =
        params.action === 'banAdded' && (params.durationMs === null || params.durationMs === undefined)
    return {
        id: `local-ban-${params.action}-${params.targetUserId}-${now}`,
        author: '',
        text: '',
        isSystem: true,
        isModeratorOnly: true,
        userId: null,
        time: new Date(now).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
        bannedUserId: params.action === 'banAdded' ? params.targetUserId : undefined,
        unbannedUserId: params.action === 'banRemoved' ? params.targetUserId : undefined,
        adminUserId: params.adminUserId,
        adminUserType: params.adminUserType,
        systemMessageType: params.action,
        systemMessageData: {
            userName: params.targetUserName,
            adminName: params.adminUserName,
            durationMs: params.durationMs ?? null,
            isPermanent,
            reason: params.reason ?? null,
            targetUserType: 'viewer',
        },
    }
}

export function appendOptimisticBanSystemMessage(prev: ChatMessage[], message: ChatMessage): ChatMessage[] {
    const filtered = prev.filter(
        (m) =>
            !(
                m.id.startsWith('local-ban-') &&
                m.systemMessageType === message.systemMessageType &&
                (m.bannedUserId === message.bannedUserId || m.unbannedUserId === message.unbannedUserId)
            )
    )
    return [...filtered, message]
}

export function mergeIncomingBanSystemMessage(prev: ChatMessage[], incoming: ChatMessage): ChatMessage[] {
    const incomingBanKey = banSystemMessageKey(incoming)
    const withoutLocal = prev.filter(
        (m) =>
            !(
                m.id.startsWith('local-ban-') &&
                m.systemMessageType === incoming.systemMessageType &&
                (m.bannedUserId === incoming.bannedUserId || m.unbannedUserId === incoming.unbannedUserId)
            )
    )
    const withoutDuplicateBan =
        incomingBanKey != null
            ? withoutLocal.filter((m) => banSystemMessageKey(m) !== incomingBanKey)
            : withoutLocal
    if (withoutDuplicateBan.some((m) => m.id === incoming.id)) {
        return withoutDuplicateBan
    }
    return [...withoutDuplicateBan, incoming]
}

export function resolveViewerCardIsBanned(
    userId: string,
    bannedUserIds: Set<string>,
    viewerCardBanStatus: { userId: string; isBanned: boolean } | null
): boolean {
    if (bannedUserIds.has(userId)) return true
    return viewerCardBanStatus?.userId === userId && viewerCardBanStatus.isBanned
}
