<template>
    <div class="tabs-wrapper tabs-wrapper-mobile">
        <img class="tabs-trigger" :src="isMoreGroupSelected ? sessionListFoldSelected : sessionListFoldIcon"
            :alt="t('打开会话类型抽屉')" draggable="false" @click="drawerVisible = true" />
        <div class="tabs tabs-mobile">
            <span v-for="tab in visibleTabOptions" :key="tab.key" class="tab-item"
                :class="{ active: isSameTab(modelValue, tab.value) }" @click="handleTabChange(tab.value)">
                <span class="tab-label">{{ tab.label }}</span>
                <span v-if="shouldShowTabUnreadCount(tab.key)" class="tab-badge">
                    {{ formatUnreadCount(getSessionUnreadCount(tab.key)) }}
                </span>
                <span v-else-if="shouldShowTabChangeDot(tab.key)" class="tab-dot"></span>
            </span>
        </div>
    </div>

    <Teleport to="body">
        <div v-if="drawerVisible" class="tabs-drawer-mask" @click="closeDrawer">
            <div class="tabs-drawer" @click.stop>
                <div class="tabs-drawer-header">
                    <span class="tabs-drawer-title">{{ t('分组') }}</span>
                </div>
                <div class="tabs-drawer-section">
                    <div class="tabs-drawer-list">
                        <button v-for="tab in visibleTabOptions" :key="`drawer-${tab.key}`" class="tabs-drawer-item"
                            :class="{ active: isSameTab(modelValue, tab.value) }" type="button"
                            @click="handleDrawerTabChange(tab.value)">
                            <div class="tab-content">
                                <img :src="tab.icon" class="tab-icon" alt="" />
                                <span class="tab-label">{{ tab.label }}</span>
                            </div>
                            <span v-if="getSessionCount(tab.key) > 0" class="tab-count">
                                {{ getSessionCount(tab.key) }}
                            </span>
                        </button>
                    </div>
                </div>
                <div class="tabs-drawer-section more-group-section">
                    <div class="tabs-drawer-section-title">{{ t('更多分组') }}</div>
                    <div class="tabs-drawer-list">
                        <button v-for="group in visibleMoreGroupOptions" :key="`group-${group.key}`"
                            class="tabs-drawer-item" :class="{ active: isSameTab(modelValue, group.value) }"
                            type="button" @click="handleDrawerTabChange(group.value)">
                            <span class="tab-label">{{ group.label }}</span>
                            <span v-if="getSessionCount(group.key) > 0" class="tab-count">
                                {{ getSessionCount(group.key) }}
                            </span>
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </Teleport>
</template>

<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref, watch } from "vue";
import { useI18n } from 'vue-i18n';
import AIDeskCoreInstance, {
    SESSION_TYPE,
    StoreName,
    type ISessionModel,
} from "@tencentcloud/ai-desk-core";
import sessionListFoldIcon from "./sessionListFold.svg";
import sessionListFoldSelected from "./sessionListFoldSelected.svg";
import servingIcon from "./serving.svg";
import ringingIcon from "./ringing.svg";
import innerSessionIcon from "./innerSession.svg";
import robotServingIcon from "./robotServing.svg";
import waitHumanIcon from "./waitHuman.svg";

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

type SessionTabValue = {
    type: SessionTabType;
    meta?: string;
};
type TabOption = {
    key: string;
    label: string;
    value: SessionTabValue;
    icon: any;
};

type MoreGroupOption = {
    key: string;
    label: string;
    value: SessionTabValue;
};

const props = defineProps<{
    modelValue: SessionTabValue;
}>();

const emit = defineEmits<{
    (e: "update:modelValue", value: SessionTabValue): void;
}>();

const { t } = useI18n();
const drawerVisible = ref(false);
const IMSessionList = ref<ISessionModel<SESSION_TYPE.IM>[]>([]);
const IMRobotSessionList = ref<ISessionModel<SESSION_TYPE.ROBOT>[]>([]);
const IMQueueSessionList = ref<ISessionModel<SESSION_TYPE.IM_QUEUE>[]>([]);
const IMOtherInprogressSessionList = ref<
    ISessionModel<SESSION_TYPE.IM_OTHER_INPROGRESS>[]
>([]);
const tabChangedMap = ref<Record<string, boolean>>({});
const robotSessionEnabled = ref(0)
const monitorAgentSessionEnabled = ref(0)

onMounted(() => {
    AIDeskCoreInstance.coreStore.watch(StoreName.SESSION, {
        IMSessionList: onIMSessionListUpdated,
        IMRobotSessionList: onIMRobotSessionListUpdated,
        IMQueueSessionList: onIMQueueSessionListUpdated,
        IMOtherInprogressSessionList: onIMOtherInprogressSessionListUpdated,
    });
    AIDeskCoreInstance.coreStore.watch(StoreName.APP_SETTING, {
        robotSessionEnabled: onRobotSessionEnabledUpdated,
        monitorAgentSessionEnabled: onMonitorAgentSessionEnabledUpdated,
    });
});

onUnmounted(() => {
    AIDeskCoreInstance.coreStore.unwatch(StoreName.SESSION, {
        IMSessionList: onIMSessionListUpdated,
        IMRobotSessionList: onIMRobotSessionListUpdated,
        IMQueueSessionList: onIMQueueSessionListUpdated,
        IMOtherInprogressSessionList: onIMOtherInprogressSessionListUpdated,
    });
    AIDeskCoreInstance.coreStore.unwatch(StoreName.APP_SETTING, {
        robotSessionEnabled: onRobotSessionEnabledUpdated,
        monitorAgentSessionEnabled: onMonitorAgentSessionEnabledUpdated,
    });
});

const onRobotSessionEnabledUpdated = (value: number) => {
    robotSessionEnabled.value = value;
};

const onMonitorAgentSessionEnabledUpdated = (value: number) => {
    monitorAgentSessionEnabled.value = value;
};

const onIMSessionListUpdated = (list: ISessionModel<SESSION_TYPE.IM>[]) => {
    IMSessionList.value = list ?? [];
};

const onIMRobotSessionListUpdated = (
    list: ISessionModel<SESSION_TYPE.ROBOT>[],
) => {
    const nextList = list ?? [];
    const currentTabKey = getTabKeyByValue(props.modelValue);
    const previousRobotCount = IMRobotSessionList.value.filter((item) => {
        return item.sessionData.transToAgentTimes === 0;
    }).length;
    const previousWaitHumanCount = IMRobotSessionList.value.filter((item) => {
        return item.sessionData.transToAgentTimes > 0;
    }).length;
    const nextRobotCount = nextList.filter((item) => {
        return item.sessionData.transToAgentTimes === 0;
    }).length;
    const nextWaitHumanCount = nextList.filter((item) => {
        return item.sessionData.transToAgentTimes > 0;
    }).length;

    IMRobotSessionList.value = nextList;

    if (
        previousRobotCount !== nextRobotCount &&
        currentTabKey !== SESSION_TYPE.ROBOT + "robot"
    ) {
        tabChangedMap.value = {
            ...tabChangedMap.value,
            [SESSION_TYPE.ROBOT + "robot"]: true,
        };
    }

    if (
        previousWaitHumanCount !== nextWaitHumanCount &&
        currentTabKey !== SESSION_TYPE.ROBOT + "wait-human"
    ) {
        tabChangedMap.value = {
            ...tabChangedMap.value,
            [SESSION_TYPE.ROBOT + "wait-human"]: true,
        };
    }
};

const onIMQueueSessionListUpdated = (
    list: ISessionModel<SESSION_TYPE.IM_QUEUE>[],
) => {
    const nextList = list ?? [];
    const previousCount = IMQueueSessionList.value.length;
    const currentTabKey = getTabKeyByValue(props.modelValue);

    IMQueueSessionList.value = nextList;

    if (
        previousCount !== nextList.length &&
        currentTabKey !== SESSION_TYPE.IM_QUEUE
    ) {
        tabChangedMap.value = {
            ...tabChangedMap.value,
            [SESSION_TYPE.IM_QUEUE]: true,
        };
    }
};

const onIMOtherInprogressSessionListUpdated = (
    list: ISessionModel<SESSION_TYPE.IM_OTHER_INPROGRESS>[],
) => {
    IMOtherInprogressSessionList.value = list ?? [];
};

const allTabOptions = computed<TabOption[]>(() => [
    {
        key: SESSION_TYPE.IM + "outer",
        label: t('服务中'),
        value: { type: SESSION_TYPE.IM, meta: "outer" },
        icon: servingIcon,
    },
    {
        key: SESSION_TYPE.IM_QUEUE,
        label: t('待分配'),
        value: { type: SESSION_TYPE.IM_QUEUE },
        icon: ringingIcon,
    },
    {
        key: SESSION_TYPE.IM + "inner",
        label: t('内部会话'),
        value: { type: SESSION_TYPE.IM, meta: "inner" },
        icon: innerSessionIcon,
    },
    {
        key: SESSION_TYPE.ROBOT + "robot",
        label: t('智能体服务中'),
        value: { type: SESSION_TYPE.ROBOT, meta: "robot" },
        icon: robotServingIcon,
    },
    {
        key: SESSION_TYPE.ROBOT + "wait-human",
        label: t('待人工处理'),
        value: { type: SESSION_TYPE.ROBOT, meta: "wait-human" },
        icon: waitHumanIcon,
    },
]);

const visibleTabOptions = computed(() => {
    if (robotSessionEnabled.value === 0) {
        return allTabOptions.value.filter((tab) => {
            return tab.value.type !== SESSION_TYPE.ROBOT;
        });
    }

    return allTabOptions.value;
});

const allMoreGroupOptions = computed<MoreGroupOption[]>(() => [
    {
        key: SESSION_TYPE.IM + "unread",
        label: t('未读消息'),
        value: { type: SESSION_TYPE.IM, meta: "unread" },
    },
    {
        key: SESSION_TYPE.IM + "star",
        label: t('星标'),
        value: { type: SESSION_TYPE.IM, meta: "star" },
    },
    {
        key: SESSION_TYPE.IM + "ended",
        label: t('已结束'),
        value: { type: SESSION_TYPE.IM, meta: "ended" },
    },
    {
        key: SESSION_TYPE.IM_OTHER_INPROGRESS,
        label: t('全部会话'),
        value: { type: SESSION_TYPE.IM_OTHER_INPROGRESS },
    },
]);

const visibleMoreGroupOptions = computed(() => {
    if (monitorAgentSessionEnabled.value === 0) {
        return allMoreGroupOptions.value.filter((group) => {
            return group.value.type !== SESSION_TYPE.IM_OTHER_INPROGRESS;
        });
    }

    return allMoreGroupOptions.value;
});

const unreadCountTabKeys = new Set<string>([
    SESSION_TYPE.IM + "outer",
    SESSION_TYPE.IM + "inner",
]);

const changeDotTabKeys = new Set<string>([
    SESSION_TYPE.IM_QUEUE,
    SESSION_TYPE.ROBOT + "robot",
    SESSION_TYPE.ROBOT + "wait-human",
]);

const getTabKeyByValue = (tabValue: SessionTabValue) => {
    return allTabOptions.value.find((tab) => {
        return tab.value.type === tabValue.type && tab.value.meta === tabValue.meta;
    })?.key;
};

const clearTabChangeState = (key: string) => {
    if (!changeDotTabKeys.has(key)) {
        return;
    }

    tabChangedMap.value = {
        ...tabChangedMap.value,
        [key]: false,
    };
};

watch(
    () => props.modelValue,
    (value) => {
        const currentTabKey = getTabKeyByValue(value);
        if (currentTabKey) {
            clearTabChangeState(currentTabKey);
        }
    },
    { deep: true },
);

const getSessionCount = (key: string) => {
    switch (key) {
        case SESSION_TYPE.IM + "outer":
            return IMSessionList.value.filter((item) => {
                return (
                    !item.sessionData.isInnerSession &&
                    (item.sessionData.sessionState === "ringing" ||
                        item.sessionData.sessionState === "inProgress" ||
                        item.sessionData.sessionState === "seatJoining")
                );
            }).length;
        case SESSION_TYPE.IM_QUEUE:
            return IMQueueSessionList.value.length;
        case SESSION_TYPE.IM + "inner":
            return IMSessionList.value.filter((item) => {
                return item.sessionData.isInnerSession;
            }).length;
        case SESSION_TYPE.ROBOT + "robot":
            return IMRobotSessionList.value.filter((item) => {
                return item.sessionData.transToAgentTimes === 0;
            }).length;
        case SESSION_TYPE.ROBOT + "wait-human":
            return IMRobotSessionList.value.filter((item) => {
                return item.sessionData.transToAgentTimes > 0;
            }).length;
        case SESSION_TYPE.IM + "unread":
            return IMSessionList.value.filter((item) => {
                return item.sessionData.unreadCount > 0;
            }).length;
        case SESSION_TYPE.IM + "star":
            return IMSessionList.value.filter((item) => {
                return item.sessionData.starStatus === 1;
            }).length;
        case SESSION_TYPE.IM + "ended":
            return IMSessionList.value.filter((item) => {
                return item.sessionData.sessionState === "finished";
            }).length;
        case SESSION_TYPE.IM_OTHER_INPROGRESS:
            return IMOtherInprogressSessionList.value.length;
        default:
            return 0;
    }
};

const getSessionUnreadCount = (key: string) => {
    switch (key) {
        case SESSION_TYPE.IM + "outer":
            return IMSessionList.value.filter((session) => session.sessionData.sessionState === 'inProgress').reduce((total, item) => {
                if (item.sessionData.isInnerSession) {
                    return total;
                }
                return total + (item.sessionData.unreadCount ?? 0);
            }, 0);
        case SESSION_TYPE.IM + "inner":
            return IMSessionList.value.reduce((total, item) => {
                if (!item.sessionData.isInnerSession) {
                    return total;
                }
                return total + (item.sessionData.unreadCount ?? 0);
            }, 0);
        default:
            return 0;
    }
};

const shouldShowTabUnreadCount = (key: string) => {
    return unreadCountTabKeys.has(key) && getSessionUnreadCount(key) > 0;
};

const shouldShowTabChangeDot = (key: string) => {
    return !unreadCountTabKeys.has(key) && Boolean(tabChangedMap.value[key]);
};

const isSameTab = (left: SessionTabValue, right: SessionTabValue) =>
    left.type === right.type && left.meta === right.meta;

const isMoreGroupSelected = computed(() => {
    return visibleMoreGroupOptions.value.some((group) => {
        return isSameTab(props.modelValue, group.value);
    });
});

const formatUnreadCount = (count: number) =>
    count > 99 ? "99+" : String(count);

const handleTabChange = (tab: SessionTabValue) => {
    emit("update:modelValue", tab);
};

const handleDrawerTabChange = (tab: SessionTabValue) => {
    handleTabChange(tab);
    closeDrawer();
};

const closeDrawer = () => {
    drawerVisible.value = false;
};
</script>

<style scoped>
.tabs-wrapper {
    display: flex;
    align-items: center;
    background: #fff;
}

.tabs-wrapper-mobile {
    gap: 8px;
    padding: 0 12px;
}

.tabs-trigger {
    width: 16px;
    height: 16px;
    display: block;
    flex-shrink: 0;
    cursor: pointer;
    user-select: none;
    -webkit-user-drag: none;
}

.tabs {
    display: flex;
    padding: 12px 16px;
    background: #fff;
}

.tabs-mobile {
    flex: 1;
    min-width: 0;
    flex-direction: row;
    gap: 40px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
    touch-action: pan-x;
    scrollbar-width: none;
    -ms-overflow-style: none;
    border-bottom: 1px solid #f0f0f0;
}

.tabs-mobile::-webkit-scrollbar {
    display: none;
}

.tab-item {
    cursor: pointer;
    font-size: 14px;
    color: #a5a9b0;
    transition: all 0.3s;
    border: none;
    background: transparent;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
}

.tab-label {
    min-width: 0;
    font-size: 14px;
}

.tab-icon {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

.tab-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 9px;
    background: #ff4d4f;
    color: #fff;
    font-size: 10px;
    line-height: 18px;
    font-weight: 500;
    flex-shrink: 0;
}

.tab-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #ff4d4f;
    flex-shrink: 0;
}

.tabs-mobile .tab-item {
    padding-bottom: 4px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 6px;
}

.tabs-mobile .tab-item.active {
    color: #000;
    font-weight: 400;
}

.tabs-drawer-mask {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.35);
    z-index: 1000;
}

.tabs-drawer {
    width: 260px;
    max-width: 80vw;
    height: 100%;
    background: #fff;
    box-shadow: 6px 0 24px rgba(0, 0, 0, 0.12);
    display: flex;
    flex-direction: column;
    animation: slide-in-left 0.2s ease-out;
    padding: 16px 8px 12px;
}

.tabs-drawer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 12px 12px;
}

.tabs-drawer-title {
    font-size: 16px;
    font-weight: 400;
    color: #1d2129;
}

.tabs-drawer-section {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.more-group-section {
    margin-top: 12px;
}

.tabs-drawer-section-title {
    padding: 0 12px;
    font-size: 16px;
    line-height: 20px;
    color: #a5a9b0;
}

.tabs-drawer-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.tabs-drawer-item {
    padding: 12px 14px;
    border: none;
    border-radius: 12px;
    background: transparent;
    text-align: left;
    font-size: 14px;
    color: #000;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.tab-content {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1;
}

.tab-count {
    margin-left: auto;
    font-size: 14px;
    flex-shrink: 0;
}

.tabs-drawer-static-item {
    cursor: default;
}

.tabs-drawer-item.active {
    background: #f0f2f7ff;
    color: #000;
    font-weight: 400;
}

@keyframes slide-in-left {
    from {
        transform: translateX(-100%);
    }

    to {
        transform: translateX(0);
    }
}
</style>
