import React, { useEffect, useMemo, useState } from "react";
import {
  App,
  Avatar,
  Button,
  Col,
  Collapse,
  DatePicker,
  Drawer,
  Form,
  Input,
  Progress,
  Radio,
  Row,
  Select,
  Skeleton,
  Space,
  Switch,
  Tag,
  Tooltip,
  Typography,
  Upload,
} from "antd";
import {
  AudioOutlined,
  CheckOutlined,
  CloudUploadOutlined,
  QuestionCircleOutlined,
  SettingOutlined,
  UserOutlined,
} from "@ant-design/icons";
import dayjs from "dayjs";
import { useNavigate } from "react-router-dom";

import { listUsers } from "../../api";
import { getAiModelDefault, getAiModelPage, type AiModelVO } from "../../api/business/aimodel";
import { getHotWordPage, type HotWordVO } from "../../api/business/hotword";
import { getHotWordGroupOptions, type HotWordGroupVO } from "../../api/business/hotwordGroup";
import {
  createMeeting,
  createRealtimeMeeting,
  getMeetingCreateConfig,
  type CreateRealtimeMeetingCommand,
  type MeetingCreateConfig,
  type SummaryDetailLevel,
  uploadAudio,
} from "../../api/business/meeting";
import { getPromptPage, type PromptTemplateVO } from "../../api/business/prompt";
import type { SysUser } from "../../types";

const { Dragger } = Upload;
const { Option } = Select;
const { Text, Title } = Typography;

export type MeetingCreateType = "upload" | "realtime";

const DEFAULT_OFFLINE_AUDIO_MAX_SIZE_MB = 1024;
const DEFAULT_CREATE_CONFIG: MeetingCreateConfig = {
  offlineEnabled: true,
  realtimeEnabled: true,
  offlineAudioMaxSizeMb: DEFAULT_OFFLINE_AUDIO_MAX_SIZE_MB,
};

interface MeetingCreateDrawerProps {
  open: boolean;
  initialType?: MeetingCreateType;
  onCancel: () => void;
  onSuccess: () => void;
}

type RealtimeMeetingSessionDraft = {
  meetingId: number;
  meetingTitle: string;
  asrModelName: string;
  summaryModelName: string;
  asrModelId: number;
  mode: string;
  language: string;
  useSpkId: number;
  enablePunctuation: boolean;
  enableItn: boolean;
  enableTextRefine: boolean;
  saveAudio: boolean;
  hotwords: Array<{ hotword: string; weight: number }>;
};

function resolveAvailableCreateTypes(config: MeetingCreateConfig): MeetingCreateType[] {
  const types: MeetingCreateType[] = [];
  if (config.offlineEnabled) {
    types.push("upload");
  }
  if (config.realtimeEnabled) {
    types.push("realtime");
  }
  return types;
}

function resolveAvailableCreateType(initialType: MeetingCreateType, config: MeetingCreateConfig): MeetingCreateType {
  const availableTypes = resolveAvailableCreateTypes(config);
  if (availableTypes.includes(initialType)) {
    return initialType;
  }
  return availableTypes[0] || initialType;
}

function resolveWsUrl(model?: AiModelVO | null) {
  if (model?.wsUrl) return model.wsUrl;
  if (model?.baseUrl) return model.baseUrl.replace(/^http:\/\//, "ws://").replace(/^https:\/\//, "wss://");
  return "";
}

function getSessionKey(meetingId: number) {
  return `realtimeMeetingSession:${meetingId}`;
}

export const MeetingCreateDrawer: React.FC<MeetingCreateDrawerProps> = ({
  open,
  initialType = "upload",
  onCancel,
  onSuccess,
}) => {
  const { message } = App.useApp();
  const navigate = useNavigate();
  const [form] = Form.useForm();

  const [type, setType] = useState<MeetingCreateType>(initialType);
  const [loading, setLoading] = useState(false);
  const [configLoaded, setConfigLoaded] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [createConfig, setCreateConfig] = useState<MeetingCreateConfig>({
    offlineEnabled: false,
    realtimeEnabled: false,
    offlineAudioMaxSizeMb: DEFAULT_OFFLINE_AUDIO_MAX_SIZE_MB,
  });

  const [asrModels, setAsrModels] = useState<AiModelVO[]>([]);
  const [llmModels, setLlmModels] = useState<AiModelVO[]>([]);
  const [prompts, setPrompts] = useState<PromptTemplateVO[]>([]);
  const [hotwordList, setHotwordList] = useState<HotWordVO[]>([]);
  const [hotWordGroups, setHotWordGroups] = useState<HotWordGroupVO[]>([]);
  const [userList, setUserList] = useState<SysUser[]>([]);

  const [audioUrl, setAudioUrl] = useState("");
  const [uploadProgress, setUploadProgress] = useState(0);
  const [fileList, setFileList] = useState<any[]>([]);

  const watchedAsrModelId = Form.useWatch("asrModelId", form);
  const watchedSummaryModelId = Form.useWatch("summaryModelId", form);
  const watchedPromptId = Form.useWatch("promptId", form);
  const watchedHotWordGroupId = Form.useWatch("hotWordGroupId", form);

  const selectedAsrModel = useMemo(
    () => asrModels.find((item) => item.id === watchedAsrModelId) || null,
    [asrModels, watchedAsrModelId]
  );
  const selectedSummaryModel = useMemo(
    () => llmModels.find((item) => item.id === watchedSummaryModelId) || null,
    [llmModels, watchedSummaryModelId]
  );
  const selectedPrompt = useMemo(
    () => prompts.find((item) => item.id === watchedPromptId) || null,
    [prompts, watchedPromptId]
  );

  const availableTypes = useMemo(() => resolveAvailableCreateTypes(createConfig), [createConfig]);
  const offlineAudioMaxSizeBytes = useMemo(
    () => (createConfig.offlineAudioMaxSizeMb || DEFAULT_OFFLINE_AUDIO_MAX_SIZE_MB) * 1024 * 1024,
    [createConfig]
  );

  useEffect(() => {
    if (!open) {
      return;
    }
    setAudioUrl("");
    setUploadProgress(0);
    setFileList([]);
    void loadInitialData();
  }, [open, initialType]);

  const loadInitialData = async () => {
    setLoading(true);
    try {
      const [asrRes, llmRes, promptRes, hotwordRes, hotWordGroupRes, users, defaultAsr, defaultLlm, createConfigRes] = await Promise.all([
        getAiModelPage({ current: 1, size: 100, type: "ASR" }),
        getAiModelPage({ current: 1, size: 100, type: "LLM" }),
        getPromptPage({ current: 1, size: 100 }),
        getHotWordPage({ current: 1, size: 1000 }),
        getHotWordGroupOptions(),
        listUsers(),
        getAiModelDefault("ASR"),
        getAiModelDefault("LLM"),
        getMeetingCreateConfig(),
      ]);

      const nextConfig = createConfigRes.data.data || DEFAULT_CREATE_CONFIG;
      const nextType = resolveAvailableCreateType(initialType, nextConfig);
      const activePrompts = promptRes.data.data.records.filter((item: PromptTemplateVO) => item.status === 1);

      setCreateConfig(nextConfig);
      setConfigLoaded(true);
      setType(nextType);
      setAsrModels(asrRes.data.data.records.filter((item: AiModelVO) => item.status === 1));
      setLlmModels(llmRes.data.data.records.filter((item: AiModelVO) => item.status === 1));
      setPrompts(activePrompts);
      setHotwordList(hotwordRes.data.data.records.filter((item: HotWordVO) => item.status === 1));
      setHotWordGroups((hotWordGroupRes.data.data || []).filter((item: HotWordGroupVO) => item.status === 1));
      setUserList(users || []);

      const defaultPrompt = activePrompts[0];
      form.setFieldsValue({
        title: nextType === "upload" ? `文件会议 ${dayjs().format("MM-DD HH:mm")}` : `实时会议 ${dayjs().format("MM-DD HH:mm")}`,
        meetingTime: dayjs(),
        asrModelId: defaultAsr.data.data?.id,
        summaryModelId: defaultLlm.data.data?.id,
        promptId: defaultPrompt?.id,
        hotWordGroupId: defaultPrompt?.hotWordGroupId ?? 0,
        summaryDetailLevel: "STANDARD",
        useSpkId: 1,
        enableTextRefine: false,
        mode: "2pass",
        language: "auto",
        enablePunctuation: true,
        enableItn: true,
        saveAudio: false,
      });
    } catch {
      message.error("加载配置失败");
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    if (!open) {
      return;
    }
    const currentTitle = form.getFieldValue("title");
    if (typeof currentTitle !== "string") {
      return;
    }
    if (currentTitle.startsWith("文件会议") || currentTitle.startsWith("实时会议")) {
      form.setFieldsValue({
        title: type === "upload" ? `文件会议 ${dayjs().format("MM-DD HH:mm")}` : `实时会议 ${dayjs().format("MM-DD HH:mm")}`,
      });
    }
  }, [form, open, type]);

  const beforeAudioUpload = (file: File) => {
    if (file.size > offlineAudioMaxSizeBytes) {
      message.error(`录音文件大小不能超过 ${createConfig.offlineAudioMaxSizeMb}MB`);
      setUploadProgress(0);
      return Upload.LIST_IGNORE;
    }
    return true;
  };

  const customUpload = async (options: any) => {
    const { file, onSuccess: uploadSuccess, onError, onProgress } = options;
    setUploadProgress(0);
    try {
      const res = await uploadAudio(file, (progressEvent) => {
        if (progressEvent.total) {
          const percent = Math.min(99, Math.round((progressEvent.loaded * 100) / progressEvent.total));
          setUploadProgress(percent);
          onProgress({ percent });
        }
      });
      setUploadProgress(100);
      onProgress({ percent: 100 });
      setAudioUrl(res.data.data);
      uploadSuccess(res.data.data);
      message.success("录音上传成功");
    } catch (err) {
      onError(err);
      message.error("文件上传失败");
    }
  };

  const handleOk = async () => {
    if (availableTypes.length === 0) {
      message.error("当前系统参数已关闭全部会议创建入口");
      return;
    }
    if (!availableTypes.includes(type)) {
      const fallbackType = availableTypes[0];
      if (fallbackType) {
        setType(fallbackType);
      }
      message.warning("当前入口已关闭，已切换到可用创建方式");
      return;
    }
    if (type === "upload" && !audioUrl) {
      message.error("请先上传录音文件");
      return;
    }

    const values = await form.validateFields();
    if (type === "realtime") {
      const wsUrl = resolveWsUrl(selectedAsrModel);
      if (!wsUrl) {
        message.error("当前 ASR 模型未配置 WebSocket 地址");
        return;
      }
    }

    setSubmitting(true);
    try {
      const { hostUserId, ...meetingValues } = values;
      const selectedHotWords = meetingValues.hotWordGroupId == null || meetingValues.hotWordGroupId === 0
        ? undefined
        : hotwordList
            .filter((item) => item.hotWordGroupId === meetingValues.hotWordGroupId)
            .map((item) => item.word)
            .filter((word) => !!word?.trim());

      if (type === "upload") {
        await createMeeting({
          ...meetingValues,
          ...(hostUserId != null ? { hostUserId } : {}),
          meetingTime: meetingValues.meetingTime.format("YYYY-MM-DD HH:mm:ss"),
          audioUrl,
          participants: meetingValues.participants?.join(","),
          tags: meetingValues.tags?.join(","),
          summaryDetailLevel: meetingValues.summaryDetailLevel as SummaryDetailLevel,
          hotWords: selectedHotWords,
        });
        message.success("会议发起成功");
        onSuccess();
        onCancel();
        return;
      }

      const selectedHotwords = hotwordList
        .filter((item) => item.hotWordGroupId === meetingValues.hotWordGroupId && meetingValues.hotWordGroupId !== 0)
        .map((item) => ({
          hotword: item.word,
          weight: Number(item.weight || 2) / 10,
        }));

      const payload: CreateRealtimeMeetingCommand = {
        ...meetingValues,
        ...(hostUserId != null ? { hostUserId } : {}),
        meetingTime: meetingValues.meetingTime.format("YYYY-MM-DD HH:mm:ss"),
        participants: meetingValues.participants?.join(",") || "",
        tags: meetingValues.tags?.join(",") || "",
        summaryDetailLevel: meetingValues.summaryDetailLevel as SummaryDetailLevel,
        mode: meetingValues.mode || "2pass",
        language: meetingValues.language || "auto",
        useSpkId: meetingValues.useSpkId == null ? 1 : (meetingValues.useSpkId ? 1 : 0),
        enablePunctuation: meetingValues.enablePunctuation !== false,
        enableItn: meetingValues.enableItn !== false,
        enableTextRefine: !!meetingValues.enableTextRefine,
        saveAudio: !!meetingValues.saveAudio,
        hotWords: selectedHotWords,
      };

      const res = await createRealtimeMeeting(payload);
      const createdMeeting = res.data.data;
      const sessionDraft: RealtimeMeetingSessionDraft = {
        meetingId: createdMeeting.id,
        meetingTitle: createdMeeting.title,
        asrModelName: selectedAsrModel?.modelName || "ASR",
        summaryModelName: selectedSummaryModel?.modelName || "LLM",
        asrModelId: selectedAsrModel?.id || values.asrModelId,
        mode: values.mode || "2pass",
        language: values.language || "auto",
        useSpkId: values.useSpkId == null ? 1 : (values.useSpkId ? 1 : 0),
        enablePunctuation: values.enablePunctuation !== false,
        enableItn: values.enableItn !== false,
        enableTextRefine: !!values.enableTextRefine,
        saveAudio: !!values.saveAudio,
        hotwords: selectedHotwords,
      };

      sessionStorage.setItem(getSessionKey(createdMeeting.id), JSON.stringify(sessionDraft));
      message.success("会议已创建，即将进入实时识别");
      onSuccess();
      onCancel();
      navigate(`/meeting-live-session/${createdMeeting.id}`);
    } catch {
      message.error(type === "upload" ? "创建会议失败" : "创建实时会议失败");
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <Drawer
      title={null}
      open={open}
      onClose={onCancel}
      width={960}
      forceRender
      destroyOnClose={false}
      placement="right"
      closable={false}
      footer={
        configLoaded ? (
          <div style={{ textAlign: "right", padding: "16px 32px" }}>
            <Space size={16}>
              <Button onClick={onCancel} size="large" style={{ borderRadius: 8, minWidth: 120 }}>取消</Button>
              <Button type="primary" onClick={handleOk} loading={submitting} size="large" style={{ borderRadius: 8, minWidth: 140, fontWeight: 500 }}>
                {type === "upload" ? (audioUrl ? "完成并分析" : "上传并分析") : "创建并进入识别"}
              </Button>
            </Space>
          </div>
        ) : null
      }
      styles={{
        header: { display: "none" },
        body: { padding: 0, display: "flex", flexDirection: "column", background: "var(--app-bg-layout)" },
        footer: { padding: 0, borderTop: "1px solid var(--app-border-color)", background: "var(--app-bg-surface)", minHeight: configLoaded ? 72 : 0 }
      }}
    >
      {!configLoaded ? (
        <div style={{ padding: "40px" }}>
          <Skeleton active paragraph={{ rows: 12 }} />
        </div>
      ) : (
        <>
          <div style={{ background: "var(--app-bg-surface)", padding: "24px 32px", borderBottom: "1px solid var(--app-border-color)" }}>
        <Row justify="space-between" align="middle">
          <Col>
            <Space size={16}>
              <div style={{ width: 48, height: 48, borderRadius: 12, background: "var(--app-bg-surface-strong)", color: "var(--app-text-main)", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 24, border: "1px solid var(--app-border-color)" }}>
                {type === "upload" ? <CloudUploadOutlined /> : <AudioOutlined />}
              </div>
              <div>
                <Title level={4} style={{ margin: 0, fontWeight: 600 }}>{type === "upload" ? "上传录音发起分析" : "创建实时会议"}</Title>
                <Text type="secondary" style={{ fontSize: 13 }}>{type === "upload" ? "上传已有音频文件并由 AI 进行转写与总结分析" : "实时采集语音并进行流式转写与实时纪要生成"}</Text>
              </div>
            </Space>
          </Col>
          <Col>
            <Radio.Group value={type} onChange={e => setType(e.target.value)} optionType="button" buttonStyle="solid" size="large">
              {createConfig.offlineEnabled && (
                <Radio.Button value="upload" style={{ padding: "0 24px" }}><CloudUploadOutlined style={{ marginRight: 6 }} /> 上传录音</Radio.Button>
              )}
              {createConfig.realtimeEnabled && (
                <Radio.Button value="realtime" style={{ padding: "0 24px" }}><AudioOutlined style={{ marginRight: 6 }} /> 实时会议</Radio.Button>
              )}
            </Radio.Group>
          </Col>
        </Row>
      </div>

      <div style={{ padding: "32px 40px", flex: 1, overflowY: "auto", background: "var(--app-bg-layout)" }}>
        <Form form={form} layout="vertical" disabled={loading}>
          <div style={{ marginBottom: 24, display: "flex", alignItems: "center" }}>
            <div style={{ width: 4, height: 16, background: "#1890ff", borderRadius: 2, marginRight: 8 }} />
            <Title level={5} style={{ margin: 0 }}>基础信息</Title>
          </div>

          <Row gutter={32}>
            <Col span={12}>
              <Form.Item name="title" label="会议标题" rules={[{ required: true }]}>
                <Input placeholder="输入会议标题" size="large" />
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item name="meetingTime" label="会议时间" rules={[{ required: true }]}>
                <DatePicker showTime style={{ width: "100%" }} size="large" />
              </Form.Item>
            </Col>
          </Row>

          <Row gutter={32}>
            <Col span={12}>
              <Form.Item name="participants" label="参会人员">
                <Select mode="multiple" placeholder="选择参会人员" showSearch optionFilterProp="children" size="large">
                  {userList.map(u => (<Option key={u.userId} value={u.userId}><Space><Avatar size="small" icon={<UserOutlined />} />{u.displayName || u.username}</Space></Option>))}
                </Select>
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item name="hostUserId" label="会议主持人">
                <Select allowClear placeholder="默认为创建人" showSearch optionFilterProp="children" size="large">
                  {userList.map(u => (<Option key={u.userId} value={u.userId}><Space><Avatar size="small" icon={<UserOutlined />} />{u.displayName || u.username}</Space></Option>))}
                </Select>
              </Form.Item>
            </Col>
          </Row>

          <Row gutter={32}>
            <Col span={12}>
              <Form.Item name="tags" label="会议标签">
                <Select mode="tags" placeholder="输入标签" size="large" />
              </Form.Item>
            </Col>
          </Row>

          <div style={{ margin: "32px 0", borderTop: "1px solid var(--app-border-color)" }} />

          <div style={{ marginBottom: 24, display: "flex", alignItems: "center" }}>
            <div style={{ width: 4, height: 16, background: "#1890ff", borderRadius: 2, marginRight: 8 }} />
            <Title level={5} style={{ margin: 0 }}>模型与纪要配置</Title>
          </div>

          <Row gutter={32}>
            <Col span={12}>
              <Form.Item name="asrModelId" label="语音识别模型 (ASR)" rules={[{ required: true }]}>
                <Select placeholder="选择 ASR 模型" size="large">{asrModels.map(m => (<Option key={m.id} value={m.id}>{m.modelName}</Option>))}</Select>
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item name="summaryModelId" label="总结模型 (LLM)" rules={[{ required: true }]}>
                <Select placeholder="选择总结模型" size="large">{llmModels.map(m => (<Option key={m.id} value={m.id}>{m.modelName}</Option>))}</Select>
              </Form.Item>
            </Col>
          </Row>

          <Form.Item name="promptId" label="总结模板" rules={[{ required: true }]}>
            {prompts.length > 15 ? (
              <Select placeholder="请选择总结模板" showSearch optionFilterProp="children" size="large">
                {prompts.map(p => <Option key={p.id} value={p.id}>{p.templateName}</Option>)}
              </Select>
            ) : (
              <div style={{ padding: "2px" }}>
                <Row gutter={[12, 12]}>
                  {prompts.map(p => {
                    const isSelected = watchedPromptId === p.id;
                    return (
                      <Col span={8} key={p.id}>
                        <div onClick={() => form.setFieldsValue({ promptId: p.id })} style={{ padding: "12px 16px", borderRadius: 8, border: `1px solid ${isSelected ? "#1890ff" : "var(--app-border-color)"}`, background: isSelected ? "#e6f7ff" : "var(--app-bg-surface)", cursor: "pointer", position: "relative", transition: "all 0.2s", display: "flex", alignItems: "center", height: "100%" }}>
                          <div style={{ fontSize: "14px", color: isSelected ? "#1890ff" : "var(--app-text-main)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", fontWeight: isSelected ? 500 : 400 }}>{p.templateName}</div>
                          {isSelected && <div style={{ position: "absolute", top: -1, right: -1, width: 20, height: 20, background: "#1890ff", borderRadius: "0 8px 0 8px", display: "flex", alignItems: "center", justifyContent: "center" }}><CheckOutlined style={{ color: "#fff", fontSize: 12 }} /></div>}
                        </div>
                      </Col>
                    );
                  })}
                </Row>
              </div>
            )}
          </Form.Item>

          <Row gutter={32}>
            <Col span={12}>
              <Form.Item name="hotWordGroupId" label="热词组" tooltip={selectedPrompt?.hotWordGroupName ? `默认跟随模板：${selectedPrompt.hotWordGroupName}` : "模板未绑定热词组时可手动选择"} extra={watchedHotWordGroupId != null ? "创建会议时会优先使用这里选中的热词组" : undefined}>
                <Select placeholder={selectedPrompt?.hotWordGroupId ? "默认已带出模板热词组，可按需修改" : "请选择热词组"} size="large" options={[{ label: "不使用热词组", value: 0 }, ...hotWordGroups.map((item) => ({ label: `${item.groupName} (${item.hotWordCount}/200)`, value: item.id }))]} />
              </Form.Item>
            </Col>
              <Col span={12}>
                <Form.Item name="summaryDetailLevel" label="总结详细程度" rules={[{ required: true }]}>
                  <Radio.Group size="large">
                    <Radio value="DETAILED">详细</Radio>
                    <Radio value="STANDARD">标准</Radio>
                    <Radio value="BRIEF">简洁</Radio>
                  </Radio.Group>
                </Form.Item>
              </Col>
            </Row>

          <Collapse
            ghost
            expandIconPosition="end"
            style={{ marginBottom: 24, background: "var(--app-bg-surface)", border: "1px solid var(--app-border-color)", borderRadius: 8, overflow: "hidden" }}
            items={[
              {
                key: "advanced",
                forceRender: true,
                label: (
                  <div style={{ display: "flex", alignItems: "center", width: "100%", height: "32px" }}>
                    <div style={{ display: "flex", alignItems: "center", fontWeight: 600, color: "var(--app-text-main)", fontSize: 15 }}>
                      <div style={{ width: 32, height: 32, borderRadius: 8, background: "#f0f5ff", color: "#1677ff", display: "flex", alignItems: "center", justifyContent: "center", marginRight: 12 }}>
                        <SettingOutlined style={{ fontSize: 16 }} />
                      </div>
                      高级设置
                    </div>
                  </div>
                ),
                children: (
                  <div style={{ paddingTop: 8, borderTop: "1px dashed var(--app-border-color)" }}>
                    <Row gutter={32}>
                      <Col span={8}>
                        <Form.Item name="useSpkId" label={<span>说话人区分 <Tooltip title="自动识别录音中的不同发言者并进行角色分离"><QuestionCircleOutlined /></Tooltip></span>} valuePropName="checked" getValueProps={(v) => ({ checked: !!v })} normalize={(v) => (v ? 1 : 0)}>
                          <Switch />
                        </Form.Item>
                      </Col>
                      <Col span={8}>
                        <Form.Item name="enableTextRefine" label={<span>文本修正 <Tooltip title="自动识别并修正语音转写中的口语词、语气助词等"><QuestionCircleOutlined /></Tooltip></span>} valuePropName="checked">
                          <Switch />
                        </Form.Item>
                      </Col>
                      {type === "realtime" && (
                        <>
                          <Col span={8}>
                            <Form.Item name="saveAudio" label="保存录音" valuePropName="checked">
                              <Switch />
                            </Form.Item>
                          </Col>
                          <Col span={24}>
                            <Form.Item name="mode" label="识别模式">
                              <Radio.Group>
                                <Radio value="2pass">2pass（流式 + 离线修正）</Radio>
                                <Radio value="online">online（纯流式）</Radio>
                              </Radio.Group>
                            </Form.Item>
                          </Col>
                        </>
                      )}
                    </Row>
                    <Form.Item name="userPrompt" label="用户提示词" extra="提供补充信息以指导 AI 在生成会议总结时更侧重于特定方面或遵循特定风格">
                      <Input.TextArea placeholder="请输入额外说明，例如：请重点关注会议中的待办事项、以摘要形式输出、或者采用严谨的公文风格等" autoSize={{ minRows: 3, maxRows: 6 }} showCount maxLength={1000} />
                    </Form.Item>
                  </div>
                ),
              }
            ]}
          />

          {type === "upload" && (
            <>
              <div style={{ margin: "32px 0", borderTop: "1px solid var(--app-border-color)" }} />
              <div style={{ marginBottom: 24, display: "flex", alignItems: "center" }}>
                <div style={{ width: 4, height: 16, background: "#1890ff", borderRadius: 2, marginRight: 8 }} />
                <Title level={5} style={{ margin: 0 }}>上传录音文件</Title>
              </div>
              <Dragger
                accept=".mp3,.wav,.m4a"
                beforeUpload={beforeAudioUpload}
                fileList={fileList}
                customRequest={customUpload}
                onChange={info => setFileList(info.fileList.slice(-1))}
                maxCount={1}
                style={{ borderRadius: 12, padding: "32px 0", background: "var(--app-bg-surface)", border: "1px dashed var(--app-border-color)" }}
              >
                <div>
                  <p className="ant-upload-drag-icon" style={{ marginBottom: 16 }}><CloudUploadOutlined style={{ fontSize: 56, color: "#1890ff" }} /></p>
                  <p className="ant-upload-text" style={{ fontSize: 18, fontWeight: 500, color: "var(--app-text-main)" }}>点击或拖拽录音文件到此处</p>
                  <p className="ant-upload-hint" style={{ fontSize: 14, marginTop: 12, color: "var(--app-text-secondary)" }}>支持 mp3、wav、m4a 等格式，大小不超过 {createConfig.offlineAudioMaxSizeMb}MB</p>
                  {uploadProgress > 0 && uploadProgress < 100 && (
                    <div style={{ width: "60%", margin: "32px auto 0" }}>
                      <Progress percent={uploadProgress} size="small" />
                      <div style={{ fontSize: 13, color: "#1890ff", marginTop: 8 }}>文件上传中，请稍候...</div>
                    </div>
                  )}
                  {audioUrl && (
                    <Tag color="processing" style={{ marginTop: 24, padding: "6px 16px", fontSize: 14, borderRadius: 6, maxWidth: "90%", display: "inline-flex", alignItems: "center" }}>
                      <span>已上传：</span>
                      <span style={{ marginLeft: 4, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{audioUrl.split("/").pop()}</span>
                    </Tag>
                  )}
                </div>
              </Dragger>
            </>
          )}
        </Form>
      </div>
    </>
  )}
</Drawer>
  );
};