import { Signaling, WebSocketSignaling } from '/module/core/signaling.js';
import { createLogger } from '../../shared/logger.js';

const logger = createLogger('signaling');

const INVITE_EVENT_NAMES = Object.freeze([
    'invite-call',
    'invite-accepted',
    'invite-rejected',
    'invite-failed'
]);

const DEFAULT_SOCKET_USER_NAME = '?';
const DEFAULT_SOCKET_USER_AVATAR = '/images/p1.png';

export function createSignalingInstance(useWebSocket) {
    return useWebSocket ? new WebSocketSignaling() : new Signaling();
}

export async function ensureSignalingStarted(existingSignaling, useWebSocket) {
    if (existingSignaling) {
        return {
            signaling: existingSignaling,
            reused: true
        };
    }

    const signaling = createSignalingInstance(useWebSocket);
    await signaling.start();

    return {
        signaling,
        reused: false
    };
}

export function bindInviteSocketEvents(signaling, eventHandlers, boundSignaling = null) {
    if (!signaling || signaling === boundSignaling || typeof signaling.addEventListener !== 'function') {
        return boundSignaling;
    }

    INVITE_EVENT_NAMES.forEach((eventName) => {
        signaling.addEventListener(eventName, (event) => {
            const handler = eventHandlers[eventName];
            if (typeof handler === 'function') {
                handler(event.detail);
            }
        });
    });

    return signaling;
}

export function getActiveSignalingInstance(preconnectedSignaling, renderstreaming) {
    if (preconnectedSignaling) {
        return preconnectedSignaling;
    }

    if (renderstreaming && renderstreaming._signaling) {
        return renderstreaming._signaling;
    }

    return null;
}

export function sendInviteSignal(signaling, methodName, payload) {
    if (!signaling || typeof signaling[methodName] !== 'function') {
        throw new Error('Invite signaling is not ready');
    }

    signaling[methodName](payload);
}

function readStoredSocketUserInfo() {
    try {
        return JSON.parse(localStorage.getItem('userSettings') || '{}');
    } catch (error) {
        logger.error('Error parsing user settings:', error);
        return {};
    }
}

export function buildSocketUserInfoPayload(userInfo, localUser) {
    const settings = userInfo || readStoredSocketUserInfo();

    return {
        id: settings.id || settings.userId || localUser.id || '',
        name: settings.name || localUser.name || DEFAULT_SOCKET_USER_NAME,
        avatar: settings.avatar || localUser.avatar || DEFAULT_SOCKET_USER_AVATAR
    };
}

export function sendSocketUserInfo(signaling, payload) {
    if (!signaling) {
        return;
    }

    if (typeof signaling.sendUserInfo === 'function') {
        signaling.sendUserInfo(payload);
        return;
    }

    if (typeof signaling.sendMessage !== 'function') {
        return;
    }

    signaling.sendMessage('', {
        type: 'user-info',
        data: payload
    });
}
