<template><a-layout class="app-container">

        <a-layout-header class="header">
            <a-flex justify="space-between" align="center" style="height: 100%">
                <div class="logo-title">
                    <!-- <WifiOutlined />
                    直播中台控制系统 -->
                </div>
                <a-space :size="20">
                    <SettingOutlined class="action-icon" />
                    <a-avatar size="default" style="background-color: #1677ff">
                        <template #icon>
                            <UserOutlined />
                        </template>
                    </a-avatar>
                </a-space>
            </a-flex>
        </a-layout-header>

        <a-layout>

            <a-layout-sider resizable width="300" :min-width="250" :max-width="500" class="sider">
                <div class="sider-top" style="overflow-y: auto;flex: 2;border-bottom: 1px solid #e8e8e8;max-height: calc(100% * 2 / 5);min-height: calc(100% * 2 / 5);">
                    
                    <a-flex justify="space-between" align="center" style="margin-bottom: 16px">
                        <a-space align="left" >
                            <a-typography-title :level="5">
                                岗位列表
                            </a-typography-title>
                        </a-space>
                        <a-space align="right" >
                            <a-button type="primary" @click="handleShow" :loading="modelLoading" >
                                添加岗位
                            </a-button>
                        </a-space>
                    </a-flex>

                    <a-list :data-source="positions" item-layout="horizontal">
                        <template #renderItem="{ item, index }" >
                            <a-list-item class="position-item" >
                                <DeleteOutlined title="删除此项" @click.stop="deletedGw(index)" 
                                    style="color: #1677ff; margin-right: 5px;margin-bottom: 3px;" />
                                <a-list-item-meta :title="item.title" @click="setGwDetail(index)" >
                                </a-list-item-meta>
                                <RightOutlined @click="sendMessageGwAll(index)" />
                            </a-list-item>
                        </template>
                    </a-list>

                    <a-divider />
                </div>
                <div ref="listScrollRef" class="sider-bottom" style="overflow-y: auto;flex: 3;max-height: calc(100% * 3 / 5);">
                    
                    <a-typography-title :level="5">岗位详情</a-typography-title>
                
                    <a-list :data-source="dutyList" item-layout="horizontal">
                        <template #renderItem="{ item, index }" >
                            <a-list-item @click="resetSayin" :ref="($el) => insertItemList($el)" class="position-item" :class="{ 'highlight-item': index === scrollIndex }">
                                <h6 class="details-title" v-if="item.length === 5 " >
                                    <StarFilled style="color: #1677ff; margin-left:-20px;margin-right:5px;" />{{ item }}
                                </h6>
                                <a-list-item-meta v-else :title="item" >
                                </a-list-item-meta>
                            </a-list-item>
                        </template>
                    </a-list>
                </div>
            </a-layout-sider>

            <a-layout class="main-content-layout">

                <a-layout-content class="content-scroll-area">

                    <a-card title="直播控制" size="small">
                        <a-row :gutter="[16, 16]">
                            <a-col :xs="24" :sm="12" :md="8">
                                <a-button type="primary" block @click="startLive" :loading="loading || isLiveOn">
                                    <template #icon>
                                        <PlayCircleOutlined />
                                    </template>
                                    开始直播
                                </a-button>
                            </a-col>
                            <a-col :xs="24" :sm="12" :md="8">
                                <a-button type="danger" block @click="stopLive" :loading="loading"
                                    :disabled="!isLiveOn">
                                    <template #icon>
                                        <StopOutlined />
                                    </template>
                                    结束直播
                                </a-button>
                            </a-col>
                            <a-col :xs="24" :sm="12" :md="8">
                                <a-button block @click="fullScreenInsert" :disabled="!isLiveOn">
                                    <template #icon>
                                        <DesktopOutlined />
                                    </template>
                                    全屏插播
                                </a-button>
                            </a-col>
                            <a-col :xs="24" :sm="12" :md="8">
                                <a-button block @click="windowInsert" :disabled="!isLiveOn">
                                    <template #icon>
                                        <FullscreenOutlined />
                                    </template>
                                    窗口插播
                                </a-button>
                            </a-col>
                            <a-col :xs="24" :sm="12" :md="8">
                                <a-button block @click="audioInsert" :disabled="!isLiveOn">
                                    <template #icon>
                                        <HighlightOutlined />
                                    </template>
                                    音频插入
                                </a-button>
                            </a-col>
                            <a-col :xs="24" :sm="12" :md="8">
                                <a-button block @click="forceClose">
                                    <template #icon>
                                        <VideoCameraOutlined />
                                    </template>
                                    强制关闭
                                </a-button>
                            </a-col>
                        </a-row>
                    </a-card>

                    <a-card title="讲解输出" size="small">
                        <div class="placeholder-box">
                        </div>
                    </a-card>

                    <a-card title="AI模型管理" size="small">
                        <a-flex justify="space-between" align="center" style="margin-bottom: 16px">
                            <a-space>
                                <a-typography-text>当前模型:</a-typography-text>
                                <a-tag :color="modelStatus.exists ? 'green' : 'orange'">
                                    {{ modelStatus.modelName }}
                                    <template v-if="modelStatus.exists">
                                        <CheckCircleOutlined />
                                    </template>
                                    <template v-else>
                                        <ClockCircleOutlined />
                                    </template>
                                </a-tag>
                                <a-tag :color="modelStatus.ollamaRunning ? 'green' : 'red'">
                                    {{ modelStatus.ollamaRunning ? 'Ollama运行中' : 'Ollama未运行' }}
                                </a-tag>
                            </a-space>
                            <a-space>
                                <a-button type="primary" @click="loadModel" :loading="modelLoading"
                                    :disabled="modelLoading">
                                    <template #icon>
                                        <DownloadOutlined />
                                    </template>
                                    {{ modelLoading ? '加载中...' : '加载模型' }}
                                </a-button>
                                <a-button @click="refreshModelStatus" :disabled="modelLoading">
                                    <template #icon>
                                        <ReloadOutlined />
                                    </template>
                                    刷新状态
                                </a-button>
                            </a-space>
                        </a-flex>

                        <!-- 文件拖拽区域 -->
                        <div class="file-drop-zone" @drop="handleFileDrop" @dragover.prevent @dragenter.prevent
                            :class="{ 'is-dragging': fileUploadLoading }">
                            <p class="file-drop-icon">
                                <InboxOutlined />
                            </p>
                            <p class="file-drop-text">拖拽图片、拖拽视频文件，自动展示</p>
                            <p class="file-drop-hint">支持图片、视频格式</p>
                        </div>

                        <!-- 已上传文件列表 -->
                        <div v-if="uploadedFiles.length > 0" class="uploaded-files-list">
                            <div v-for="(file, index) in uploadedFiles" :key="index" class="file-item">
                                <div class="file-info">
                                    <FileOutlined class="file-icon" />
                                    <span class="file-name">{{ file.name }}</span>
                                    <a-tag :color="getFileTagColor(file.type)" size="small">{{
                                        getFileTypeText(file.type)
                                    }}</a-tag>
                                </div>
                                <a-button size="small" danger @click="removeFile(index)">
                                    <template #icon>
                                        <DeleteOutlined />
                                    </template>
                                    删除
                                </a-button>
                            </div>
                        </div>

                        <a-space style="margin-top: 12px;">
                            <a-button @click="clearAllFiles" :disabled="uploadedFiles.length === 0">
                                <template #icon>
                                    <DeleteOutlined />
                                </template>
                                清空文件
                            </a-button>
                            <a-button @click="showFilesInLive" :disabled="uploadedFiles.length === 0 || !isLiveOn">
                                <template #icon>
                                    <EyeOutlined />
                                </template>
                                在直播中展示
                            </a-button>
                        </a-space>
                    </a-card>

                </a-layout-content>

                <a-layout-footer class="input-footer">
                    <a-space>
                        <a-button danger size="small" block @click="polishText" :loading="polishLoading"
                            :disabled="!inputValue.trim()">
                            润色
                        </a-button>
                    </a-space>
                    <a-space-compact block style="display: flex; margin-bottom: 8px; margin-top: 8px;">
                        <a-textarea v-model:value="inputValue" placeholder="输入指令..."
                            :auto-size="{ minRows: 1, maxRows: 3 }" @press-enter="sendMessage" />
                        <a-button type="primary" @click="sendMessage" :disabled="!isLiveOn">发送</a-button>
                    </a-space-compact>
                    <a-space>
                        <a-typography-text type="secondary">快捷指令:</a-typography-text>
                        <a-button type="dashed" size="small" @click="setQuickCommand('欢迎新观众')">欢迎新观众</a-button>
                        <a-button type="dashed" size="small" @click="setQuickCommand('感谢大家的陪伴')">感谢陪伴</a-button>
                        <a-button type="dashed" size="small" @click="setQuickCommand('有什么问题可以随时提问')">互动提问</a-button>
                        <a-button type="dashed" size="small"
                            @click="setQuickCommand('今天给大家分享一些有趣的行业资讯')">行业分享</a-button>
                    </a-space>
                </a-layout-footer>
            </a-layout>

        </a-layout>
    </a-layout>

    <!-- 可输入内容的模态框 -->
    <a-modal
      v-model:open="showModal"
      width="800px"
      ok-text="提交"
      cancel-text="取消"
      @ok="handleOk"
      @cancel="handleCancel"
      :maskClosable="false"
      :destroyOnClose="true"
      :confirmLoading="confirmLoading"
    > 
      <template #title>
        <div class="modal-title-wrapper">
          <!-- 标题栏右侧按钮组 -->
          <div class="title-button-group">
            <a-row>
                <a-col :span="10">
                    <!-- 原标题文字 -->
                    <a-label style="font-weight: bolder;" >新增岗位信息</a-label>
                    <!-- 暂时没有其他格式得，默认就是text
                    <a-button 
                    :type="btn1Type" 
                    size="small" 
                    @click="typeChange('btn1')"
                    style="margin-left:10px;"
                    >
                    文本
                    </a-button>
                    <a-button 
                    :type="btn2Type" 
                    size="small" 
                    @click="typeChange('btn2')"
                    style="margin-left:5px;"
                    >
                    JSON
                    </a-button>
                    -->
                </a-col>
                <a-col :span="14">
                    <!-- 在提交得时候自动进行转换 ， 仅保留文字润色功能
                    <a-button 
                    type="default" 
                    size="small" 
                    @click="transText"
                    style="margin-left:13px;"
                    >
                    转换
                    </a-button>
                    -->
                    <a-button 
                    type="default" 
                    size="small" 
                    @click="handleCancel"
                    style="margin-left:5px;"
                    >
                    润色
                    </a-button>
                </a-col>   
            </a-row>
          </div>
        </div>
      </template>

      <!-- 表单区域 -->
      <a-form
        ref="formRef"
        :model="formData"
        :rules="formRules"
        :label-col="{ span: 6 }"  
        :wrapper-col="{ span: 50 }"
        layout="horizontal"
      >
        <a-row :gutter="16">
            <a-col :span="24">
                <!-- 单行输入框 -->
                <a-form-item label="" name="infoin">
                <a-textarea
                    v-model:value="formData.infoin"
                    placeholder="请输岗位信息"
                    :rows="15"
                    maxlength="2000"
                />
                </a-form-item>
            </a-col>

            <a-col :span="0">
                <div style="width: 375px;height: 340px;overflow-y: scroll;">
                    <!-- 多行文本框 -->
                    <div v-for="(item, index) in formData.infoDetail" 
                    :key="index" 
                    >
                        <textarea style="overflow: hidden;border: none;line-height: 1.1;height: auto;min-height: 10px;outline: none;width: 100%;flex: none;resize: none;margin: 0px;padding: 0px 5px;word-wrap: break-word;word-break: break-all;"
                            v-model="formData.infoDetail[index]" 
                            readonly="true" class="auto-wrap-textarea" wrap="soft"
                        />
                    </div>
                </div>
            </a-col>
        </a-row>
      </a-form>
    </a-modal>

</template>

<script setup>
import { ref, onMounted, onUnmounted, computed, reactive, nextTick, watch } from 'vue';
import { message, Modal, } from 'ant-design-vue';
import SocketClient from '@renderer/utils/socket';
import {
    WifiOutlined,
    SettingOutlined,
    UserOutlined,
    RightOutlined,
    StarFilled,
    PlayCircleOutlined,
    StopOutlined,
    DesktopOutlined,
    FullscreenOutlined,
    HighlightOutlined,
    VideoCameraOutlined,
    InboxOutlined,
    DeleteOutlined,
    MoreOutlined,
    DownloadOutlined,
    ReloadOutlined,
    CheckCircleOutlined,
    ClockCircleOutlined,
    FileOutlined,
    EyeOutlined,
} from '@ant-design/icons-vue';
import { useUserStore } from '@renderer/stores/useUserStore';

// 从 store 获取用户信息
const userStore = useUserStore();

// socket核心变量定义
const WS_URL = 'wss://dmdemo.hx.cn/ws?session_id='; // 你的 WSS 地址
let socketClient = null; // Socket 实例（约束类型）
// 响应式变量（强类型）
const isConnected = ref(false);
const sendMsg = ref('');
const msgList = ref([]); // 消息列表强类型
const dutyList = ref([]);
let liveIsSay = ref(false);

const listScrollRef = ref([])
const listItemRefs = ref([])
const insertItemList = (_this) => {
    listItemRefs.value.push(_this)
}
let scrollIndex = ref(0);//记录现在滚动到哪了
const scrollToIndex = (index) => {
  console.log("listItemRefs.value[index].$el.offsetTop",listItemRefs.value[index].$el.offsetTop)
  scrollIndex.value = index;
  let scrollto = listItemRefs.value[index].$el.offsetTop-listItemRefs.value[0].$el.offsetTop;
  if(scrollto < 0) scrollto = 0;
  nextTick(() => { // 确保 DOM 已渲染完成
    listScrollRef.value.scrollTo({
      top: scrollto,//每次滚动定格其实不好看，就减去一点
      behavior: 'smooth'
    });
  });
};


const resetSayin = () => {
    liveIsSay.value = false;//我说完啦
    //console.info('我说完啦：重置好说话状态，现在没有在说话啦');
}

// 2. 格式化时间
const formatTime = () => {
  const now = new Date();
  return `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`;
};

// 初始化 WebSocket 连接
const initWebSocket = (_initWebSocket) => {
  if(_initWebSocket){
    socketClient = new SocketClient(WS_URL+_initWebSocket, {
        heartbeatInterval: 20000,
        // 连接成功回调（类型约束）
        onOpen: () => {
        isConnected.value = true;
            msgList.value.push({
                time: formatTime(),
                type: 'system',
                content: 'Socket 长连接建立成功'
            });
            console.info('Socket 长连接建立成功');
        },
        // 接收消息回调（类型约束）
        onMessage: (data) => {
            console.info('接收回调消息：', data);
            let msg = data;
            // 仅解析字符串类型的 JSON 消息
            if (typeof data === 'string' && data.indexOf("{") == 0) {
                setTimeout(resetSayin,500)
                try {
                    msg = JSON.parse(data);
                } catch (e) {
                    console.warn('消息非 JSON 格式：', e);
                }
            }
            msgList.value.push({
                time: formatTime(),
                type: 'receive',
                content: msg
            });
        },
        // 错误回调（类型约束）
        onError: (error) => {
            isConnected.value = false;
            msgList.value.push({
                time: formatTime(),
                type: 'system',
                content: `Socket 错误：${error.message || '未知错误'}`
            });
        },
        // 关闭回调（类型约束）
        onClose: (event) => {
            isConnected.value = false;
            msgList.value.push({
                time: formatTime(),
                type: 'system',
                content: `Socket 断开：${event.reason || '网络波动，正在重连...'}`
            });
        }
    });
  }
};

const sayMessageList = ref([]);
//将职位详情添加到虚拟的待播放队列中
const sendMessageGwAll = (_index) => {
  if (dutyList.value.length == 0) {
    setGwDetail(_index);
  }

  if(dutyList.value){
    let index = 0;
    for(const oneItem of dutyList.value){
        const oneMessage = {};
        oneMessage["type"] = "dutyDetail";
        oneMessage["message"] = oneItem;
        oneMessage["dutyIndex"] = index++;
        sayMessageList.value.push(oneMessage);
    }
    console.log("待播放消息列表：",sayMessageList)
  }
}

const setGwDetail = (_index) => {
  const jsonData = getFromLocalStorage('gangweiList');
  while (dutyList.value.length > 0) {
    dutyList.value.splice(0, 1);
  }
  if(jsonData[_index]&&jsonData[_index]["infoDetail"]){
    for (const oneItem of jsonData[_index]["infoDetail"]){
        dutyList.value.push(oneItem);
    }
  }
}

const initGwData = () => {
    while (positions.value.length > 0) {
        positions.value.splice(0, 1);
    }
    const jsonData = getFromLocalStorage('gangweiList');
    if(jsonData){
        for (const oneItem of jsonData){
            const oneTitle = {};
            oneTitle.title = oneItem["gwName"];
            positions.value.push(oneTitle);
        }
    }
}

const deletedGw = (_index) => {
    Modal.confirm({
        title: '是否确认删除岗位信息?',
        content: positions.value[_index]['title'],
        okText: '确认删除',
        cancelText: '取消',
        centered: true,
        width: 400,
        maskClosable: false,
        onOk() {
          const jsonData = getFromLocalStorage('gangweiList');
          jsonData.splice(_index, 1);
          const result = saveToLocalStorage(jsonData,'gangweiList');
          if(result){
            positions.value.splice(_index, 1);
            while (dutyList.value.length > 0) {
                dutyList.value.splice(0, 1);
            }
            
            message.success('删除成功')
          }else{
          message.error('删除失败')
          }
        },
        onCancel() {
          message.error('取消操作')
        }
    });
}

const doText = () => {
    //遇到句号就切分
    const tempStr1 = (formData.infoin || "")
                        .replace(/\n/g, "。")
                        .trim();
    
    formData.infoDetail = tempStr1.split("。").filter(item => {
                        // 过滤空项、仅含空格/换行的项
                        return item.trim() !== "";
                      });
    formData.gwName = formData.infoDetail[0];
}
const doJson = () => {
    try {
        console.log("jsonStr",formData.infoin.replace(/\n/g, "").replace(" ", "").trim())
        const data = JSON.parse(formData.infoin.replace(/\n/g, "").replace(" ", "").trim());
        console.log("data",data)
    } catch (err) {
        message.error("json转换失败");
    }
}

const transText = () => {
    if(textType == "text"){
        doText();
    }else if(textType == "json"){
        doJson();
    }
}

const btn1Type = ref('primary')
const btn2Type = ref('text')
let textType = "text";
const typeChange = (btnKey) => {
    switch (btnKey) {
        case 'btn1':
            btn1Type.value = 'primary';
            btn2Type.value = 'text';
            textType = "text";
            break
        case 'btn2':
            btn2Type.value = 'primary';
            btn1Type.value = 'text';
            textType = "json";
            break
        default:
            break
    }
}

const showModal = ref(false)
const confirmLoading = ref(false)
// 表单引用
const formRef = ref(null)

// 表单数据
const formData = reactive({
  infoin: '',    // 输入内容
  gwName: '',    // 提交时处理岗位名称
  infoDetail: ref([])   // 内容解析
})
const formRules = reactive({
  infoin: [
    { required: true, message: '请输入岗位信息', trigger: 'blur' },
    { min: 20, max: 2000, message: '岗位信息长度需在 20-2000 个字符之间', trigger: 'blur' }
  ],
  /* 提交时自动进行得转换，就校验啦，保留字段是因为不向改变结构，其他地方都得动
  gwName: [ //没有对应的form元素，验证不生效
    { required: true, message: '未进行转换', trigger: 'blur' }
  ],
  infoDetail: [ //动态列表，验证不生效
    { required: true, message: '未进行转换', trigger: 'blur' }
  ]
  */
})
const saveToLocalStorage = (data, key) => {
  try {
    // 存储到localStoragev
    localStorage.setItem(key, JSON.stringify(data));
    console.log('表单数据已成功存储到localStorage！');
    return true;
  } catch (err) {
    // 捕获所有可能的报错（格式错误、大小超限等）
    const errorMsg = `存储失败：${err.message}`;
    console.error('localStorage存储报错：', err);
    return false;
  }
};

const getFromLocalStorage = (key) => {
  try {
    
    // 步骤1：读取存储的字符串
    const jsonStr = localStorage.getItem(key);
    
    // 步骤2：判断是否存在数据
    if (!jsonStr) {
      console.error('localStorage中无该表单数据！');
      return null;
    }
    // 步骤3：解析JSON字符串为对象/数组（核心！）
    const data = JSON.parse(jsonStr);
    
    console.log('表单数据已从localStorage加载！');
    
    return data;
    
  } catch (err) {
    const errorMsg = `读取失败：${err.message}（可能是JSON格式错误）`;
    console.error('localStorage读取报错：', err);
    return null;
  }
};

const refreshGwList = async () => {
    const jsonData = getFromLocalStorage('gangweiList');
    
}

// 确认提交
const handleOk = async () => {
  try {
    // 1. 表单校验
    await formRef.value.validate()
    transText();

    let jsonData = getFromLocalStorage('gangweiList');
    if (jsonData == null) {
        jsonData = []
    }

    jsonData.push({ ...formData });
    // 2. 模拟接口请求（实际项目中替换为真实接口）
    const result = saveToLocalStorage(jsonData,'gangweiList');
    if(result){
        const oneTitle = {};
        oneTitle.title = formData.gwName;
        positions.value.push(oneTitle);
        // 3. 提交成功处理
        message.success('提交成功！')
        console.log('提交的表单数据：', { ...formData })
    }else{
        message.success('提交失败')
        //里面已经打印了失败日志
    }
    // 4. 关闭模态框
    showModal.value = false
  } catch (error) {
    // 表单校验失败
    console.error('表单校验失败：', error)
    message.error('请检查输入内容是否符合要求')
  } finally {
    // 关闭加载状态
    confirmLoading.value = false
  }
}

const resetForm = () => {
  formData.infoin = '';    // 输入内容
  formData.gwName = '';    // 提交时处理岗位名称
  formData.infoDetail = [];   // 内容解析
}

const handleShow = () => {
  // 重置表单（清空输入值和校验状态）
  resetForm()
  // 关闭模态框
  showModal.value = true
}

// 取消弹窗
const handleCancel = () => {
  // 重置表单（清空输入值和校验状态）
  formRef.value?.resetFields()
  resetForm()
  // 关闭模态框
  showModal.value = false
}

// 左侧岗位列表数据
const positions = ref([
    { title: '主播岗位',  },
    { title: '运营岗位',  },
    { title: '场控岗位',  },
]);

// UI 状态 - 只负责界面显示
const inputValue = ref('');
const isLiveOn = ref(false);
const loading = ref(false);

// AI模型管理状态
const modelLoading = ref(false);
const modelStatus = ref({
    exists: false,
    ollamaRunning: false,
    modelName: 'qwen3:8b'
});

// 润色功能状态
const polishLoading = ref(false);

// 文件管理状态
const uploadedFiles = ref([]);
const fileUploadLoading = ref(false);

// 从 userStore 获取 userId (固定值 'rs876543')
const currentUserId = computed(() => {
    return userStore.user?.userId || 'rs876543';
});

// 状态同步 - 从主进程获取直播状态
const syncLiveStatus = async () => {
    try {
        //console.log('开始同步直播状态...');
        const result = await window.electron.ipcRenderer.invoke('get-live-status');
        //console.log('状态同步结果:', result);
        if (result.success) {
            const newState = result.data.isLiveOn;
            isLiveOn.value = newState;
        } else {
            console.error('状态同步失败:', result.error);
        }
    } catch (error) {
        console.error('获取直播状态失败:', error);
    }
};

// IPC 通信胶水代码 - 只负责与主进程通信
const startLive = async () => {
    if (loading.value) return;

    loading.value = true;
    try {
        console.log('开始启动直播...');
        const result = await window.electron.ipcRenderer.invoke('start-live', {
            userId: currentUserId.value // 从 userStore 获取固定 userId 'rs876543'
        });

        console.log('直播启动结果:', result);
        const sessionId = result["sessionId"];
        console.log('result["sessionId"]',sessionId)
        if(sessionId)(
            initWebSocket(sessionId) // 同步到sessionId时才进行socket
        )

        if (result.success) {
            // 等待一下确保状态已更新
            await new Promise(resolve => setTimeout(resolve, 500));

            // 立即同步状态
            await syncLiveStatus();

            message.success('直播已开始');
            console.log('直播启动成功，当前状态:', isLiveOn.value);
        } else {
            message.error('启动直播失败: ' + result.error);
            console.error('启动直播失败:', result.error);
        }
    } catch (error) {
        console.error('启动直播出错:', error);
        message.error('启动直播出错: ' + error.message);
    } finally {
        // 确保loading状态被重置
        loading.value = false;
        console.log('loading状态已重置:', loading.value);
    }
};

const stopLive = async () => {
    if (loading.value) return;

    loading.value = true;
    try {
        console.log('开始停止直播...');
        const result = await window.electron.ipcRenderer.invoke('stop-live');
        console.log('停止直播结果:', result);

        if (result.success) {
            // 等待一下确保状态已更新
            await new Promise(resolve => setTimeout(resolve, 300));

            // 立即同步状态
            await syncLiveStatus();

            message.success('直播已结束');
            console.log('直播停止成功，当前状态:', isLiveOn.value);
        } else {
            message.error('结束直播失败: ' + result.error);
            console.error('结束直播失败:', result.error);
        }
    } catch (error) {
        console.error('停止直播出错:', error);
        message.error('停止直播出错: ' + error.message);
    } finally {
        // 确保loading状态被重置
        loading.value = false;
        console.log('stopLive loading状态已重置:', loading.value);
    }
};

// 插播功能 - 直接调用主进程 IPC
const fullScreenInsert = async () => {
    window.electron.ipcRenderer.send('toggle-camera-insert');
    message.info('已切换全屏插播');
};

const windowInsert = async () => {
    window.electron.ipcRenderer.send('insert-camera-video');
    message.info('已开启窗口插播');
};

const audioInsert = async () => {
    window.electron.ipcRenderer.send('insert-video-audio');
    message.info('已插入音频');
};

const forceClose = async () => {
    try {
        console.log('开始强制关闭直播窗口...');
        const result = await window.electron.ipcRenderer.invoke('force-close-live');
        console.log('强制关闭结果:', result);

        if (result.success) {
            // 等待一下确保状态已更新
            await new Promise(resolve => setTimeout(resolve, 300));

            // 立即同步状态
            await syncLiveStatus();

            message.success('直播窗口已强制关闭');
            console.log('强制关闭成功，当前状态:', isLiveOn.value);
        } else {
            message.error('强制关闭失败: ' + result.error);
            console.error('强制关闭失败:', result.error);
        }
    } catch (error) {
        console.error('强制关闭出错:', error);
        message.error('强制关闭出错: ' + error.message);
    }
};

// AI模型管理函数
const checkModelStatus = async () => {
    try {
        console.log('检查模型状态...');
        const ollamaResult = await window.electron.ipcRenderer.invoke('check-ollama-status');
        const modelResult = await window.electron.ipcRenderer.invoke('check-model-exists', modelStatus.value.modelName);

        modelStatus.value.ollamaRunning = ollamaResult;
        if (modelResult.success) {
            modelStatus.value.exists = modelResult.exists;
            console.log('模型状态检查完成:', modelStatus.value);
        } else {
            console.error('模型检查失败:', modelResult.error);
        }
    } catch (error) {
        console.error('检查模型状态出错:', error);
    }
};

const loadModel = async () => {
    if (modelLoading.value) {
        message.warning('模型正在加载中，请稍候...');
        return;
    }

    modelLoading.value = true;
    try {
        console.log('开始加载AI模型...');
        const result = await window.electron.ipcRenderer.invoke('load-model', modelStatus.value.modelName);
        console.log('模型加载结果:', result);

        if (result.success) {
            if (result.downloaded) {
                message.success(`模型 ${modelStatus.value.modelName} 下载并加载成功！`);
            } else {
                message.success(`模型 ${modelStatus.value.modelName} 已就绪`);
            }

            // 重新检查模型状态
            await checkModelStatus();
        } else {
            message.error('加载模型失败: ' + result.message);
        }
    } catch (error) {
        console.error('加载模型出错:', error);
        message.error('加载模型出错: ' + error.message);
    } finally {
        modelLoading.value = false;
    }
};

const refreshModelStatus = async () => {
    await checkModelStatus();
    message.info('模型状态已刷新');
};


const sendMessageHasParam = async (syncliveSay) => {

    if(syncliveSay){//正说着呢
        //console.info('进入播放语音方法，有人正说着啦', syncliveSay);
        return false;
    }

    if (sayMessageList.value.length == 0) {
        //console.info('进入播放语音方法，待播放内容为空',sayMessageList.value.length);
        return false;
    }

    liveIsSay.value = true; //我准备说啦，后续需要考虑死锁问题
    //console.info('进入播放语音方法，我准备开始说啦,看看对象有什么',sayMessageList.value);

    try {
        const result = await window.electron.ipcRenderer.invoke('push-explain-position', sayMessageList.value[0]["message"]);
        if(sayMessageList.value[0]["type"] == "dutyDetail"){
            //如果是职位详情，播放是高亮，滚动
            scrollToIndex(sayMessageList.value[0]["dutyIndex"]);
        }
        sayMessageList.value.splice(0, 1);
        if (result.success) {
            message.success('消息已发送');
            return true;
        } else {
            message.error('发送失败: ' + result.error);
            return false;
        }
    } catch (error) {
        liveIsSay.value = false;
        console.error('发送消息出错:', error);
        message.error('发送消息出错');
        return false;
    }
}

// 发送消息到数字人
const sendMessage = () => {
    
    //临时添加也只是先添加到 语音消息队列中
    const oneMessage = {"type":"tempMessage","dutyIndex":0,message:inputValue.value};
    sayMessageList.value.unshift(oneMessage);//插播内容添加到开头
    inputValue.value = '';
    console.log("待播放消息列表：sayMessageList",sayMessageList)

};

// 润色文本功能
const polishText = async () => {
    if (!inputValue.value.trim()) {
        message.warning('请输入需要润色的文本');
        return;
    }

    if (polishLoading.value) {
        message.warning('正在润色中，请稍候...');
        return;
    }

    polishLoading.value = true;
    const originalText = inputValue.value;

    try {
        console.log('开始润色文本:', originalText);
        const result = await window.electron.ipcRenderer.invoke('polish-text', originalText);
        console.log('润色结果:', result);

        if (result.success) {
            inputValue.value = result.data;
            message.success('文本润色完成');
        } else {
            message.error('润色失败: ' + result.error);
            console.error('润色失败:', result.error);
        }
    } catch (error) {
        console.error('润色文本出错:', error);
        message.error('润色服务出错: ' + error.message);
    } finally {
        polishLoading.value = false;
    }
};

// 文件处理函数
const handleFileDrop = async (event) => {
    event.preventDefault();
    const files = Array.from(event.dataTransfer.files);

    if (files.length === 0) {
        message.warning('请选择要上传的文件');
        return;
    }

    // 过滤文件，只保留图片和视频
    const supportedFiles = files.filter(file => {
        const isImage = file.type.startsWith('image/');
        const isVideo = file.type.startsWith('video/');
        return isImage || isVideo;
    });

    const unsupportedFiles = files.filter(file => {
        const isImage = file.type.startsWith('image/');
        const isVideo = file.type.startsWith('video/');
        return !isImage && !isVideo;
    });

    // 如果有不支持的文件，给出提示
    if (unsupportedFiles.length > 0) {
        const unsupportedNames = unsupportedFiles.map(f => f.name).join(', ');
        message.warning(`以下文件类型不支持，已自动过滤: ${unsupportedNames}`);
    }

    if (supportedFiles.length === 0) {
        message.warning('请选择图片或视频文件');
        return;
    }

    fileUploadLoading.value = true;

    try {
        console.log('处理拖拽文件:', supportedFiles);

        for (const file of supportedFiles) {
            // 读取文件为base64或blob URL
            const fileInfo = await processFile(file);
            uploadedFiles.value.push(fileInfo);
        }

        message.success(`成功添加 ${supportedFiles.length} 个图片/视频文件`);

        // 如果正在直播，自动在直播窗口展示
        if (isLiveOn.value) {
            await showFilesInLive();
        }
    } catch (error) {
        console.error('文件处理失败:', error);
        message.error('文件处理失败: ' + error.message);
    } finally {
        fileUploadLoading.value = false;
    }
};

// 处理单个文件
const processFile = async (file) => {
    // 对于大文件，只传输基本信息，不传输完整数据
    // 在Electron环境中，我们可以使用文件路径
    const fileInfo = {
        name: file.name,
        type: file.type,
        size: file.size,
        path: file.path || file.webkitRelativePath || file.name, // 使用文件路径
        // 移除 data 字段，避免大文件导致克隆错误
    };
    return fileInfo;
};

// 获取文件类型文本
const getFileTypeText = (mimeType) => {
    if (mimeType.startsWith('image/')) return '图片';
    if (mimeType.startsWith('video/')) return '视频';
    if (mimeType.startsWith('audio/')) return '音频';
    if (mimeType.includes('pdf')) return 'PDF';
    if (mimeType.includes('word') || mimeType.includes('document')) return '文档';
    if (mimeType.includes('excel') || mimeType.includes('spreadsheet')) return '表格';
    return '文件';
};

// 获取文件标签颜色
const getFileTagColor = (mimeType) => {
    if (mimeType.startsWith('image/')) return 'green';
    if (mimeType.startsWith('video/')) return 'blue';
    if (mimeType.startsWith('audio/')) return 'purple';
    if (mimeType.includes('pdf')) return 'red';
    return 'default';
};

// 移除单个文件
const removeFile = async (index) => {
    try {
        const removedFile = uploadedFiles.value[index];

        uploadedFiles.value.splice(index, 1);

        // 通知直播窗口移除对应的展示
        if (isLiveOn.value) {
            await window.electron.ipcRenderer.invoke('remove-file-from-live', {
                index,
                fileName: removedFile.name
            });
        }

        message.success('文件已移除');
    } catch (error) {
        console.error('移除文件失败:', error);
        message.error('移除文件失败');
    }
};

// 清空所有文件
const clearAllFiles = async () => {
    try {
        uploadedFiles.value = [];

        // 通知直播窗口清空所有展示
        if (isLiveOn.value) {
            await window.electron.ipcRenderer.invoke('clear-all-files-from-live');
        }

        message.success('已清空所有文件');
    } catch (error) {
        console.error('清空文件失败:', error);
        message.error('清空文件失败');
    }
};

// 在直播中展示文件
const showFilesInLive = async () => {
    if (!isLiveOn.value) {
        message.warning('请先开始直播');
        return;
    }

    if (uploadedFiles.value.length === 0) {
        message.warning('没有可展示的文件');
        return;
    }

    try {
        console.log(uploadedFiles.value)
        console.log('在直播中展示文件:', uploadedFiles.value);

        // 将响应式对象转换为普通对象，避免序列化问题
        const filesData = JSON.parse(JSON.stringify(uploadedFiles.value));

        const result = await window.electron.ipcRenderer.invoke('show-files-in-live', {
            files: filesData
        });

        if (result.success) {
            message.success('文件已在直播窗口展示');
        } else {
            message.error('展示失败: ' + result.error);
        }
    } catch (error) {
        console.error('展示文件失败:', error);
        message.error('展示文件失败');
    }
};

const setQuickCommand = (command) => {
    inputValue.value = command;
};

// 处理直播状态更新
const handleLiveStatusUpdated = (event, data) => {
    console.log('收到直播状态更新:', data);
    if (data.windowLoaded) {
        syncLiveStatus();
    }
};

// 模型加载进度优化
const modelProgressTimer = ref(null);
const lastProgressMessage = ref('');
const progressDebounceDelay = 1000; // 1秒内最多显示一次进度更新

const handleModelLoadProgress = (event, data) => {
    // 清除之前的定时器
    if (modelProgressTimer.value) {
        clearTimeout(modelProgressTimer.value);
    }

    const messageType = data.type || 'info';
    const currentMessage = data.status;

    // 错误、成功、警告消息立即显示
    if (messageType === 'error') {
        message.error(`模型加载错误: ${currentMessage}`);
        return;
    }

    if (messageType === 'success') {
        message.success(currentMessage);
        lastProgressMessage.value = '';
        return;
    }

    if (messageType === 'warning') {
        message.warning(currentMessage);
        return;
    }

    // 下载进度和普通进度消息处理
    if (currentMessage === lastProgressMessage.value) {
        return;
    }

    const delay = messageType === 'download' ? 200 : progressDebounceDelay;
    const duration = messageType === 'download' ? 3 : 2;

    modelProgressTimer.value = setTimeout(() => {
        message.info(currentMessage, duration);
        lastProgressMessage.value = currentMessage;
    }, delay);
};

// 处理模型下载确认请求
const handleModelDownloadConfirm = async (_event, data) => {
    Modal.confirm({
        title: '模型下载确认',
        content: data.message,
        okText: '确认下载',
        cancelText: '取消',
        centered: true,
        width: 400,
        maskClosable: false,
        onOk() {
            window.electron.ipcRenderer.send('model-download-confirm-response', {
                modelName: data.modelName,
                confirmed: true,
                timestamp: new Date().toISOString()
            });
        },
        onCancel() {
            window.electron.ipcRenderer.send('model-download-confirm-response', {
                modelName: data.modelName,
                confirmed: false,
                timestamp: new Date().toISOString()
            });
        }
    });
};

onUnmounted(() => {
  if (socketClient) {
    socketClient.close(1000, '页面卸载');
    msgList.value.push({
      time: formatTime(),
      type: 'system',
      content: '页面卸载，主动关闭 Socket 长连接'
    });
  }
});

// 监听直播状态变化
onMounted(() => {
    
    setInterval(() => {
        sendMessageHasParam(liveIsSay.value)
    }, 1000);
    initGwData();
    // 初始化时同步状态
    syncLiveStatus();
    checkModelStatus(); // 初始化时检查模型状态

    // 监听窗口加载完成事件
    window.electron.ipcRenderer.on('live-status-updated', handleLiveStatusUpdated);

    // 监听模型加载进度
    window.electron.ipcRenderer.on('model-load-progress', handleModelLoadProgress);

    // 监听模型下载确认请求
    window.electron.ipcRenderer.on('model-download-confirm', handleModelDownloadConfirm);

    // 定期同步状态 (可选)
    const statusInterval = setInterval(syncLiveStatus, 1000);

    // 清理定时器
    onUnmounted(() => {
        clearInterval(statusInterval);
        if (modelProgressTimer.value) {
            clearTimeout(modelProgressTimer.value);
        }
        window.electron.ipcRenderer.off('live-status-updated', handleLiveStatusUpdated);
        window.electron.ipcRenderer.off('model-load-progress', handleModelLoadProgress);
        window.electron.ipcRenderer.off('model-download-confirm', handleModelDownloadConfirm);
    });
});
</script>

<style scoped>
/* 根容器：
  使用 100vh 充满窗口，并禁止窗口级别滚动。
  内部的 <a-layout> 会自动继承这个高度。
*/
.app-container {
    height: 100vh;
    overflow: hidden;
    /* 关键：禁止最外层滚动 */
}

/* 顶部导航栏 */
.header {
    background: #fff;
    border-bottom: 1px solid #f0f0f0;
    padding: 0 20px;
    height: 60px;
    /* 缩小顶部栏高度 */
    line-height: 60px;
    flex-shrink: 0;
    /* 防止顶部栏被压缩 */
    -webkit-app-region: drag;
}

.logo-title {
    font-size: 18px;
    /* 缩小字体 */
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 8px;
}

.action-icon {
    font-size: 16px;
    cursor: pointer;
}

/* 左侧边栏：
  - ant-layout-sider 默认有 100% 高度
  - 我们需要让 *内部* 的内容可滚动
*/
.sider {
    background: #fff;
    border-right: 1px solid #f0f0f0;
    /* 关键：Sider 本身高度 100%，
    但内部内容可能溢出，所以用一个 wrapper 来滚动
  */
    height: 100%;
}

.sider-scroll-content {
    height: 100%;
    overflow-y: auto;
    padding: 16px;
    /* 缩小内边距 */
}

.position-item {
    padding: 10px 8px;
    /* 缩小列表项间距 */
    border-radius: 6px;
    cursor: pointer;
    transition: background-color 0.3s;
}

.position-item:hover {
    background-color: #f7f7f7;
}

/* 岗位详情 */
.details-title {
    font-size: 14px;
    font-weight: 600;
    margin-top: 16px;
    margin-bottom: 8px;
    display: flex;
    align-items: center;
}

.details-list {
    padding-left: 24px;
    /* 缩小缩进 */
    margin: 0;
    color: #555;
    line-height: 1.7;
}

/* 右侧主布局：
  - 默认就是 flex: 1，自动撑满
  - 背景色放在这里，而不是 content-scroll-area
*/
.main-content-layout {
    background: #f0f2f5;
    /* 关键：确保内部的 content 和 footer 垂直排列 */
    display: flex;
    flex-direction: column;
    height: 100%;
    /* 继承父级高度 */
}

/* 右侧可滚动内容区：
  - flex: 1: 自动撑满所有可用空间
  - overflow-y: auto: 独立滚动
*/
.content-scroll-area {
    overflow-y: auto;
    padding: 16px;
    /* 缩小内边距 */
    flex: 1;
    /* 关键：撑满除 footer 外的空间 */
}

/* 讲解输出占位符 */
.placeholder-box {
    min-height: 120px;
    /* 缩小高度 */
    background: #fafafa;
    border: 1px dashed #d9d9d9;
    border-radius: 8px;
}

/* 底部输入框：
  - flex-shrink: 0: 确保不会被压缩
  - height: auto: 高度自适应
*/
.input-footer {
    background: #fff;
    padding: 12px 16px;
    /* 缩小内边距 */
    border-top: 1px solid #f0f0f0;
    box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.05);
    height: auto;
    /* 关键：高度自适应 */
    flex-shrink: 0;
    /* 关键：防止被压缩 */
}

/* 文件拖拽区域样式 */
.file-drop-zone {
    border: 2px dashed #d9d9d9;
    border-radius: 8px;
    padding: 24px;
    text-align: center;
    background-color: #fafafa;
    transition: all 0.3s ease;
    cursor: pointer;
    margin-bottom: 16px;
}

.file-drop-zone:hover,
.file-drop-zone.is-dragging {
    border-color: #1677ff;
    background-color: #f0f8ff;
}

.file-drop-icon {
    font-size: 48px;
    color: #1677ff;
    margin-bottom: 8px;
}

.file-drop-text {
    font-size: 16px;
    color: #262626;
    margin-bottom: 4px;
    font-weight: 500;
}

.file-drop-hint {
    font-size: 14px;
    color: #8c8c8c;
    margin: 0;
}

/* 文件列表样式 */
.uploaded-files-list {
    max-height: 200px;
    overflow-y: auto;
    border: 1px solid #f0f0f0;
    border-radius: 6px;
    margin-bottom: 12px;
}

.file-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 12px;
    border-bottom: 1px solid #f0f0f0;
}

.file-item:last-child {
    border-bottom: none;
}

.file-item:hover {
    background-color: #f5f5f5;
}

.file-info {
    display: flex;
    align-items: center;
    flex: 1;
    min-width: 0;
}

.file-icon {
    margin-right: 8px;
    color: #1677ff;
    flex-shrink: 0;
}

.file-name {
    font-size: 14px;
    color: #262626;
    margin-right: 8px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1;
}

/* 确保卡片之间有间距 */
.ant-card {
    margin-bottom: 16px;
}
/* 新增：index=5 时的高亮样式（可根据需求自定义） */
.highlight-item {
  background-color: #e6f7ff; /* 浅蓝色背景 */
  border-left: 3px solid #1677ff; /* 蓝色左侧边框强调 */
  padding-left: 15px !important; /* 调整内边距 */
  color: #1677ff; /* 文字变蓝 */
}

</style>