import { createLogger } from '../../shared/logger.js';

const logger = createLogger('invite');
const DEFAULT_CALLER_NAME = '\u9080\u8bf7\u65b9';
const DEFAULT_CALLER_AVATAR = '/images/p2.png';
const DEFAULT_APPLY_REASON = '\u672a\u586b\u5199';

function readConnectionIdFromSearch(search) {
    return new URLSearchParams(search).get('connectionId') || '';
}

function hideInviteDialog() {
    const dialog = document.getElementById('callRequestDialog');
    if (dialog) {
        dialog.classList.add('hidden');
    }
}

function normalizeInviteCaller(caller = {}) {
    return {
        connectionId: caller.connectionId || '',
        inviterSocketId: caller.inviterSocketId || '',
        inviterUserId: caller.inviterUserId || '',
        name: caller.name || caller.inviterName || DEFAULT_CALLER_NAME,
        avatar: caller.avatar || caller.inviterAvatar || DEFAULT_CALLER_AVATAR,
        applyReason: caller.applyReason || caller.reason || DEFAULT_APPLY_REASON
    };
}

function renderInviteDialog(caller) {
    const dialog = document.getElementById('callRequestDialog');
    if (!dialog) {
        return false;
    }

    const callRequestName = document.getElementById('callRequestName');
    const callRequestAvatar = document.getElementById('callRequestAvatar');
    const callRequestText = document.getElementById('callRequestText');
    const callRequestReason = document.getElementById('callRequestReason');

    if (callRequestName) {
        callRequestName.textContent = caller.name;
    }
    if (callRequestAvatar) {
        callRequestAvatar.src = caller.avatar;
    }
    if (callRequestText) {
        callRequestText.textContent = caller.connectionId
            ? `\u6b63\u5728\u9080\u8bf7\u60a8\u52a0\u5165\u901a\u8bdd (${caller.connectionId})`
            : '\u6b63\u5728\u8bf7\u6c42\u4e0e\u60a8\u8fdb\u884c\u89c6\u9891\u901a\u8bdd';
    }
    if (callRequestReason) {
        callRequestReason.textContent = caller.applyReason;
    }

    dialog.classList.remove('hidden');
    return true;
}

export function createInviteController({
    store,
    notify,
    onAcceptConnection,
    getCurrentView,
    getConnectionId,
    setConnectionId
}) {
    let pendingInvite = null;
    let signalHandlersBound = false;

    function showCallRequestDialog(caller = {}) {
        const normalizedCaller = normalizeInviteCaller(caller);
        pendingInvite = normalizedCaller;

        if (normalizedCaller.connectionId) {
            setConnectionId(normalizedCaller.connectionId);
        }

        return renderInviteDialog(normalizedCaller);
    }

    function getInvitePayloadFromUrl(search = window.location.search) {
        const params = new URLSearchParams(search);
        if (params.get('invite') !== '1') {
            return null;
        }

        return normalizeInviteCaller({
            name: params.get('callerName'),
            avatar: params.get('callerAvatar'),
            connectionId: params.get('connectionId')
        });
    }

    function bindSignalHandlers() {
        if (signalHandlersBound) {
            return;
        }

        store.onSocketEvent('invite-call', (payload) => {
            const caller = normalizeInviteCaller(payload);
            showCallRequestDialog(caller);
            notify(`${caller.name} \u9080\u8bf7\u4f60\u52a0\u5165\u901a\u8bdd`);
        });

        signalHandlersBound = true;
    }

    async function acceptInvite() {
        hideInviteDialog();

        const targetConnectionId =
            (pendingInvite && pendingInvite.connectionId) ||
            getConnectionId() ||
            localStorage.getItem('connectionId') ||
            readConnectionIdFromSearch(window.location.search);

        if (!targetConnectionId) {
            notify('\u7f3a\u5c11\u8fde\u63a5ID\uff0c\u65e0\u6cd5\u63a5\u53d7\u9080\u8bf7', 'error');
            return;
        }

        setConnectionId(targetConnectionId);

        if (pendingInvite) {
            try {
                store.sendInviteAccepted({
                    connectionId: targetConnectionId,
                    targetSocketId: pendingInvite.inviterSocketId,
                    targetUserId: pendingInvite.inviterUserId
                });
            } catch (error) {
                logger.error('Error accepting invite:', error);
                notify('\u63a5\u53d7\u9080\u8bf7\u5931\u8d25\uff0c\u8bf7\u7a0d\u540e\u91cd\u8bd5', 'error');
                return;
            }
        }

        pendingInvite = null;
        notify('\u5df2\u63a5\u53d7\u901a\u8bdd\u8bf7\u6c42');

        if (getCurrentView() !== 'call') {
            await onAcceptConnection(targetConnectionId);
        }
    }

    function rejectInvite() {
        hideInviteDialog();

        if (pendingInvite) {
            try {
                store.sendInviteRejected({
                    connectionId: pendingInvite.connectionId,
                    targetSocketId: pendingInvite.inviterSocketId,
                    targetUserId: pendingInvite.inviterUserId
                });
            } catch (error) {
                logger.error('Error rejecting invite:', error);
            }
        }

        pendingInvite = null;
        notify('\u5df2\u62d2\u7edd\u901a\u8bdd\u8bf7\u6c42');
    }

    function bindDialogEvents() {
        window.showCallRequest = showCallRequestDialog;
        window.rejectCall = rejectInvite;
        window.acceptCall = acceptInvite;

        const rejectCallButton = document.getElementById('rejectCall');
        const acceptCallButton = document.getElementById('acceptCall');

        if (rejectCallButton && !rejectCallButton.dataset.bound) {
            rejectCallButton.addEventListener('click', rejectInvite);
            rejectCallButton.dataset.bound = 'true';
        }
        if (acceptCallButton && !acceptCallButton.dataset.bound) {
            acceptCallButton.addEventListener('click', acceptInvite);
            acceptCallButton.dataset.bound = 'true';
        }
    }

    return {
        bindDialogEvents,
        bindSignalHandlers,
        getInvitePayloadFromUrl,
        showCallRequestDialog
    };
}
