<template>
    <view class="chat-container">
        <!-- #ifdef MP-WEIXIN -->
         <view class="chat-background">
        <!-- #endif -->
        <!-- #ifndef MP-WEIXIN -->
        <view class="chat-background" v-fade:600="!messages.length">
        <!-- #endif -->
            <image class="backlogo" src="/static/icon/backAI.png"></image>
            <view class="back-rowTitle">嗨！欢迎使用青岛AI智能求职</view>
            <view class="back-rowText">
                我可以根据您的简历和求职需求，帮你精准匹配青岛市互联网招聘信息，对比招聘信息的优缺点，提供面试指导等，请把你的任务交给我吧~
            </view>
            <view class="back-rowh3">猜你所想</view>
            <view
                class="back-rowmsg button-click"
                v-for="(item, index) in queries"
                :key="index"
                @click="sendMessageGuess(item)"
            >
                {{ item }}
            </view>
            <view class="chat-item self" v-if="isRecording">
                <view class="message">{{ recognizedText }} {{ lastFinalText }}</view>
            </view>
        </view>
        <scroll-view class="chat-list scrollView" :scroll-top="scrollTop" :scroll-y="true" scroll-with-animation>
            <!-- #ifdef MP-WEIXIN -->
            <view class="chat-list list-content">
            <!-- #endif -->
            <!-- #ifndef MP-WEIXIN -->
            <view class="chat-list list-content" v-fade:600="messages.length >= 1">
            <!-- #endif -->
                <view
                    v-for="(msg, index) in messages"
                    :key="index"
                    :id="'msg-' + index"
                    class="chat-item"
                    :class="{ self: msg.self }"
                >
                    <view class="message" v-if="msg.self">
                        <view class="msg-filecontent" v-if="msg.files.length">
                            <view
                                class="msg-files btn-light"
                                v-for="(file, vInex) in msg.files"
                                :key="vInex"
                                @click="jumpUrl(file)"
                            >
                                <image class="msg-file-icon" src="/static/icon/Vector2.png"></image>
                                <text class="msg-file-text">{{ file.name || '附件' }}</text>
                            </view>
                        </view>
                        {{ msg.displayText }}
                    </view>
                    <view class="message" :class="{ messageNull: !msg.displayText }" v-else>
                        <!-- {{ msg.displayText }} -->
                        <view class="message-markdown">
                            <md-render
                                :content="msg.displayText"
                                :typing="isTyping && messages.length - 1 === index"
                            ></md-render>
                            <view class="message-controll" v-show="showControll(index)">
                                <view class="controll-left">
                                    <image
                                        class="controll-icon btn-light"
                                        src="/static/icon/copy.png"
                                        @click="copyMarkdown(msg.displayText)"
                                    ></image>
                                    <image
                                        class="controll-icon mar_le10 btn-light"
                                        src="/static/icon/feedback.png"
                                        v-if="!msg.userBadFeedback"
                                        @click="userGoodFeedback(msg)"
                                    ></image>
                                    <image
                                        v-if="isSpeaking && !isPaused && speechIndex === index"
                                        class="controll-icon mar_le10 btn-light"
                                        src="/static/icon/stop.png"
                                        @click="stopMarkdown(msg.displayText, index)"
                                    ></image>
                                    <image
                                        class="controll-icon mar_le10 btn-light"
                                        src="/static/icon/broadcast.png"
                                        @click="readMarkdown(msg.displayText, index)"
                                        v-else
                                    ></image>
                                </view>
                                <view class="controll-right">
                                    <image
                                        class="controll-icon mar_ri10 btn-light"
                                        src="/static/icon/refresh.png"
                                        @click="refreshMarkdown(index)"
                                    ></image>
                                </view>
                            </view>
                        </view>
                        <!-- guess -->
                        <view
                            class="guess"
                            v-if="showGuess && !msg.self && messages.length - 1 === index && msg.displayText"
                        >
                            <view class="gulist">
                                <view
                                    class="guess-list"
                                    @click="sendMessageGuess(item)"
                                    v-for="(item, index) in guessList"
                                    :key="index"
                                >
                                    {{ item }}
                                </view>
                            </view>
                        </view>
                    </view>
                </view>
                <view class="chat-item self" v-if="isRecording">
                    <!-- <view class="message">{{ recognizedText }} {{ lastFinalText }}</view> -->
                    <view class="message">{{ recognizedText }}</view>
                </view>
                <view v-if="isTyping" class="self">
                    <text class="message msg-loading">
                        <span class="ai-loading"></span>
                    </text>
                </view>
            </view>
        </scroll-view>
        <!-- 使用 v-show 保证不销毁事件 -->
        <view class="vio_container" :class="status" v-show="status !== 'idle'">
            <view class="record-tip">{{ statusText }}</view>
            <WaveDisplay
                :background="audiowaveStyle"
                :isActive="isRecording"
                :audioData="audioDataForDisplay"
                :showInfo="isRecording"
            />
        </view>
        <view class="input-area" v-show="status === 'idle'">
            <view class="areatext">
                <input
                    v-model="textInput"
                    placeholder-class="inputplaceholder"
                    class="input"
                    @confirm="sendMessage"
                    :disabled="isTyping"
                    :adjust-position="false"
                    placeholder="请输入您的职位名称、薪资要求、岗位地址"
                    v-show="!isVoice"
                />
                <view
                    class="input_vio"
                    @touchstart.prevent="handleTouchStart"
                    @touchmove.passive="handleTouchMove"
                    @touchend="handleTouchEnd"
                    @touchcancel="handleTouchCancel"
                    :catchtouchstart="true"
                    :catchtouchmove="true"
                    :catchtouchend="true"
                    v-show="isVoice"
                    type="default"
                >
                    按住说话
                </view>
                <!-- upload -->
                <view class="btn-box" @click="changeShowFile">
                    <image
                        class="send-btn"
                        :class="{ 'add-file-btn': showfile }"
                        src="/static/icon/addGroup.png"
                    ></image>
                </view>

                <!-- sendmessgae  Button-->
                <view class="btn-box purple" v-if="textInput && !isTyping" @click="sendMessage">
                    <image class="send-btn" src="/static/icon/send3.png"></image>
                </view>
                <view class="btn-box" v-else-if="!isTyping && !isVoice" @click="changeVoice">
                    <image class="send-btn" src="/static/icon/send2x.png"></image>
                </view>
                <view class="btn-box" v-else-if="!isTyping" @click="changeVoice">
                    <image class="send-btn" src="/static/icon/send4.png"></image>
                </view>
                <view class="btn-box purple" v-else>
                    <view class="btn-box-round"></view>
                </view>
            </view>
            <!-- btn -->
            <CollapseTransition :show="showfile">
                <view class="area-tips">
                    <my-icons type="info-filled" color="#ADADAD" size="30"></my-icons>
                    上传后自动解析简历内容
                </view>
                <view class="area-file">
                    <view class="file-card" @click="uploadCamera">
                        <image class="card-img" src="/static/icon/file1.png"></image>
                        <text>拍照上传</text>
                    </view>
                    <view class="file-card" @click="uploadCamera('album')">
                        <image class="card-img" src="/static/icon/file2.png"></image>
                        <text>相册上传</text>
                    </view>
                    <view class="file-card" @click="getUploadFile">
                        <image class="card-img" src="/static/icon/file3.png"></image>
                        <text>文件上传</text>
                    </view>
                </view>
            </CollapseTransition>

            <!-- filelist -->
            <view class="area-uploadfiles" v-if="filesList.length">
                <scroll-view class="uploadfiles-scroll" scroll-x="true">
                    <view class="uploadfiles-list">
                        <view
                            class="file-uploadsend"
                            :class="{ 'file-border': isImage(file.type) }"
                            v-for="(file, index) in filesList"
                            :key="index"
                        >
                            <image
                                class="file-iconImg"
                                @click="jumpUrl(file)"
                                v-if="isImage(file.type)"
                                :src="file.url"
                            ></image>
                            <view class="file-doc" @click="jumpUrl(file)" v-else>
                                <FileIcon class="doc-icon" :type="file.type"></FileIcon>
                                <view class="doc-con">
                                    <view class="filename-text">{{ file.name }}</view>
                                    <view class="filerow">
                                        <FileText :type="file.type"></FileText>
                                        <view class="row-x"></view>
                                        <view class="filename-size">{{ file.size }}</view>
                                    </view>
                                </view>
                                <!-- <image class="file-icon" @click="jumpUrl(file)" :src=""></image> -->
                            </view>
                            <view class="file-del" catchtouchmove="true" @click="delfile(file)">
                                <my-icons type="closeempty" color="#FFFFFF" size="20"></my-icons>
                            </view>
                        </view>
                    </view>
                </scroll-view>
            </view>
        </view>
        <PopupFeeBack ref="feeback" @onClose="colseFeeBack" @onSend="confirmFeeBack"></PopupFeeBack>
        <MsgTips ref="feeBackTips" content="已收到反馈，感谢您的关注" title="反馈成功" :icon="successIcon"></MsgTips>
    </view>
</template>

<script setup>
import {
    ref,
    inject,
    nextTick,
    onMounted,
    onUnmounted,
    toRaw,
    reactive,
    computed,
    watch,
} from 'vue';
import { storeToRefs } from 'pinia';
import config from '@/config.js';
import useChatGroupDBStore from '@/stores/userChatGroupStore';
import MdRender from '@/components/md-render/md-render.vue';
import CollapseTransition from '@/components/CollapseTransition/CollapseTransition.vue';
import PopupFeeBack from './popupbadFeeback.vue';
import AudioWave from './AudioWave.vue';
import WaveDisplay from './WaveDisplay.vue';
import FileIcon from './fileIcon.vue';
import FileText from './fileText.vue';
import useScreenStore from '@/stores/useScreenStore'
const screenStore = useScreenStore();
// 系统功能hook和阿里云hook
import { useAudioRecorder } from '@/hook/useRealtimeRecorder2.js';
// import { useAudioRecorder } from '@/hook/useSystemSpeechReader.js';
import { useTTSPlayer } from '@/hook/useTTSPlayer2.js';
// import { useTTSPlayer } from '@/hook/useSystemPlayer.js';
// 全局
const { $api, navTo, throttle } = inject('globalFunction');
const emit = defineEmits(['onConfirm']);
const { messages, isTyping, textInput, chatSessionID } = storeToRefs(useChatGroupDBStore());
import successIcon from '@/static/icon/success.png';
// hook
// 语音识别
const {
    isRecording,
    startRecording,
    stopRecording,
    cancelRecording,
    audioDataForDisplay,
    volumeLevel,
    recognizedText,
    lastFinalText,
} = useAudioRecorder();
 // 语音合成
const { speak, pause, resume, isSpeaking, isPaused, cancelAudio } = useTTSPlayer(config.speechSynthesis);

// state
const queries = ref([]);
const guessList = ref([]);
const scrollTop = ref(0);
const showGuess = ref(false);
const showfile = ref(false);
const filesList = ref([]);
const bgText = ref(false);
const isVoice = ref(false);
const status = ref('idle'); // idle | recording | cancel
const startY = ref(0);
const cancelThreshold = 100;
const speechIndex = ref(0);
const isAudioPermission = ref(false);
const feebackData = ref(null);
// ref for DOM element
const voiceBtn = ref(null);
const feeback = ref(null);
const feeBackTips = ref(null);
const state = reactive({
    uploadFileTips: '请根据以上附件，帮我推荐岗位。',
});

const statusText = computed(() => {
    switch (status.value) {
        case 'recording':
            return '松手发送，上划取消';
        case 'cancel':
            return '松手取消';
        default:
            return '按住说话';
    }
});

const audiowaveStyle = computed(() => {
    return status.value === 'cancel'
        ? '#f54545'
        : status.value === 'recording'
        ? 'linear-gradient(to right, #377dff, #9a60ff)'
        : '#f1f1f1';
});

onMounted(async () => {
    changeQueries();
    scrollToBottom();
    isAudioPermission.value = await requestMicPermission();
});

const requestMicPermission = async () => {
    try {
        const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
        console.log('✅ 麦克风权限已授权');

        // 立刻停止所有音轨，释放麦克风
        stream.getTracks().forEach((track) => track.stop());

        return true;
    } catch (err) {
        console.warn('❌ 用户拒绝麦克风权限或不支持:', err);
        return false;
    }
};

function showControll(index) {
    if (index === messages.value.length - 1 && isTyping.value) {
        return false;
    }
    return true;
}

const sendMessage = (text) => {
    const values = textInput.value || text;
    showfile.value = false;
    showGuess.value = false;
    if (values.trim()) {
        // 判断是否有对话ID // 没有则创建对话列表
        const callback = () => {
            const normalArr = toRaw(filesList.value); // 转换为普通数组
            filesList.value = [];
            useChatGroupDBStore()
                .getStearm(values, normalArr, scrollToBottom, {
                    onComplete: () => console.log('Display complete'),
                })
                .then(() => {
                    getGuess();
                    scrollToBottom();
                });
            emit('onConfirm', values);
            textInput.value = '';
            scrollToBottom();
        };
        // 没有对话列表则创建
        if (!chatSessionID.value) {
            useChatGroupDBStore()
                .addTabel(values)
                .then((res) => {
                    callback();
                });
        } else {
            callback();
        }
    } else {
        if (filesList.value.length) {
            $api.msg('上传文件请输入想问的问题描述');
        } else {
            $api.msg('请输入职位信息或描述');
        }
    }
};

const sendMessageGuess = (item) => {
    showGuess.value = false;
    textInput.value = item;
    sendMessage(item);
};

const delfile = (file) => {
    uni.showModal({
        content: '确认删除文件？',
        success(res) {
            if (res.confirm) {
                filesList.value = filesList.value.filter((item) => item.url !== file.url);
                if (!filesList.value.length) {
                    if (textInput.value === state.uploadFileTips) {
                        textInput.value = '';
                    }
                }
                $api.msg('附件删除成功');
            }
        },
    });
};

const scrollToBottom = throttle(function () {
    nextTick(() => {
        try {
            const query = uni.createSelectorQuery();
            query.select('.scrollView').boundingClientRect();
            query.select('.list-content').boundingClientRect();
            query.exec((res) => {
                const scrollViewHeight = res[0].height;
                const scrollContentHeight = res[1].height;
                if (scrollContentHeight > scrollViewHeight) {
                    const scrolldistance = scrollContentHeight - scrollViewHeight;
                    scrollTop.value = scrolldistance;
                }
            });
        } catch (err) {
            console.warn(err);
        }
    });
}, 500);

function getGuess() {
    $api.createRequest('/app/chat/guest', { sessionId: chatSessionID.value }, 'POST').then((res) => {
        guessList.value = res.data;
        showGuess.value = true;
        nextTick(() => {
            scrollToBottom();
        });
    });
}

function isImage(type) {
    return new RegExp('image').test(type);
}

function isFile(type) {
    const allowedTypes = config.allowedFileTypes || [];
    if (!allowedTypes.includes(type)) {
        return false;
    }
    return true;
}

function jumpUrl(file) {
    if (file.url) {
        window.open(file.url);
    } else {
        $api.msg('文件地址丢失');
    }
}

function VerifyNumberFiles(num) {
    if (filesList.value.length >= config.allowedFileNumber) {
        $api.msg(`最大上传文件数量 ${config.allowedFileNumber} 个`);
        return true;
    } else {
        return false;
    }
}

function uploadCamera(type = 'camera') {
    if (VerifyNumberFiles()) return;
    uni.chooseImage({
        count: 1, //默认9
        sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图，默认二者都有
        sourceType: [type], //从相册选择
        success: function (res) {
            const tempFilePaths = res.tempFilePaths;
            const file = res.tempFiles[0];
            // 继续上传
            $api.uploadFile(tempFilePaths[0], true).then((resData) => {
                resData = JSON.parse(resData);
                if (isImage(file.type)) {
                    filesList.value.push({
                        url: resData.msg,
                        type: file.type,
                        name: file.name,
                    });
                    textInput.value = state.uploadFileTips;
                }
            });
        },
    });
}

function getUploadFile(type = 'camera') {
    if (VerifyNumberFiles()) return;
    uni.chooseFile({
        count: 1,
        success: (res) => {
            const tempFilePaths = res.tempFilePaths;
            const file = res.tempFiles[0];
            const allowedTypes = config.allowedFileTypes || [];
            const size = $api.formatFileSize(file.size);
            if (!allowedTypes.includes(file.type)) {
                return $api.msg('仅支持 txt md html word pdf ppt csv excel 格式类型');
            }
            // 继续上传
            $api.uploadFile(tempFilePaths[0], true).then((resData) => {
                resData = JSON.parse(resData);
                filesList.value.push({
                    url: resData.msg,
                    type: file.type,
                    name: file.name,
                    size: size,
                });
                textInput.value = state.uploadFileTips;
            });
        },
    });
}

const tipsPermisson = () => {
    uni.showToast({
        title: '需要授权麦克风权限才能使用语音功能',
        icon: 'none',
    });
};

const handleTouchStart = async (e) => {
    if (!isAudioPermission.value) {
        return tipsPermisson();
    }
    cancelAudio();
    startY.value = e.touches[0].clientY;
    status.value = 'recording';
    showfile.value = false;
    startRecording();
    $api.sleep(1000).then(() => {
        scrollToBottom();
    });
};

const handleTouchMove = (e) => {
    const moveY = e.touches[0].clientY;
    if (startY.value - moveY > cancelThreshold) {
        status.value = 'cancel';
    } else {
        status.value = 'recording';
    }
};

const handleTouchEnd = () => {
    if (status.value === 'cancel') {
        console.log('取消发送');
        cancelRecording();
    } else {
        stopRecording();
        if (isAudioPermission.value) {
            if (recognizedText.value) {
                sendMessage(recognizedText.value);
            } else {
                $api.msg('说话时长太短');
            }
        }
    }
    status.value = 'idle';
};

const handleTouchCancel = () => {
    stopRecording();
    status.value = 'idle';
};

function closeGuess() {
    showGuess.value = false;
}

function changeVoice() {
    isVoice.value = !isVoice.value;
}

function changeShowFile() {
    showfile.value = !showfile.value;
}

function colseFile() {
    showfile.value = false;
}

function copyMarkdown(value) {
    $api.copyText(value);
}

function userGoodFeedback(msg) {
    // $api.msg('该功能正在开发中，敬请期待后续更新！');
    feeback.value?.open();
    feebackData.value = msg;
    uni.hideTabBar()
}

function confirmFeeBack(value) {
    useChatGroupDBStore()
        .badFeedback(feebackData.value, value)
        .then(() => {
            if (!screenStore.isWideScreen) uni.showTabBar()
            feeback.value?.close();
            feeBackTips.value?.open();
        });
}

function colseFeeBack() {
     if (!screenStore.isWideScreen) uni.showTabBar()
}

function readMarkdown(value, index) {
    speechIndex.value = index;
    if (speechIndex.value !== index) {
        speak(value);
        return;
    }
    if (isPaused.value) {
        resume();
    } else {
        // console.log(value, speechIndex.value, index, isPaused.value)
        speak(value);
    }
}
function stopMarkdown(value, index) {
    pause(value);
    speechIndex.value = index;
}
function refreshMarkdown(index) {
    if (isTyping.value) {
        $api.msg('正在生成');
    } else {
        const text = messages.value[index - 1].text;
        sendMessageGuess(text);
    }
}

const jobSearchQueries = [
    '青岛有哪些薪资 12K 以上的岗位适合我？',
    '青岛 3 年工作经验能找到哪些 12K 以上的工作？',
    '青岛哪些公司在招聘，薪资范围在 12K 以上？',
    '青岛有哪些企业提供 15K 以上的岗位？',
    '青岛哪些公司在招 3-5 年经验的岗位？',
    '我有三年的工作经验，能否推荐一些适合我的青岛的国企 岗位？',
    '青岛国企目前在招聘哪些岗位？',
    '青岛有哪些适合 3 年经验的国企岗位？',
    '青岛国企招聘的岗位待遇如何？',
    '青岛国企岗位的薪资水平是多少？',
    '青岛哪些国企支持双休 & 五险一金完善？',
    '青岛有哪些公司支持远程办公？',
    '青岛有哪些外企的岗位，薪资 12K 以上的多吗？',
    '青岛哪些企业在招聘 Web3.0 相关岗位？',
    '青岛哪些岗位支持海外远程？薪资如何？',
    '青岛招聘 AI/大数据相关岗位的公司有哪些？',
];

function changeQueries(value) {
    queries.value = getRandomJobQueries(jobSearchQueries);
}

function getRandomJobQueries(queries, count = 2) {
    const shuffled = queries.sort(() => 0.5 - Math.random()); // 随机打乱数组
    return shuffled.slice(0, count); // 取前 count 条
}

defineExpose({ scrollToBottom, closeGuess, colseFile, changeQueries, handleTouchCancel });
</script>

<style lang="stylus" scoped>
/* 过渡样式 */
.collapse-enter-active,
.collapse-leave-active {
  transition: max-height 0.3s ease, opacity 0.3s ease;
}

.collapse-enter-from,
.collapse-leave-to {
  max-height: 0;
  opacity: 0;
}

.collapse-enter-to,
.collapse-leave-from {
  max-height: 400rpx; /* 根据你内容最大高度设定 */
  opacity: 1;
}
.msg-filecontent
    display: flex
    flex-wrap: wrap
.msg-files
    overflow: hidden
    margin-right: 10rpx
    height: 30rpx
    max-width: 201rpx
    background: #FFFFFF
    border-radius: 10rpx
    display: flex
    align-items: center
    justify-content: flex-start
    padding: 10rpx
    color: #000000
    margin-bottom: 10rpx
    .msg-file-icon
        width: 29rpx
        height: 26rpx
        padding-right: 10rpx
    .msg-file-text
        flex: 1
        white-space: nowrap
        overflow: hidden
        text-overflow: ellipsis
        color: rgba(96, 96, 96, 1)
        font-size: 24rpx
.msg-files:active
    background: #e9e9e9
.guess
    padding: 5rpx 0 10rpx 0
    .guess-list
        padding: 16rpx 24rpx
        margin-top: 28rpx
        font-size: 24rpx
        color: #8c8c8c
        width: 100%;
        border-radius: 20rpx 20rpx 20rpx 20rpx;
        border: 2rpx solid #E5E5E5;
        font-size: 28rpx;
        color: #333333;
        line-height: 33rpx;
    .gulist
        display: flex
        flex-wrap: wrap
        position: relative
image-margin-top = 40rpx
.chat-container
    display: flex;
    flex-direction: column;
    height: 100%;
    position: relative
    z-index: 1
    background: #FFFFFF

.chat-background
    position: absolute
    padding: 44rpx;
    display: flex
    flex-direction: column
    justify-content: flex-start
    align-items: center
    width: calc(100% - 88rpx)
    position: relative
    z-index: 1
    .backlogo
        width: 313rpx;
        height: 190rpx;
    .back-rowTitle
        height: 56rpx;
        font-weight: bold;
        font-size: 40rpx;
        color: #333333;
        line-height: 47rpx;
        margin-top: 40rpx
    .back-rowText
        margin-top: 28rpx
        width: 100%;
        height: 148rpx;
        font-weight: 400;
        font-size: 28rpx;
        color: #333333;
        line-height: 40rpx
        // border-bottom: 2rpx dashed rgba(0, 0, 0, 0.2);
        border-bottom: 2rpx solid transparent;
        background-image: linear-gradient(to right, rgba(0, 0, 0, 0.2) 50%, transparent 50%);
        background-size: 10rpx 2rpx; /* 调整虚线宽度和间距 */
        background-repeat: repeat-x;
        background-position: 0 148rpx
    .back-rowh3
        width: 100%;
        font-weight: 500;
        font-size: 28rpx;
        color: #000000;
        margin-top: 28rpx
    .back-rowmsg
        width: calc(100% - 32rpx)
        margin-top: 24rpx
        font-weight: 500;
        color: rgba(51, 51, 51, 1);
        line-height: 28rpx;
        font-size: 24rpx
        background: rgba(246, 246, 246, 1);
        border-radius: 8rpx 8rpx 8rpx 8rpx;
        padding: 32rpx 18rpx;

.chat-list {
    flex: 1;
    overflow-y: auto;
    white-space: pre-wrap;
}
.list-content {
    padding: 0 44rpx 44rpx 44rpx;
}
.chat-item {
    display: flex;
    align-items: flex-start;
    margin-bottom: 20rpx;
    width: 100%;
}
.chat-item.self {
    justify-content: flex-end;
}
.message
    margin-top: 40rpx
    // max-width: 80%;
    width: 100%;
    word-break: break-word;
    color: #333333;
    user-select: text;
    -webkit-user-select: text;
    .message-markdown
        border-radius: 0 20rpx 20rpx 20rpx;
        padding: 20rpx 20rpx 20rpx 20rpx;
        background: #F6F6F6;
        .message-controll
            display: flex
            justify-content: space-between
            align-items: center
            border-top: 2rpx solid #EAEAEA
            padding: 24rpx 0 4rpx 0
            margin-top: 10rpx
            .controll-left
            .controll-right
                .controll-icon
                    width: 60rpx;
                    height: 60rpx;

.messageNull
    display: none
.msg-loading{
    background: transparent;
    font-size: 24rpx;
    color: #8f8d8e;
    display: flex;
    align-items: flex-end;
    justify-content: flex-start;
}
.loaded{
    padding-left: 20rpx
}
.chat-item.self .message {
    background: linear-gradient( 225deg, #DAE2FE 0%, #E9E3FF 100%);
        border-radius: 20rpx 0 20rpx 20rpx;
    padding: 20rpx;
    width: fit-content;
}
.input-area {
    padding: 32rpx 28rpx 24rpx 28rpx;
    position: relative;
    background: #FFFFFF;
    box-shadow: 0rpx -4rpx 10rpx 0rpx rgba(11,44,112,0.06);
    transition: height 2s ease-in-out;
}
.input-area::after
    position: absolute
    content: ''
    top: 0
    left: 0
    width: 100%
    z-index: 1
    box-shadow: 0rpx -4rpx 10rpx 0rpx rgba(11,44,112,0.06);
.areatext{
    display: flex;
}
.input {
    flex: 1;
    border-radius: 5rpx;
    min-height: 63rpx;
    line-height: 63rpx;
    padding: 4rpx 24rpx;
    position: relative
    background: #F5F5F5;
    border-radius: 60rpx 60rpx 60rpx 60rpx;
    font-size: 28rpx;
}
.input_vio
    flex: 1;
    border-radius: 5rpx;
    min-height: 63rpx;
    line-height: 63rpx;
    padding: 4rpx 24rpx;
    // position: relative
    border-radius: 60rpx 60rpx 60rpx 60rpx;
    font-size: 28rpx
    color: #333333
    background: #F5F5F5;
    text-align: center
    font-size: 28rpx
    font-weight: 500
    user-select:none;
    -webkit-touch-callout:none;
    -webkit-user-select:none;
    -khtml-user-select:none;
    -moz-user-select:none;
    -ms-user-select:none;
    touch-action: none; /* 禁用默认滚动 */
.input_vio:active
    background: #e8e8e8
.vio_container
    background: transparent
    padding: 28rpx
    text-align: center
    -webkit-touch-callout:none;
    -webkit-user-select:none;
    -khtml-user-select:none;
    -moz-user-select:none;
    -ms-user-select:none;
    touch-action: none; /* 禁用默认滚动 */
    .record-tip
        font-weight: 400;
        color: #909090;
        text-align: center;
        padding-bottom: 16rpx


.inputplaceholder {
    font-weight: 500;
    font-size: 24rpx;
    color: #000000;
    line-height: 28rpx;
    opacity: 0.4
}
.btn-box
    margin-left: 12rpx;
    width: 70rpx;
    height: 70rpx;
    border-radius: 50%
    background: #F5F5F5;
    display: flex
    align-items: center
    justify-content: center
    .send-btn,
    .receive-btn
        transition: transform 0.5s ease;
        width: 38rpx;
        height: 38rpx;
    .btn-box-round
        width: 22rpx
        height: 22rpx
        border-radius: 4rpx
        background: #FFFFFF
.purple
    background: linear-gradient( 225deg, #9E74FD 0%, #256BFA 100%);
.add-file-btn{
    transform: rotate(45deg)
    transition: transform 0.5s ease;
}
.area-tips{
    font-weight: 400;
    font-size: 26rpx;
    color: #434343;
    margin-top: 18rpx
}
.area-file
    display: grid
    width: 100%
    grid-template-columns: repeat(3, 1fr)
    grid-gap: 20rpx
    padding: 20rpx 0 0 0;
    .file-card
        display: flex
        flex-direction: column
        align-items: center
        padding: 24rpx 0
        background: #F5F5F5;
        border-radius: 20rpx 20rpx 20rpx 20rpx;
        text
            font-size: 24rpx
            font-weight: 500
            color: rgba(0,0,0,.5)
            padding-top: 8rpx
        .card-img
            height: 56rpx
            width: 56rpx
    .file-card:active
        background: #e8e8e8

.area-uploadfiles
    position: absolute
    top: -180rpx
    width: calc(100% - 30rpx)
    background: #FFFFFF
    left: 0
    padding: 10rpx 0 10rpx 30rpx
    box-shadow: 0rpx -4rpx 10rpx 0rpx rgba(11,44,112,0.06);
    .uploadfiles-scroll
        height: 100%
        .uploadfiles-list
            height: 100%
            display: flex
            margin-right: 28rpx
            flex-wrap: nowrap
            .file-doc
                display: flex
                align-items: center
                justify-content: flex-start
                padding: 16rpx 20rpx 18rpx 20rpx
                height: calc(100% - 40rpx)
                .doc-icon
                    width: 60rpx
                    height: 76rpx
                    margin-right: 20rpx
                .doc-con
                    flex: 1
                    width: 0
            .file-uploadsend
                margin: 10rpx 18rpx 0 0;
                height: 100%
                font-size: 24rpx
                position: relative
                min-width: 460rpx;
                height: 160rpx;
                border-radius: 12rpx 12rpx 12rpx 12rpx;
                border: 2rpx solid #E2E2E2;
                overflow: hidden
                .file-del
                    position: absolute
                    right: 25rpx
                    top: 18rpx
                    z-index: 9
                    border-radius: 50%
                    display: flex
                    align-items: center
                    justify-content: center
                    transform: translate(50%, -10rpx)
                    height: 40rpx
                    width: 37rpx;
                    height: 37rpx;
                    background: #4B4B4B;
                    border: 2rpx solid #FFFFFF;
                .file-del:active
                    background: #e8e8e8
                .filename-text
                    overflow: hidden
                    text-overflow: ellipsis
                    white-space: nowrap
                    color: #333333
                    font-size: 24rpx
                    font-weight: 500
                    max-width: 100%
                .filename-size
                    overflow: hidden
                    text-overflow: ellipsis
                    white-space: nowrap
                    color: #7B7B7B;
                    max-width: 100%
                .file-iconImg
                    height: 100%
                    width: 100%
                .filerow
                    display: flex
                    align-items: center
                    margin-top: 7rpx
                    .row-x
                        margin: 0 18rpx
                        height: 20rpx
                        width: 2rpx
                        background: rgba(226, 226, 226, .9)
            .file-border
                width: 160rpx !important;

@keyframes ai-circle {
    0% {
        -webkit-transform: rotate(0);
        transform: rotate(0);
    }
    100% {
        -webkit-transform: rotate(360deg);
        transform: rotate(360deg);
    }
}
.ai-loading
    display: inline-flex;
    vertical-align: middle;
    width: 28rpx;
    height: 28rpx;
    background: 0 0;
    border-radius: 50%;
    border: 4rpx solid;
    border-color: #e5e5e5 #e5e5e5 #e5e5e5 #8f8d8e;
    -webkit-animation: ai-circle 1s linear infinite;
    animation: ai-circle 1s linear infinite;
</style>
