<template>
    <div class="pc-desk-view">
        <TopBar />
        <div class="pc-desk-shell">
            <SideNav />
            <div class="pc-desk-main">
                <div class="pc-desk-body">
                    <SessionTabs v-model="sessionType" />
                    <template v-if="isServiceRecordTab">
                        <ServiceRecord />
                    </template>
                    <template v-else>
                        <div class="pc-session-list" :style="{ width: `${sessionListWidth}px` }">
                            <div class="pc-session-list-header">
                                <span class="pc-session-list-title">{{ currentTabLabel }}</span>
                                <ReceptionLimit v-if="isMyTab && enableModifySelfReceptionLimit === 1" />
                                <CreateSessionEntry v-if="isMyTab" class="pc-session-list-header-action" />
                            </div>
                            <div class="pc-session-list-body">
                                <SessionList :current-tab="sessionType" :merge-inner="true" :hide-ringing="true" />
                            </div>
                            <div class="pc-session-list-resizer" :class="{ 'is-resizing': isResizing }"
                                @mousedown="handleResizerMouseDown"></div>
                        </div>
                        <div class="pc-desk-content">
                            <template v-if="currentSession">
                                <ChatHeader :session="currentSession" @end="handleSessionClosed"
                                    @complete="handleSessionClosed" />
                                <div class="message-list-panel">
                                    <MessageList :re-edit-message="handleReEditMessage"
                                        :footer-action-disabled="isFooterActionDisabled"
                                        :on-switch-to-my-tab="handleSwitchToMyTab" />
                                </div>
                                <ChatInput v-if="showChatInput" ref="chatInputRef" :session-id="currentSessionId"
                                    :is-inner-session="isCurrentInnerSession" />
                            </template>
                            <div v-else class="pc-desk-empty">
                                <img class="pc-desk-empty-icon" :src="emptyIcon" alt="empty" />
                                <div class="pc-desk-empty-text">{{ t('此刻暂无会话，偷得片刻闲，稍后继续加油服务哟!') }}</div>
                            </div>
                        </div>
                        <UserInfoPanel v-if="showUserInfoPanel" />
                    </template>
                </div>
            </div>
        </div>
        <RingingCallFloat />
    </div>
</template>

<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import AIDeskCoreInstance, {
    AI_DESK_EVENTS,
    SESSION_TYPE,
    StoreName,
    type IMessageModel,
    type SessionTypeMap,
} from '@tencentcloud/ai-desk-core';
import SessionTabs from './components/SessionTabs/index.vue';
import TopBar from './components/TopBar/index.vue';
import SideNav from './components/SideNav/index.vue';
import UserInfoPanel from './components/UserInfoPanel/index.vue';
import RingingCallFloat from './components/RingingCallFloat/index.vue';
import ServiceRecord from './components/ServiceRecord/index.vue';
import ReceptionLimit from './components/ReceptionLimit/index.vue';
import CreateSessionEntry from './components/CreateSessionEntry/index.vue';
import SessionList from '../../components/SessionList/index.vue';
import MessageList from '../../components/MessageList/index.vue';
import ChatHeader from './Chat/ChatHeader/index.vue';
import ChatInput from './Chat/ChatInput/index.vue';
import toast from '../../utils/toast.ts';
import emptyIcon from './empty.svg';

type SessionTabType =
    | SESSION_TYPE.IM
    | SESSION_TYPE.IM_OTHER_INPROGRESS
    | SESSION_TYPE.IM_QUEUE
    | SESSION_TYPE.ROBOT;

type SessionTabValue = {
    type: SessionTabType;
    meta?: string;
};

const { t } = useI18n();
const sessionType = ref<SessionTabValue>({ type: SESSION_TYPE.IM, meta: 'outer' });
const enableModifySelfReceptionLimit = ref(0);

const isServiceRecordTab = computed(() => sessionType.value.meta === 'service-record');

const isMyTab = computed(
    () => sessionType.value.type === SESSION_TYPE.IM && sessionType.value.meta === 'outer',
);

const handleSwitchToMyTab = () => {
    sessionType.value = { type: SESSION_TYPE.IM, meta: 'outer' };
};

const currentTabLabel = computed(() => {
    const { type, meta } = sessionType.value;

    if (type === SESSION_TYPE.IM && meta === 'outer') {
        return t('我的');
    }

    if (type === SESSION_TYPE.IM_QUEUE) {
        return t('待分配');
    }

    if (type === SESSION_TYPE.ROBOT && meta === 'robot') {
        return t('智能体服务中');
    }

    if (type === SESSION_TYPE.ROBOT && meta === 'wait-human') {
        return t('待人工处理');
    }

    if (type === SESSION_TYPE.IM_OTHER_INPROGRESS) {
        return t('全部会话');
    }

    return '';
});

watch(
    () => [sessionType.value.type, sessionType.value.meta] as const,
    () => {
        AIDeskCoreInstance.sessionService.switchSession({ sessionId: '', sessionType: '' });
    },
);

const currentSession = ref<SessionTypeMap[SESSION_TYPE] | null>(null);
const currentSessionId = ref('');
const lastIMSessionState = ref('');
const isCurrentInnerSession = computed(
    () => currentSession.value?.type === SESSION_TYPE.IM
        && Boolean(currentSession.value.isInnerSession),
);
const isFooterActionDisabled = ref(false);
const chatInputRef = ref<{ setText: (text?: string) => Promise<void> } | null>(null);

const SESSION_LIST_MIN_WIDTH = 240;
const SESSION_LIST_MAX_WIDTH = 480;
const SESSION_LIST_DEFAULT_WIDTH = 320;
const sessionListWidth = ref(SESSION_LIST_DEFAULT_WIDTH);
const isResizing = ref(false);
let resizeStartX = 0;
let resizeStartWidth = 0;

const handleResizerMouseMove = (event: MouseEvent) => {
    if (!isResizing.value) {
        return;
    }
    const delta = event.clientX - resizeStartX;
    const nextWidth = Math.min(
        SESSION_LIST_MAX_WIDTH,
        Math.max(SESSION_LIST_MIN_WIDTH, resizeStartWidth + delta),
    );
    sessionListWidth.value = nextWidth;
};

const handleResizerMouseUp = () => {
    if (!isResizing.value) {
        return;
    }
    isResizing.value = false;
    document.body.style.userSelect = '';
    document.body.style.cursor = '';
    window.removeEventListener('mousemove', handleResizerMouseMove);
    window.removeEventListener('mouseup', handleResizerMouseUp);
};

const handleResizerMouseDown = (event: MouseEvent) => {
    isResizing.value = true;
    resizeStartX = event.clientX;
    resizeStartWidth = sessionListWidth.value;
    document.body.style.userSelect = 'none';
    document.body.style.cursor = 'col-resize';
    window.addEventListener('mousemove', handleResizerMouseMove);
    window.addEventListener('mouseup', handleResizerMouseUp);
    event.preventDefault();
};

const showChatInput = computed(() => {
    if (!currentSession.value) {
        return false;
    }

    return currentSession.value.type === SESSION_TYPE.IM
        && currentSession.value.sessionState === 'inProgress';
});

const showUserInfoPanel = computed(() => {
    if (isServiceRecordTab.value || !currentSession.value) {
        return false;
    }

    return currentSession.value.type !== SESSION_TYPE.IM
        || !currentSession.value.isInnerSession
        || currentSession.value.imAgentChatType === 1;
});

const shouldDisableFooterAction = (session: SessionTypeMap[SESSION_TYPE]) => {
    if (session.type === SESSION_TYPE.ROBOT) {
        return ['my', 'other', 'allocation'].includes(session.transferStatus);
    }

    if (session.type === SESSION_TYPE.IM_QUEUE) {
        return session.currentState !== 'Queueing';
    }

    if (session.type === SESSION_TYPE.IM_OTHER_INPROGRESS) {
        return session.memberOutType === 1 || session.memberOutType === 2;
    }

    return false;
};

const onCurrentSessionUpdated = (session: {
    sessionId: string;
    sessionType: SESSION_TYPE | '';
    sessionData: SessionTypeMap[SESSION_TYPE] | null;
}) => {
    const sessionInfo = session.sessionData;
    const previousSessionId = currentSessionId.value;
    const previousIMSessionState = lastIMSessionState.value;

    if (sessionInfo === null) {
        currentSession.value = null;
        currentSessionId.value = session.sessionId;
        lastIMSessionState.value = '';
        isFooterActionDisabled.value = false;
        return;
    }

    currentSession.value = sessionInfo;
    currentSessionId.value = sessionInfo.sessionId;
    isFooterActionDisabled.value = shouldDisableFooterAction(sessionInfo);

    const nextIMSessionState = sessionInfo.type === SESSION_TYPE.IM
        ? sessionInfo.sessionState
        : '';
    lastIMSessionState.value = nextIMSessionState;

    if (
        previousSessionId === sessionInfo.sessionId
        && previousIMSessionState === 'inProgress'
        && nextIMSessionState === 'finished'
    ) {
        toast.warn(t('当前会话已结束'));
        AIDeskCoreInstance.sessionService.switchSession({ sessionId: '', sessionType: '' });
    }
};

const handleReEditMessage = (message: IMessageModel) => {
    chatInputRef.value?.setText(typeof message.payload?.text === 'string' ? message.payload.text : '');
};

const handleSessionClosed = () => {
    AIDeskCoreInstance.sessionService.switchSession({ sessionId: '', sessionType: '' });
};

const onKickedOutEvent = () => {
    toast.error('您已被踢下线，请重新登录');
};
const onForcedOfflineEvent = () => {
    toast.error('您已被强制下线，请重新登录');
};
const onEnableModifySelfReceptionLimitUpdated = (value: number) => {
    enableModifySelfReceptionLimit.value = value ?? 0;
};

onMounted(() => {
    AIDeskCoreInstance.coreStore.watch(StoreName.SESSION, {
        currentSession: onCurrentSessionUpdated,
    });
    AIDeskCoreInstance.coreStore.watch(StoreName.APP_SETTING, {
        enableModifySelfReceptionLimit: onEnableModifySelfReceptionLimitUpdated,
    });
    AIDeskCoreInstance.eventCenter.addEvent(AI_DESK_EVENTS.KICKED_OUT, onKickedOutEvent);
    AIDeskCoreInstance.eventCenter.addEvent(AI_DESK_EVENTS.FORCED_OFFLINE, onForcedOfflineEvent);
});

onUnmounted(() => {
    AIDeskCoreInstance.coreStore.unwatch(StoreName.SESSION, {
        currentSession: onCurrentSessionUpdated,
    });
    AIDeskCoreInstance.coreStore.unwatch(StoreName.APP_SETTING, {
        enableModifySelfReceptionLimit: onEnableModifySelfReceptionLimitUpdated,
    });
    AIDeskCoreInstance.eventCenter.removeEvent(AI_DESK_EVENTS.KICKED_OUT, onKickedOutEvent);
    AIDeskCoreInstance.eventCenter.removeEvent(AI_DESK_EVENTS.FORCED_OFFLINE, onForcedOfflineEvent);
    if (isResizing.value) {
        document.body.style.userSelect = '';
        document.body.style.cursor = '';
    }
    window.removeEventListener('mousemove', handleResizerMouseMove);
    window.removeEventListener('mouseup', handleResizerMouseUp);
});
</script>

<style scoped>
.pc-desk-view {
    height: 100%;
    display: flex;
    flex-direction: column;
    background: #fff;
}

.pc-desk-shell {
    flex: 1;
    min-height: 0;
    display: flex;
    background: #F2F3F5;
}

.pc-desk-main {
    flex: 1;
    min-width: 0;
    display: flex;
    padding: 12px;
    box-sizing: border-box;
}

.pc-desk-body {
    flex: 1;
    min-width: 0;
    min-height: 0;
    display: flex;
    background: #fff;
    border-radius: 12px;
    overflow: hidden;
}

.pc-session-list {
    width: 320px;
    flex-shrink: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    border-right: 1px solid #f0f0f0;
    background: #fff;
    overflow: hidden;
    position: relative;
}

.pc-session-list-resizer {
    position: absolute;
    top: 0;
    right: -3px;
    width: 6px;
    height: 100%;
    cursor: col-resize;
    background: transparent;
    z-index: 10;
    user-select: none;
}

.pc-session-list-resizer:hover,
.pc-session-list-resizer.is-resizing {
    background: rgba(22, 119, 255, 0.15);
}

.pc-session-list-header {
    flex-shrink: 0;
    padding: 16px 16px 12px;
    background: #fff;
    display: flex;
    align-items: center;
    gap: 12px;
}

.pc-session-list-title {
    font-size: 16px;
    font-weight: 500;
    color: #000;
    line-height: 24px;
}

.pc-session-list-header-action {
    margin-left: auto;
}

.pc-session-list-body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.pc-desk-content {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    background: #fff;
}

.message-list-panel {
    flex: 1;
    min-height: 0;
}

.pc-desk-empty {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: #fff;
}

.pc-desk-empty-icon {
    width: 216px;
    height: 164px;
}

.pc-desk-empty-text {
    color: #727A8A;
    font-size: 14px;
    font-weight: 400;
}
</style>
