import React, { useEffect, useState, useRef } from 'react';
import { Button, Empty, Input, Select, Space, Typography, Tag, message, Modal, Table, DatePicker, Tabs, Transfer, Tooltip, Spin } from 'antd';
import dayjs from 'dayjs';
import JSZip from 'jszip';
import {
    FilterOutlined,
    VideoCameraOutlined,
    PictureOutlined,
    FolderOpenOutlined,
    FileTextOutlined,
    DownloadOutlined,
    ClockCircleOutlined,
    UploadOutlined,
    ReloadOutlined,
    StarOutlined,
    PlayCircleOutlined,
    DeleteOutlined,
    LoadingOutlined,
    UserOutlined,
} from '@ant-design/icons';
import { useSearchParams } from 'react-router-dom';
import { PrivatePortraitLibraryPanel } from '../components/privatePortrait';
import { UploadResourceHistoryPanel } from '../components/uploadResource';
import { gethistory, gethistoryItems, getOAuthList, asyncBatchUploadMaterial, updateFilename, getUploadHistory, getAllOAuthAccountList, getOpenTypeAll, getPreTestList, getDefaultPreTest, deleteHistory, deleteResourcesMaterial } from '../api';

const { Search } = Input;
const { Text } = Typography;

const usePageAllLoaded = (callback: () => void) => {
    const executedRef = React.useRef(false);
    useEffect(() => {
        if (executedRef.current) return;
        const handleLoad = () => {
            if (executedRef.current) return;
            executedRef.current = true;
            callback?.();
        };
        if (document.readyState === 'complete') {
            handleLoad();
        } else {
            window.addEventListener('load', handleLoad);
        }
        return () => {
            window.removeEventListener('load', handleLoad);
        };
    }, [callback]);
};

const GeneratedRecord: React.FC = () => {
    const [isPageLoaded, setIsPageLoaded] = useState(false);
    usePageAllLoaded(() => {
        setIsPageLoaded(true);
    });

    const [searchParams] = useSearchParams();
    const initialFilterType = searchParams.get('filterType') === 'private_portrait' ? 'private_portrait' : searchParams.get('filterType') === 'upload_resource' ? 'upload_resource' : 'project';
    const [filterType, setFilterType] = useState<'project' | 'creation' | 'hot_opening_replicate' | 'shot_replicate' | 'private_portrait' | 'upload_resource'>(initialFilterType);
    const [filterMedia, setFilterMedia] = useState<'video' | 'image'>('video');
    const [recordlist, setRecordList] = useState<any[]>([]);
    const [Pagebreak, setPagebreak] = useState<any>({
        page: 1,
        pageSize: 10,
    });
    const [Totalnumber, setTotalnumber] = useState<number>(0);
    const [loading, setLoading] = useState<boolean>(false);
    const [loadingGroups, setLoadingGroups] = useState<Set<string>>(new Set());
    const [previewVisible, setPreviewVisible] = useState(false);
    const [previewItem, setPreviewItem] = useState<any>(null);
    const videoRef = React.createRef<HTMLVideoElement>();
    const [selectedDate, setSelectedDate] = useState<string>('');

    const [uploading, setUploading] = useState(false);

    // 推送配置弹窗相关状态
    const [uploadConfigModalVisible, setUploadConfigModalVisible] = useState(false);
    const [accountIdLists, setAccountIdLists] = useState<{
        accountId: string;
    }[][]>([[]]);
    const [accountIdInputs, setAccountIdInputs] = useState<string[]>(['']);

    const [oauthList, setOauthList] = useState<any[]>([]);
    const [oauthLoading, setOauthLoading] = useState(false);
    const [oauthTotal, setOauthTotal] = useState(0);
    const [selectedOauthItems, setSelectedOauthItems] = useState<({ value: string; label: string } | undefined)[]>([undefined]);
    const [materialFileNames, setMaterialFileNames] = useState<Map<string, string>>(new Map());
    const [unifiedFileName, setUnifiedFileName] = useState('');
    const [mediaLoadStatus, setMediaLoadStatus] = useState<Map<string, 'loading' | 'loaded' | 'error'>>(new Map());
    const updateFilenameDebounceRef = useRef<Map<string, ReturnType<typeof setTimeout>>>(new Map());

    useEffect(() => {
        return () => {
            updateFilenameDebounceRef.current.forEach(timer => clearTimeout(timer));
            updateFilenameDebounceRef.current.clear();
        };
    }, []);
    const [oauthPage, setOauthPage] = useState(1);
    const [oauthPageSize, setOauthPageSize] = useState(10);
    const [oauthSelectOpens, setOauthSelectOpens] = useState<boolean[]>([false]);

    const [accountTab, setAccountTab] = useState<'new' | 'history'>('new');
    const [historyOAuthList, setHistoryOAuthList] = useState<any[]>([]);
    const [historyOAuthLoading, setHistoryOAuthLoading] = useState(false);
    const [selectedHistoryAccounts, setSelectedHistoryAccounts] = useState<any[]>([]);
    const [openTypeMap, setOpenTypeMap] = useState<Record<number, string>>({});

    const [isPreTest, setIsPreTest] = useState<string>('2');
    const [preTestTemplate, setPreTestTemplate] = useState<string>('');
    const [preTestTemplates, setPreTestTemplates] = useState<any[]>([]);
    const [preTestTemplatesLoading, setPreTestTemplatesLoading] = useState(false);
    // 推送任务历史弹窗相关状态
    const [uploadHistoryModalVisible, setUploadHistoryModalVisible] = useState(false);
    const [uploadHistoryList, setUploadHistoryList] = useState<any[]>([]);
    const [uploadHistoryTotal, setUploadHistoryTotal] = useState(0);
    const [uploadHistoryPage, setUploadHistoryPage] = useState(1);
    const [uploadHistoryPageSize, setUploadHistoryPageSize] = useState(10);
    const [uploadHistoryLoading, setUploadHistoryLoading] = useState(false);
    const [uploadHistoryStatus, setUploadHistoryStatus] = useState<string>('');
    const [isSelectionMode, setIsSelectionMode] = useState(false);
    const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set());
    // 从URL中提取exp时间戳（支持相对路径和完整URL）
    const extractExpTimestamp = (url: string): number | null => {
        if (!url) return null;
        try {
            // 尝试作为完整URL解析
            const urlObj = new URL(url);
            const expStr = urlObj.searchParams.get('exp');
            if (expStr) {
                return parseInt(expStr, 10);
            }
            return null;
        } catch {
            // 如果完整URL解析失败，尝试解析相对路径中的查询参数
            try {
                const queryStart = url.indexOf('?');
                if (queryStart !== -1) {
                    const queryString = url.substring(queryStart + 1);
                    const params = new URLSearchParams(queryString);
                    const expStr = params.get('exp');
                    if (expStr) {
                        return parseInt(expStr, 10);
                    }
                }
                return null;
            } catch {
                return null;
            }
        }
    };
    // 检查媒体是否过期
    const isMediaExpired = (url: string): boolean => {
        const expTimestamp = extractExpTimestamp(url);
        if (!expTimestamp) {
            return false; // 没有exp参数，视为不过期
        }
        const currentTimestamp = Math.floor(Date.now() / 1000);
        return currentTimestamp > expTimestamp;
    };
    const buildUrl = (path: string, isImage: boolean = false): string => {
        const baseUrl = import.meta.env.VITE_API_BASE || "http://localhost:8000";
        const cleanPath = path.startsWith('/') ? path.slice(1) : path;
        const cleanBase = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
        if (isImage) {
            return `${cleanBase}/static/${cleanPath}&w=300&q=50`;
        }
        return `${cleanBase}/${cleanPath}`;
    };
    // 下载文件
    const handleDownload = (item: any) => {
        const url = `${import.meta.env.VITE_API_BASE || "http://localhost:8000"}${item.videoUrl || item.imageUrl}`;
        const link = document.createElement('a');
        link.href = url;
        link.download = item.title || item.id || 'download';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    };
    // 预览文件
    const handlePreview = (item: any) => {
        setPreviewItem(item);
        setPreviewVisible(true);
        // 触发事件通知布局组件关闭浮动按钮
        window.dispatchEvent(new Event('previewOpen'));
    };
    // 关闭预览并暂停视频
    const handleClosePreview = () => {
        // 方法1: 使用 ref
        if (videoRef.current) {
            videoRef.current.pause();
            videoRef.current.currentTime = 0;
        }
        // 方法2: 直接通过 DOM 查询（备用）
        const videoElements = document.querySelectorAll('video');
        videoElements.forEach(video => {
            video.pause();
            video.currentTime = 0;
        });
        setPreviewVisible(false);
    };
    // 获取item的资源ID（优先使用generatedResourceId，否则使用id）
    const getItemResourceId = (item: any): string => {
        return item.generatedResourceId || item.id;
    };
    // 判断item是否有generatedResourceId
    const hasGeneratedResourceId = (item: any): boolean => {
        return Boolean(item.generatedResourceId);
    };
    // 检查视频尺寸是否符合480p要求（270×480或480×270）
    const checkVideoSize = (imagePx: string): boolean => {
        if (!imagePx) return true;
        const match = imagePx.match(/^(\d+)x(\d+)$/);
        if (!match) return true;
        const width = parseInt(match[1], 10);
        const height = parseInt(match[2], 10);
        const aspectRatio = width / height;
        const isLandscape = width >= height;
        if (isLandscape) {
            const isValidWidth = width >= 480 && width <= 2560;
            const isValidHeight = height >= 270 && height <= 1440;
            const isValidRatio = aspectRatio >= 1.775 && aspectRatio <= 1.784;
            return isValidWidth && isValidHeight && isValidRatio;
        } else {
            const isValidWidth = width >= 270 && width <= 1440;
            const isValidHeight = height >= 480 && height <= 2560;
            const isValidRatio = aspectRatio >= 0.555 && aspectRatio <= 0.564;
            return isValidWidth && isValidHeight && isValidRatio;
        }
    };
    // 多选相关函数
    const handleToggleSelect = (itemId: string) => {
        setSelectedItems(prev => {
            const newSet = new Set(prev);
            if (newSet.has(itemId)) {
                newSet.delete(itemId);
            } else {
                newSet.add(itemId);
            }
            return newSet;
        });
    };
    const handleSelectAll = () => {
        const allItemIds = recordlist.flatMap((group: any) =>
            group.items.map((item: any) => getItemResourceId(item))
        );
        if (selectedItems.size === allItemIds.length) {
            setSelectedItems(new Set());
        } else {
            setSelectedItems(new Set(allItemIds));
        }
    };
    const handleDownloadSelected = async () => {
        if (selectedItems.size === 0) {
            message.warning('请先选择要下载的媒体');
            return;
        }

        // 检查下载数量限制
        if (selectedItems.size > 30) {
            message.warning('最多只能单次下载30个文件');
            return;
        }

        const selectedContent: any[] = [];
        recordlist.forEach((group: any) => {
            group.items.forEach((item: any) => {
                if (selectedItems.has(getItemResourceId(item))) {
                    selectedContent.push(item);
                }
            });
        });

        const zip = new JSZip();
        const baseUrl = import.meta.env.VITE_API_BASE || "http://localhost:8000";
        const folder = zip.folder('downloads');
        let hasError = false;
        let successCount = 0;

        message.loading({ content: '下载中，请稍候...', key: 'downloadProgress' });

        for (const item of selectedContent) {
            const url = `${baseUrl}${item.videoUrl || item.imageUrl}`;
            const filename = ((item.videoUrl || item.imageUrl).split('/').pop() || `file_${Date.now()}`).split('?')[0];
            try {
                const response = await fetch(url);
                if (!response.ok) throw new Error('Network response was not ok');
                const blob = await response.blob();
                folder?.file(filename, blob);
                successCount++;
            } catch (error) {
                console.warn(`文件下载失败（CORS限制）: ${filename}，将使用备用方式下载`);
                hasError = true;
                break;
            }
        }

        if (hasError) {
            // Fallback: 逐个打开文件下载（不受 CORS 限制）
            message.destroy('downloadProgress');
            message.info('由于跨域限制，将逐个下载文件');
            selectedContent.forEach((item, index) => {
                setTimeout(() => {
                    const url = `${baseUrl}${item.videoUrl || item.imageUrl}&download=1`;
                    const link = document.createElement('a');
                    link.href = url;
                    link.download = '';
                    document.body.appendChild(link);
                    link.click();
                    document.body.removeChild(link);
                }, index * 500);
            });
            return;
        }

        const zipBlob = await zip.generateAsync({ type: 'blob' });
        const link = document.createElement('a');
        link.href = URL.createObjectURL(zipBlob);
        link.download = `downloads_${Date.now()}.zip`;
        link.click();
        URL.revokeObjectURL(link.href);

        message.destroy('downloadProgress');
        message.success(`下载完成，共 ${successCount} 个文件`);
        setIsSelectionMode(false);
        setSelectedItems(new Set());
    };
    const handleDeleteSelected = async () => {
        if (selectedItems.size === 0) {
            message.warning('请先选择要删除的媒体');
            return;
        }
         // 检查下载数量限制
        if (selectedItems.size > 30) {
            message.warning('最多只能单次删除30个文件');
            return;
        }


        const selectedData = recordlist.flatMap((group: any) => 
            group.items.filter((item: any) => selectedItems.has(getItemResourceId(item)))
        );

        let confirmContent: React.ReactNode = '';
        if (filterType === 'shot_replicate') {
            confirmContent = (
                <div>
                    <div style={{ marginBottom: 8 }}>以下内容所连带的图片和视频都将被删除：</div>
                    <ul style={{ margin: 0, paddingLeft: 20 }}>
                        {selectedData.map((item: any, index: number) => (
                            <li key={index} style={{ marginBottom: 4, color: '#334155' }}>
                                {item.shotReplicateProjectTitle}—  —{item.shotSegmentLabel}
                            </li>
                        ))}
                    </ul>
                    <div style={{ marginTop: 12 }}>确定删除吗？</div>
                </div>
            );
        } else if (filterType === 'hot_opening_replicate') {
            confirmContent = (
                <div>
                    <div style={{ marginBottom: 8 }}>爆款开头复刻中以下内容所连带的图片和视频都将被删除：</div>
                    <ul style={{ margin: 0, paddingLeft: 20 }}>
                        {selectedData.map((item: any, index: number) => (
                            <li key={index} style={{ marginBottom: 4, color: '#334155' }}>
                                {item.moduleProjectTitle}
                            </li>
                        ))}
                    </ul>
                    <div style={{ marginTop: 12 }}>确定删除吗？</div>
                </div>
            );
        } else {
            confirmContent = `确定删除选中的 ${selectedItems.size} 条记录吗？`;
        }

        Modal.confirm({
            title: '确认删除',
            content: confirmContent,
            okText: '确定删除',
            cancelText: '取消',
            okButtonProps: { danger: true },
            onOk: async () => {
                let historySource = '';
                if (filterType === 'project') {
                    historySource = 'generation_record';
                } else if (filterType === 'creation') {
                    historySource = 'chat_task';
                } else if (filterType === 'hot_opening_replicate') {
                    historySource = 'hot_opening_replicate';
                } else if (filterType === 'shot_replicate') {
                    historySource = 'shot_replicate';
                }

                const selectedContent: any[] = [];
                recordlist.forEach((group: any) => {
                    group.items.forEach((item: any) => {
                        if (selectedItems.has(getItemResourceId(item))) {
                            selectedContent.push(item);
                        }
                    });
                });

                let idArr: any[] = [];
                if (historySource === 'generation_record') {
                    idArr = selectedContent.map((item: any) => item.id);
                } else if (historySource === 'chat_task') {
                    idArr = selectedContent.map((item: any) => item.id);
                } else if (historySource === 'hot_opening_replicate') {
                    idArr = selectedContent.map((item: any) => item.moduleProjectId);
                } else if (historySource === 'shot_replicate') {
                    idArr = selectedContent.map((item: any) => item.shotSegmentId);
                }
                
                

                const params = {
                    history_source: historySource,
                    ids: idArr,
                };

                try {
                    await deleteResourcesMaterial(params);
                    message.success('删除成功');
                    setIsSelectionMode(false);
                    setSelectedItems(new Set());
                    setPagebreak(prev => ({ ...prev, page: 1 }));
                    loadRecordList();
                } catch (error) {
                    message.error('删除失败，请重试');
                }
            },
        });
    };
    const loadPreTestTemplates = async () => {
        setPreTestTemplatesLoading(true);
        try {
            const res = await getPreTestList({ page: 1, pageSize: 100 });
            setPreTestTemplates(res.data?.data || res.data || []);
        } catch (error) {
            console.error('加载前测模板失败:', error);
        } finally {
            setPreTestTemplatesLoading(false);
        }
    };

    const handleBatchUploadSelected = () => {
        if (selectedItems.size === 0) {
            message.warning('请先选择要推送的媒体');
            return;
        }
        setAccountIdLists([[]]);
        setAccountIdInputs(['']);
        setSelectedOauthItems([undefined]);
        setIsPreTest('2');
        setPreTestTemplate('');
        loadPreTestTemplates();
        setUploadConfigModalVisible(true);
    };
    const handleSinglePushToMedia = () => {
        if (!previewItem) return;
        const resourceId = getItemResourceId(previewItem);
        setSelectedItems(new Set([resourceId]));
        setAccountIdLists([[]]);
        setAccountIdInputs(['']);
        setSelectedOauthItems([undefined]);
        setMaterialFileNames(new Map());
        setUnifiedFileName('');
        setIsPreTest('2');
        setPreTestTemplate('');
        loadPreTestTemplates();
        setUploadConfigModalVisible(true);
    };
    const loadOAuthList = async (page: number, pageSize: number) => {
        setOauthLoading(true);
        try {
            const res = await getOAuthList({ page, page_size: pageSize });
            const data = res?.data || res;
            setOauthList(data || []);
            setOauthTotal(res.pagination.total || 0);
        } catch (error) {
            console.error('加载授权列表失败:', error);
            setOauthList([]);
            setOauthTotal(0);
        } finally {
            setOauthLoading(false);
        }
    };
    const loadHistoryOAuthList = async () => {
        setHistoryOAuthLoading(true);
        try {
            const [oauthRes, openTypeRes] = await Promise.all([
                getAllOAuthAccountList(),
                getOpenTypeAll(),
            ]);
            const oauthData = oauthRes?.data || [];
            setHistoryOAuthList(oauthData);

            const openTypeData = openTypeRes?.data || [];
            const map: Record<number, string> = {};
            openTypeData.forEach((item: any) => {
                map[item.openType] = item.typeName;
            });
            setOpenTypeMap(map);
        } catch (error) {
            console.error('加载历史授权账户列表失败:', error);
            setHistoryOAuthList([]);
            setOpenTypeMap({});
        } finally {
            setHistoryOAuthLoading(false);
        }
    };
    const loadUploadHistory = async () => {
        setUploadHistoryLoading(true);
        try {
            const res = await getUploadHistory({
                status: uploadHistoryStatus || undefined,
                page: uploadHistoryPage,
                pageSize: uploadHistoryPageSize,
            });
            const data = res?.data || res;
            setUploadHistoryList(data || []);
            setUploadHistoryTotal(res.pagination?.total || res.total || 0);
        } catch (error) {
            console.error('加载推送历史失败:', error);
            setUploadHistoryList([]);
            setUploadHistoryTotal(0);
        } finally {
            setUploadHistoryLoading(false);
        }
    };
    const handleOpenUploadHistory = () => {
        setUploadHistoryModalVisible(true);
        setUploadHistoryPage(1);
        setUploadHistoryStatus('');
        loadUploadHistory();
    };
    const handleUploadHistorySearch = () => {
        setUploadHistoryPage(1);
        loadUploadHistory();
    };
    const handleUploadHistoryPageChange = (page: number, pageSize: number) => {
        setUploadHistoryPage(page);
        setUploadHistoryPageSize(pageSize);
        loadUploadHistory();
    };
    // 批量推送素材
    const handleStartBatchUpload = async () => {
        if (selectedItems.size === 0) {
            message.warning('请先选择要推送的媒体');
            return;
        }
        const itemMap = new Map<string, any>();
        recordlist.forEach((group: any) => {
            group.items.forEach((item: any) => {
                const resourceId = getItemResourceId(item);
                itemMap.set(resourceId, item);
            });
        });
        let tasks: {
            advertiser_ids: string[];
            resource_ids: string[];
            is_pre_test: string;
            pre_test_template: string;
            oauth_id: string;
            source_model: string;
        }[] = [];
        if (accountTab === 'new') {
            const validOauthItems = selectedOauthItems.filter(item => item !== undefined);
            if (validOauthItems.length === 0) {
                message.warning('请先选择授权账户');
                return;
            }
            for (let i = 0; i < validOauthItems.length; i++) {
                const oauthItem = validOauthItems[i];
                const advertiserIds = accountIdLists[i]?.map(account => account.accountId) || [];
                if (advertiserIds.length === 0) {
                    message.warning(`第 ${i + 1} 组授权账户未设置账户ID，已跳过`);
                    continue;
                }
                const sourceModelMap = new Map<string, string[]>();
                for (const itemId of selectedItems) {
                    const item = itemMap.get(itemId);
                    let sourceModel: string;
                    if (item && hasGeneratedResourceId(item)) {
                        sourceModel = 'generated_resources';
                    }
                    //  else {
                    //     sourceModel = filterType === 'project' ? 'generation_records' : 'chat_generation_tasks';
                    // }
                    if (!sourceModelMap.has(sourceModel)) {
                        sourceModelMap.set(sourceModel, []);
                    }
                    sourceModelMap.get(sourceModel)!.push(itemId);
                }
                sourceModelMap.forEach((resourceIds, sourceModel) => {
                    tasks.push({
                        advertiser_ids: advertiserIds,
                        resource_ids: resourceIds,
                        oauth_id: oauthItem.value,
                        source_model: sourceModel,
                        is_pre_test: isPreTest,
                        pre_test_template: preTestTemplate,
                    });
                });
            }
        } else {
            if (selectedHistoryAccounts.length === 0) {
                message.warning('请先选择历史账户');
                return;
            }
            for (const account of selectedHistoryAccounts) {
                const sourceModelMap = new Map<string, string[]>();
                for (const itemId of selectedItems) {
                    const item = itemMap.get(itemId);
                    let sourceModel: string;
                    if (item && hasGeneratedResourceId(item)) {
                        sourceModel = 'generated_resources';
                    } else {
                        sourceModel = filterType === 'project' ? 'generation_records' : 'chat_generation_tasks';
                    }
                    if (!sourceModelMap.has(sourceModel)) {
                        sourceModelMap.set(sourceModel, []);
                    }
                    sourceModelMap.get(sourceModel)!.push(itemId);
                }
                sourceModelMap.forEach((resourceIds, sourceModel) => {
                    tasks.push({
                        advertiser_ids: [account.advertiserId],
                        resource_ids: resourceIds,
                        oauth_id: String(account.oauthId),
                        source_model: sourceModel,
                        is_pre_test: isPreTest,
                        pre_test_template: preTestTemplate,
                    });
                });
            }
        }

        setUploading(true);
        try {
            const res = await asyncBatchUploadMaterial({ tasks });
            if (res.errors?.length > 0) {
                message.warning(res.message);
            } else if (res.code === 0) {
                message.success(res.message);
            } else {
                message.error(res.message);
            }
            setIsSelectionMode(false);
            setSelectedItems(new Set());
            setUploadConfigModalVisible(false);
            setAccountIdLists([[]]);
            setAccountIdInputs(['']);
            setSelectedOauthItems([undefined]);
            setSelectedHistoryAccounts([]);
            setMaterialFileNames(new Map());
            setUnifiedFileName('');
            setIsPreTest('2');
            setPreTestTemplate('');
        } catch (error: any) {
            console.error('批量推送失败:', error);
            message.error(error.message || '批量推送失败');
        } finally {
            setUploading(false);
        }
    };
    // 更新文件名函数
    const handleUpdateFileName = async (sourceId: string, newFileName: string) => {
        if (!newFileName.trim()) return;
        try {
            const response = await updateFilename({
                filenames: [{ source_id: sourceId, file_name: newFileName }],
            });
            // 更新 recordlist 中的文件名，使用 API 返回的 new_file_name
            const result = response?.results?.find((r: any) => r.source_id === sourceId);
            const actualFileName = result?.new_file_name || newFileName;
            setRecordList(prevList => {
                return prevList.map(group => ({
                    ...group,
                    items: group.items.map((item: any) => {
                        const resourceId = getItemResourceId(item);
                        if (resourceId === sourceId) {
                            return { ...item, fileName: actualFileName };
                        }
                        return item;
                    }),
                }));
            });
            message.success('文件名更新成功');
        } catch (error: any) {
            console.error('文件名更新失败:', error);
            message.error(error.message || '文件名更新失败');
        }
    };
    // 批量更新文件名函数
    const handleBatchUpdateFileName = async (sourceIds: string[], newFileName: string) => {
        if (!newFileName.trim() || sourceIds.length === 0) return;
        try {
            const filenames = sourceIds.map(sourceId => ({
                source_id: sourceId,
                file_name: newFileName,
            }));
            const response = await updateFilename({ filenames });
            // 批量更新 recordlist 中的文件名，使用 API 返回的 new_file_name
            const resultsMap = new Map<string, string>();
            response?.results?.forEach((r: any) => {
                if (r.success && r.newFileName) {
                    resultsMap.set(r.sourceId, r.newFileName);
                }
            });
            setRecordList(prevList => {
                const sourceIdSet = new Set(sourceIds);
                return prevList.map(group => ({
                    ...group,
                    items: group.items.map((item: any) => {
                        const resourceId = getItemResourceId(item);
                        if (sourceIdSet.has(resourceId)) {
                            const actualFileName = resultsMap.get(resourceId) || newFileName;
                            return { ...item, fileName: actualFileName };
                        }
                        return item;
                    }),
                }));
            });
            console.log(response);
            const successCount = response?.successCount || 0;
            message.success(`已更新 ${successCount} 个文件名`);
        } catch (error: any) {
            console.error('文件名更新失败:', error);
            message.error(error.message || '文件名更新失败');
        }
    };
    const handleDateChange = (dateString: string) => {
        setSelectedDate(dateString);
    };
    const getVideoDimensions = (videoUrl: string): Promise<string> => {
        return new Promise((resolve) => {
            const video = document.createElement('video');
            const baseUrl = import.meta.env.VITE_API_BASE || "http://localhost:8000";
            let cleanPath = videoUrl.startsWith('/') ? videoUrl.slice(1) : videoUrl;
            let cleanBase = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
            video.src = `${cleanBase}/${cleanPath}`;
            video.crossOrigin = 'anonymous';
            video.onloadedmetadata = () => {
                const width = video.videoWidth;
                const height = video.videoHeight;
                video.remove();
                resolve(`${width}x${height}`);
            };
            video.onerror = () => {
                video.remove();
                resolve('');
            };
            video.onabort = () => {
                video.remove();
                resolve('');
            };
            setTimeout(() => {
                video.remove();
                resolve('');
            }, 5000);
        });
    };
    const loadRecordList = () => {
        if (filterType === 'private_portrait' || filterType === 'upload_resource') {
            setLoading(false);
            setRecordList([]);
            return;
        }
        setLoading(true);
        let historySource = '';
        if (filterType === 'project') {
            historySource = 'generation_record';
        } else if (filterType === 'hot_opening_replicate') {
            historySource = 'hot_opening_replicate';
        } else if (filterType === 'shot_replicate') {
            historySource = 'shot_replicate';
        }
        let parameters = `?gen_type=${filterMedia}&page=${Pagebreak.page}&page_size=${Pagebreak.pageSize}`;
        if (historySource) {
            parameters = `?gen_type=${filterMedia}&history_source=${historySource}&page=${Pagebreak.page}&page_size=${Pagebreak.pageSize}`;
        }
        if (selectedDate) {
            let parameters = `${selectedDate}?gen_type=${filterMedia}&page=${Pagebreak.page}&page_size=${Pagebreak.pageSize}`;
            if (historySource) {
                parameters = `${selectedDate}?gen_type=${filterMedia}&history_source=${historySource}&page=${Pagebreak.page}&page_size=${Pagebreak.pageSize}`;
            }
            gethistoryItems(parameters).then((res: any) => {
                const data = Array.isArray(res) ? res : (res?.items || []);
                let recordList = [{
                    generatedDate: res.generatedDate,
                    items: data,
                    total: res.total,
                    page: res.page,
                }];
                if (recordList && recordList[0].items.length > 0) {
                    setRecordList(recordList);
                } else {
                    setRecordList([]);
                }
                if (isPageLoaded) {
                    data.forEach(async (item: any) => {
                        if (item.videoUrl && item.videoUrl.trim()) {
                            const dimensions = await getVideoDimensions(item.videoUrl);
                            if (dimensions) {
                                setRecordList(prev => prev.map(group => ({
                                    ...group,
                                    items: group.items.map((i: any) =>
                                        i.id === item.id ? { ...i, imagePx: dimensions } : i
                                    ),
                                })));
                            }
                        }
                    });
                }
            }).catch((err) => {
            }).finally(() => {
                setLoading(false);
            });
            try {
            } catch (err) {
            } finally {
            }
        } else {
            gethistory(parameters).then((res: any) => {
                const data = Array.isArray(res) ? res : (res?.groups || []);
                data.forEach(group => {
                    group.page = 1;
                });
                if (Pagebreak.page === 1) {
                    setRecordList(data);
                } else {
                    setRecordList(prev => [...prev, ...data]);
                }
                setTotalnumber(res?.totalDays || 0);
                if (isPageLoaded) {
                    data.forEach(group => {
                        group.items.forEach(async (item: any) => {
                            if (item.videoUrl && item.videoUrl.trim()) {
                                const dimensions = await getVideoDimensions(item.videoUrl);
                                if (dimensions) {
                                    setRecordList(prev => prev.map(g => ({
                                        ...g,
                                        items: g.items.map((i: any) =>
                                            i.id === item.id ? { ...i, imagePx: dimensions } : i
                                        ),
                                    })));
                                }
                            }
                        });
                    });
                }
            }).catch((err) => {
                if (Pagebreak.page === 1) {
                    setRecordList([]);
                }
            }).finally(() => {
                setLoading(false);
            });
        }
    };
    useEffect(() => {
        loadRecordList();
    }, [filterType, filterMedia, Pagebreak.page, selectedDate]);
    // 加载更多
    const handleLoadMore = () => {
        if (loading) return;
        setPagebreak(prev => ({
            ...prev,
            page: prev.page + 1
        }));
    };
    // 分组加载更多
    const handleGroupLoadMore = async (time: string, date: string, page: number) => {
        if (loadingGroups.has(date)) return;
        setLoadingGroups(prev => new Set([...prev, date]));
        const addpage = page + 1;
        let historySource = '';
        if (filterType === 'project') {
            historySource = 'generation_record';
        } else if (filterType === 'hot_opening_replicate') {
            historySource = 'hot_opening_replicate';
        } else if (filterType === 'shot_replicate') {
            historySource = 'shot_replicate';
        }
        let parameters = `${time}?gen_type=${filterMedia}&page=${addpage}&page_size=${Pagebreak.pageSize}`;
        if (historySource) {
            parameters = `${time}?gen_type=${filterMedia}&history_source=${historySource}&page=${addpage}&page_size=${Pagebreak.pageSize}`;
        }
        try {
            const res: any = await gethistoryItems(parameters);
            const newItems: any[] = res.items || [];
            if (newItems && newItems.length > 0) {
                setRecordList(prev => prev.map(group => {
                    if (group.generatedDate === time) {
                        return {
                            ...group,
                            items: [...group.items, ...newItems],
                            page: addpage
                        };
                    }
                    return group;
                }));
            }
        } catch (err) {
        } finally {
            setLoadingGroups(prev => {
                const next = new Set(prev);
                next.delete(date);
                return next;
            });
        }
    };
    // 当筛选条件改变时，重置页码
    useEffect(() => {
        setPagebreak(prev => ({
            ...prev,
            page: 1
        }));
    }, [filterType, filterMedia]);
    return (
        <div style={{ minHeight: 'calc(100vh - 90px)', background: '#ffffffff', overflowY: 'auto' }} >
            {/* 操作栏：筛选 + 推送按钮 */}
            <div style={{
                display: 'flex',
                flexWrap: 'wrap',
                alignItems: 'center',
                gap: 12,
                marginBottom: 16,
                padding: '12px 16px',
                borderRadius: 12,
                background: '#fff',
                border: '1px solid #f0f0f5',
                justifyContent: 'space-between',
            }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 4, flexWrap: 'wrap' }}>
                    <FilterOutlined style={{ color: '#090a0cff', fontSize: 14 }} />
                    <Space size={8} wrap={true}>
                        <Button
                            type={filterType === 'project' ? 'primary' : 'default'}
                            onClick={() => {
                                setFilterType('project');
                                setIsSelectionMode(false);
                                setSelectedItems(new Set());
                            }}
                            style={{
                                borderRadius: 8,
                                background: filterType === 'project'
                                    ? 'linear-gradient(135deg, #6366f1, #8b5cf6)'
                                    : '#f8f9fc',
                                border: filterType === 'project' ? 'none' : '1px solid #e2e8f0',
                                color: filterType === 'project' ? '#fff' : '#64748b',
                                fontWeight: 600,
                            }}
                            icon={<FolderOpenOutlined />}
                        >
                            项目记录
                        </Button>
                        <Button
                            type={filterType === 'creation' ? 'primary' : 'default'}
                            onClick={() => {
                                setFilterType('creation');
                                setIsSelectionMode(false);
                                setSelectedItems(new Set());
                            }}
                            style={{
                                borderRadius: 8,
                                background: filterType === 'creation'
                                    ? 'linear-gradient(135deg, #6366f1, #8b5cf6)'
                                    : '#f8f9fc',
                                border: filterType === 'creation' ? 'none' : '1px solid #e2e8f0',
                                color: filterType === 'creation' ? '#fff' : '#64748b',
                                fontWeight: 600,
                            }}
                            icon={<FileTextOutlined />}
                        >
                            创作记录
                        </Button>
                        <Button
                            type={filterType === 'hot_opening_replicate' ? 'primary' : 'default'}
                            onClick={() => {
                                setFilterType('hot_opening_replicate');
                                setIsSelectionMode(false);
                                setSelectedItems(new Set());
                            }}
                            style={{
                                borderRadius: 8,
                                background: filterType === 'hot_opening_replicate'
                                    ? 'linear-gradient(135deg, #6366f1, #8b5cf6)'
                                    : '#f8f9fc',
                                border: filterType === 'hot_opening_replicate' ? 'none' : '1px solid #e2e8f0',
                                color: filterType === 'hot_opening_replicate' ? '#fff' : '#64748b',
                                fontWeight: 600,
                            }}
                            icon={<StarOutlined />}
                        >
                            爆款复刻
                        </Button>
                        <Button
                            type={filterType === 'shot_replicate' ? 'primary' : 'default'}
                            onClick={() => {
                                setFilterType('shot_replicate');
                                setIsSelectionMode(false);
                                setSelectedItems(new Set());
                            }}
                            style={{
                                borderRadius: 8,
                                background: filterType === 'shot_replicate'
                                    ? 'linear-gradient(135deg, #6366f1, #8b5cf6)'
                                    : '#f8f9fc',
                                border: filterType === 'shot_replicate' ? 'none' : '1px solid #e2e8f0',
                                color: filterType === 'shot_replicate' ? '#fff' : '#64748b',
                                fontWeight: 600,
                            }}
                            icon={<PlayCircleOutlined />}
                        >
                            拆镜复刻
                        </Button>
                        <Button
                            type={filterType === 'private_portrait' ? 'primary' : 'default'}
                            onClick={() => {
                                setFilterType('private_portrait');
                                setIsSelectionMode(false);
                                setSelectedItems(new Set());
                            }}
                            style={{
                                borderRadius: 8,
                                background: filterType === 'private_portrait'
                                    ? 'linear-gradient(135deg, #6366f1, #8b5cf6)'
                                    : '#f8f9fc',
                                border: filterType === 'private_portrait' ? 'none' : '1px solid #e2e8f0',
                                color: filterType === 'private_portrait' ? '#fff' : '#64748b',
                                fontWeight: 600,
                            }}
                            icon={<UserOutlined />}
                        >
                            私域素材库
                        </Button>
                        <Button
                            type={filterType === 'upload_resource' ? 'primary' : 'default'}
                            onClick={() => {
                                setFilterType('upload_resource');
                                setIsSelectionMode(false);
                                setSelectedItems(new Set());
                            }}
                            style={{
                                borderRadius: 8,
                                background: filterType === 'upload_resource'
                                    ? 'linear-gradient(135deg, #6366f1, #8b5cf6)'
                                    : '#f8f9fc',
                                border: filterType === 'upload_resource' ? 'none' : '1px solid #e2e8f0',
                                color: filterType === 'upload_resource' ? '#fff' : '#64748b',
                                fontWeight: 600,
                            }}
                            icon={<UploadOutlined />}
                        >
                            历史素材
                        </Button>
                    </Space>
                </div>
                {filterType !== 'private_portrait' && filterType !== 'upload_resource' && (
                <div style={{ display: 'flex', alignItems: 'center', gap: 4, flexWrap: 'wrap' }}>
                    {/* 多选模式按钮 */}
                    {isSelectionMode ? (
                        <Space size={8} wrap={true}>
                            <Button
                                onClick={handleSelectAll}
                                style={{
                                    borderRadius: 8,
                                    background: '#f8f9fc',
                                    border: '1px solid #e2e8f0',
                                    color: '#222222ff',
                                    fontWeight: 600,
                                }}
                            >
                                {selectedItems.size === recordlist.reduce((sum: number, group: any) => sum + group.items.length, 0) ? '取消全选' : '全选'}
                            </Button>
                            <Button
                                onClick={() => {
                                    setIsSelectionMode(false);
                                    setSelectedItems(new Set());
                                }}
                                style={{
                                    borderRadius: 8,
                                    background: '#f8f9fc',
                                    border: '1px solid #e2e8f0',
                                    color: '#64748b',
                                    fontWeight: 600,
                                }}
                            >
                                取消选择
                            </Button>
                            <Button
                                onClick={() => handleDeleteSelected()}
                                style={{ borderRadius: 8, background: 'linear-gradient(135deg, #bf0b0a 0%, #ff8165 100%)',  fontWeight: 600, padding: '8px 24px', color: '#fff' }}
                            >
                                删除 ({selectedItems.size})
                            </Button>
                            <Button
                                onClick={() => handleDownloadSelected()}
                                style={{
                                    borderRadius: 8,
                                    background: 'linear-gradient(135deg, #6366f1, #8b5cf6)',
                                    color: '#fff',
                                    fontWeight: 600,
                                }}
                            >
                                下载 ({selectedItems.size})
                            </Button>
                            <Button
                                type="primary"
                                onClick={handleBatchUploadSelected}
                                loading={uploading}
                                disabled={uploading || selectedItems.size === 0}
                                style={{
                                    borderRadius: 8,
                                    background: 'linear-gradient(135deg, #6366f1, #8b5cf6)',
                                    color: '#fff',
                                    fontWeight: 600,
                                }}
                            >
                                {uploading ? '推送中...' : `推送至账户 (${selectedItems.size})`}
                            </Button>
                        </Space>
                    ) : (
                        <Button
                            type="primary"
                            icon={<UploadOutlined />}
                            onClick={() => setIsSelectionMode(true)}
                            style={{
                                borderRadius: 8,
                                background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)',
                                border: 'none',
                                fontWeight: 600,
                            }}
                        >
                            批量操作
                        </Button>

                    )}
                </div>
                )}
            </div>
            {filterType === 'private_portrait' ? (
                <PrivatePortraitLibraryPanel />
            ) : filterType === 'upload_resource' ? (
                <UploadResourceHistoryPanel />
            ) : (
            <>
            {/* Second row filter: 视频 / 图片 */}
            <div style={{
                display: 'flex',
                flexWrap: 'wrap',
                justifyContent: 'space-between',
                alignItems: 'center',
                gap: 12,
                marginBottom: 24,
                padding: '12px 16px',
                borderRadius: 12,
                background: '#fff',
                border: '1px solid #f0f0f5',
            }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                    <Typography.Text style={{ color: '#94a3b8', fontSize: 14 }}>媒体类型：</Typography.Text>
                    <Space size={8} wrap={true}>
                        <Button
                            type={filterMedia === 'video' ? 'primary' : 'default'}
                            onClick={() => {
                                setFilterMedia('video');
                                setIsSelectionMode(false);
                                setSelectedItems(new Set());
                            }}
                            style={{
                                borderRadius: 8,
                                background: filterMedia === 'video'
                                    ? 'linear-gradient(135deg, #6366f1, #8b5cf6)'
                                    : '#f8f9fc',
                                border: filterMedia === 'video' ? 'none' : '1px solid #e2e8f0',
                                color: filterMedia === 'video' ? '#fff' : '#64748b',
                                fontWeight: 600,
                            }}
                            icon={<VideoCameraOutlined />}
                        >
                            视频
                        </Button>
                        <Button
                            type={filterMedia === 'image' ? 'primary' : 'default'}
                            onClick={() => {
                                setFilterMedia('image');
                                setIsSelectionMode(false);
                                setSelectedItems(new Set());
                            }}
                            style={{
                                borderRadius: 8,
                                background: filterMedia === 'image'
                                    ? 'linear-gradient(135deg, #6366f1, #8b5cf6)'
                                    : '#f8f9fc',
                                border: filterMedia === 'image' ? 'none' : '1px solid #e2e8f0',
                                color: filterMedia === 'image' ? '#fff' : '#64748b',
                                fontWeight: 600,
                            }}
                            icon={<PictureOutlined />}
                        >
                            图片
                        </Button>
                        <DatePicker
                            picker="date"
                            value={selectedDate ? dayjs(selectedDate) : undefined}
                            onChange={(date, dateString) => handleDateChange(dateString || '')}
                            format="YYYY-MM-DD"
                            style={{ width: 160, borderRadius: 8, border: '1px solid #e2e8f0' }}
                            placeholder="选择日期"
                        />
                        {selectedDate && (
                            <Button
                                type="text"
                                onClick={() => handleDateChange('')}
                                style={{ color: '#94a3b8', fontSize: 12 }}
                            >
                                清除
                            </Button>
                        )}
                    </Space>
                </div>
                <Button
                    icon={<ClockCircleOutlined />}
                    onClick={handleOpenUploadHistory}
                    style={{
                        borderRadius: 8,
                        background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)',
                        border: 'none',
                        color: '#ffffff',
                        fontWeight: 600,
                        boxShadow: '0 4px 15px rgba(102, 126, 234, 0.4)',
                        transition: 'all 0.3s ease',
                    }}
                    onMouseEnter={(e) => {
                        e.currentTarget.style.transform = 'translateY(-2px)';
                        e.currentTarget.style.boxShadow = '0 6px 20px rgba(102, 126, 234, 0.6)';
                    }}
                    onMouseLeave={(e) => {
                        e.currentTarget.style.transform = 'translateY(0)';
                        e.currentTarget.style.boxShadow = '0 4px 15px rgba(102, 126, 234, 0.4)';
                    }}
                >
                    查询推送任务历史
                </Button>
            </div>
            {/* Content area */}
            {loading ? (
                <div style={{
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    minHeight: '400px',
                }}>
                    <Spin
                        indicator={<LoadingOutlined style={{ fontSize: 24, color: '#64748b' }} spin />}
                        tip="加载中..."
                        size="large"
                    />
                </div>
            ) : recordlist.length === 0 ? (
                <Empty
                    image={Empty.PRESENTED_IMAGE_SIMPLE}
                    description="暂无生成记录"
                    style={{ padding: '60px 0' }}
                />
            ) : (
                <div style={{ padding: '0 4px' }}>
                    {recordlist.map((group: any, index: number) => (
                        <div key={index} style={{ marginBottom: 32 }}>
                            {/* Date label */}
                            <div style={{
                                fontSize: 14,
                                fontWeight: 600,
                                color: '#64748b',
                                marginBottom: 12,
                                paddingLeft: 8,
                            }}>
                                {group.generatedDate}
                            </div>
                            {/* Media grid */}
                            <div style={{
                                display: 'flex',
                                flexWrap: 'wrap',
                                gap: 8,
                            }}>
                                {group.items.map((item: any) => {
                                        const displayUrl = filterMedia === 'video' && item.videoCoverUrl 
                                            ? buildUrl(item.videoCoverUrl, true) 
                                            : buildUrl(filterMedia === 'video' ? item.videoUrl : item.imageUrl, true);
                                        const hasCover = filterMedia === 'video' && item.videoCoverUrl;
                                        const showImage = hasCover || filterMedia === 'image';
                                        const isSelectedItem = selectedItems.has(getItemResourceId(item));
                                        
                                        return (
                                            <div
                                                key={getItemResourceId(item)}
                                                className="media-card"
                                                style={{
                                                    width: 160,
                                                    height: 120,
                                                    position: 'relative',
                                                    borderRadius: 4,
                                                    cursor: 'pointer',
                                                    overflow: 'hidden',
                                                    boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
                                                    transition: 'transform 0.2s, box-shadow 0.2s',
                                                }}
                                                onClick={() => isSelectionMode ? handleToggleSelect(getItemResourceId(item)) : handlePreview(item)}
                                                onMouseEnter={(e) => {
                                                    if (!isSelectionMode) {
                                                        (e.currentTarget as HTMLElement).style.transform = 'scale(1.05)';
                                                        (e.currentTarget as HTMLElement).style.boxShadow = '0 4px 16px rgba(0,0,0,0.2)';
                                                    }
                                                }}
                                                onMouseLeave={(e) => {
                                                    if (!isSelectionMode) {
                                                        (e.currentTarget as HTMLElement).style.transform = 'scale(1)';
                                                        (e.currentTarget as HTMLElement).style.boxShadow = '0 2px 8px rgba(0,0,0,0.1)';
                                                    }
                                                }}
                                            >
                                                {showImage ? (
                                                    <div style={{ width: '100%', height: '100%', position: 'relative' }}>
                                                        <img
                                                            src={displayUrl}
                                                            alt="预览"
                                                            style={{
                                                                width: '100%',
                                                                height: '100%',
                                                                objectFit: 'cover',
                                                                opacity: mediaLoadStatus.get(getItemResourceId(item)) === 'loaded' ? 1 : 0,
                                                                transition: 'opacity 0.3s',
                                                            }}
                                                            onLoad={() => {
                                                                setMediaLoadStatus(prev => {
                                                                    const newMap = new Map(prev);
                                                                    newMap.set(getItemResourceId(item), 'loaded');
                                                                    return newMap;
                                                                });
                                                            }}
                                                            onError={() => {
                                                                setMediaLoadStatus(prev => {
                                                                    const newMap = new Map(prev);
                                                                    newMap.set(getItemResourceId(item), 'error');
                                                                    return newMap;
                                                                });
                                                            }}
                                                        />
                                                        {mediaLoadStatus.get(getItemResourceId(item)) !== 'loaded' && (
                                                            <div style={{
                                                                position: 'absolute',
                                                                top: 0,
                                                                left: 0,
                                                                width: '100%',
                                                                height: '100%',
                                                                display: 'flex',
                                                                alignItems: 'center',
                                                                justifyContent: 'center',
                                                                background: 'linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%)',
                                                            }}>
                                                                <div style={{
                                                                    width: 32,
                                                                    height: 32,
                                                                    borderRadius: 8,
                                                                    backgroundColor: '#cbd5e1',
                                                                    display: 'flex',
                                                                    alignItems: 'center',
                                                                    justifyContent: 'center',
                                                                    animation: mediaLoadStatus.get(getItemResourceId(item)) === 'loading' ? 'pulse 1.5s infinite' : 'none',
                                                                }}>
                                                                    {item.mediaType === 'video' ? (
                                                                        <VideoCameraOutlined style={{ color: '#64748b', fontSize: 16 }} />
                                                                    ) : (
                                                                        <PictureOutlined style={{ color: '#64748b', fontSize: 16 }} />
                                                                    )}
                                                                </div>
                                                            </div>
                                                        )}
                                                    </div>
                                                ) : (
                                                    <div style={{
                                                        width: '100%',
                                                        height: '100%',
                                                        display: 'flex',
                                                        flexDirection: 'column',
                                                        alignItems: 'center',
                                                        justifyContent: 'center',
                                                        backgroundColor: '#1e293b',
                                                    }}>
                                                        <VideoCameraOutlined style={{ color: '#64748b', fontSize: 24 }} />
                                                        <Text style={{ fontSize: 12, color: '#94a3b8', marginTop: 4 }}>暂无封面</Text>
                                                    </div>
                                                )}
                                                
                                                {isSelectionMode && (
                                                    <>
                                                        <div
                                                            style={{
                                                                position: 'absolute',
                                                                top: 8,
                                                                left: 8,
                                                                width: 20,
                                                                height: 20,
                                                                borderRadius: '50%',
                                                                backgroundColor: isSelectedItem ? '#10b981' : 'rgba(255,255,255,0.9)',
                                                                border: isSelectedItem ? '2px solid #10b981' : '2px solid #d1d5db',
                                                                display: 'flex',
                                                                alignItems: 'center',
                                                                justifyContent: 'center',
                                                                cursor: 'pointer',
                                                                zIndex: 10,
                                                            }}
                                                            onClick={(e) => {
                                                                e.stopPropagation();
                                                                handleToggleSelect(getItemResourceId(item));
                                                            }}
                                                        >
                                                            {isSelectedItem && (
                                                                <svg width={12} height={12} viewBox="0 0 12 12" fill="none">
                                                                    <path d="M10 3L4.5 8.5L2 6" stroke="white" strokeWidth={2} strokeLinecap="round" strokeLinejoin="round" />
                                                                </svg>
                                                            )}
                                                        </div>
                                                        {isSelectedItem && filterMedia === 'video' && item.imagePx && !checkVideoSize(item.imagePx) && (
                                                            <div style={{
                                                                position: 'absolute',
                                                                top: 36,
                                                                left: 8,
                                                                right: 8,
                                                                padding: '4px 8px',
                                                                backgroundColor: 'rgba(239, 68, 68, 0.9)',
                                                                color: '#fff',
                                                                fontSize: 12,
                                                                borderRadius: 4,
                                                                zIndex: 10,
                                                            }}>
                                                                视频实际尺寸可能不符合平台推送要求
                                                            </div>
                                                        )}
                                                    </>
                                                )}
                                                
                                                {!isSelectionMode && (
                                                    <>
                                                        <div style={{
                                                            position: 'absolute',
                                                            bottom: 0,
                                                            left: 0,
                                                            right: 0,
                                                            background: 'linear-gradient(transparent, rgba(0,0,0,0.5))',
                                                            padding: '8px',
                                                            color: '#fff',
                                                            fontSize: 12,
                                                            opacity: 0,
                                                            transition: 'opacity 0.2s',
                                                        }}
                                                            onMouseEnter={(e) => {
                                                                (e.currentTarget as HTMLElement).style.opacity = '1';
                                                            }}
                                                            onMouseLeave={(e) => {
                                                                (e.currentTarget as HTMLElement).style.opacity = '0';
                                                            }}
                                                        >
                                                            点击预览
                                                        </div>
                                                        <div
                                                            className="media-download-btn"
                                                        >
                                                            <Tooltip title="下载">
                                                                <div
                                                                    style={{
                                                                        width: 28,
                                                                        height: 28,
                                                                        borderRadius: '50%',
                                                                        background: 'rgba(0,0,0,0.5)',
                                                                        backdropFilter: 'blur(4px)',
                                                                        display: 'flex',
                                                                        alignItems: 'center',
                                                                        justifyContent: 'center',
                                                                        cursor: 'pointer',
                                                                        transition: 'background 0.15s',
                                                                    }}
                                                                    onClick={(e) => {
                                                                        e.stopPropagation();
                                                                        const url = `${import.meta.env.VITE_API_BASE || "http://localhost:8000"}${item.videoUrl || item.imageUrl}&download=1`;
                                                                        const link = document.createElement('a');
                                                                        link.href = url;
                                                                        link.download = '';
                                                                        document.body.appendChild(link);
                                                                        link.click();
                                                                        document.body.removeChild(link);
                                                                    }}
                                                                >
                                                                    <DownloadOutlined style={{ color: '#fff', fontSize: 14 }} />
                                                                </div>
                                                            </Tooltip>
                                                        </div>
                                                    </>
                                                )}
                                                
                                                
                                                {isSelectionMode && isSelectedItem && (
                                                    <div style={{
                                                        position: 'absolute',
                                                        top: 0,
                                                        left: 0,
                                                        right: 0,
                                                        bottom: 0,
                                                        border: '3px solid #10b981',
                                                        borderRadius: 4,
                                                        pointerEvents: 'none',
                                                        zIndex: 5,
                                                    }} />
                                                )}
                                            </div>
                                        );
                                    })}
                            </div>
                            {/* 分组内加载更多 */}
                            {group.total && group.total > group.items.length && (
                                <div style={{ padding: '12px 0', textAlign: 'left' }}>
                                    <Button
                                        onClick={() => handleGroupLoadMore(group.generatedDate, group.items, group.page)}
                                        loading={loadingGroups.has(group.generatedDate)}
                                        disabled={loadingGroups.has(group.generatedDate)}
                                        size="small"
                                        style={{
                                            borderRadius: 6,
                                            background: 'transparent',
                                            border: '1px dashed #cbd5e1',
                                            color: '#64748b',
                                            fontSize: 12,
                                        }}
                                    >
                                        {loadingGroups.has(group.date) ? '加载中...' : `查看全部 (${group.total})`}
                                    </Button>
                                </div>
                            )}
                        </div>
                    ))}
                    {/* 加载更多按钮 */}
                    {recordlist.length > 0 && Totalnumber > recordlist.length && (
                        <div style={{ textAlign: 'center', padding: '20px 0' }}>
                            <Button
                                onClick={handleLoadMore}
                                loading={loading}
                                disabled={loading}
                                style={{
                                    borderRadius: 8,
                                    background: '#f8f9fc',
                                    border: '1px solid #e2e8f0',
                                    color: '#64748b',
                                    fontWeight: 500,
                                }}
                            >
                                {loading ? '加载中...' : '加载更多'}
                            </Button>
                        </div>
                    )}
                </div>
            )}
            </>
            )}
            {/* 推送任务历史弹窗 */}
            <Modal
                title="推送任务历史"
                open={uploadHistoryModalVisible}
                onCancel={() => setUploadHistoryModalVisible(false)}
                footer={null}
                width={800}
                style={{ borderRadius: 8 }}
                mask={{ closable: false }}
            >
                <div style={{ marginBottom: 16, display: 'flex', gap: 4 }}>
                    <Select
                        value={uploadHistoryStatus}
                        onChange={(value) => setUploadHistoryStatus(value)}
                        placeholder="选择状态"
                        style={{ width: 200, marginRight: 12 }}
                        options={[
                            { value: '1', label: '待推送' },
                            { value: '2', label: '推送中' },
                            { value: '3', label: '推送成功' },
                            { value: '4', label: '推送失败' },
                        ]}
                        allowClear
                    />
                    <div style={{ display: 'flex', gap: 4 }}>
                        <Button
                            type="primary"
                            onClick={handleUploadHistorySearch}
                            style={{ borderRadius: 8 }}
                        >
                            查询
                        </Button>
                        <Button
                            icon={<ReloadOutlined />}
                            onClick={handleUploadHistorySearch}
                            style={{ borderRadius: 8 }}
                        >
                            刷新
                        </Button>
                    </div>
                </div>
                <Table
                    dataSource={uploadHistoryList}
                    columns={[
                        {
                            title: '素材名称',
                            dataIndex: 'fileName',
                            key: 'fileName',
                            width: 200,
                        },
                        {
                            title: '账户ID',
                            dataIndex: 'advertiserId',
                            key: 'advertiserId',
                            width: 180,
                        },
                        {
                            title: '状态',
                            dataIndex: 'status',
                            key: 'status',
                            width: 100,
                            render: (status: string) => {
                                const statusMap: Record<string, string> = {
                                    '1': '待推送',
                                    '2': '推送中',
                                    '3': '推送成功',
                                    '4': '推送失败',
                                };
                                const statusColorMap: Record<string, string> = {
                                    '1': '#f59e0b',
                                    '2': '#6366f1',
                                    '3': '#10b981',
                                    '4': '#ef4444',
                                };
                                return (
                                    <Tag color={statusColorMap[status] || '#64748b'} style={{ borderRadius: 4 }}>
                                        {statusMap[status] || status}
                                    </Tag>
                                );
                            },
                        },
                        {
                            title: '备注',
                            dataIndex: 'note',
                            key: 'note',
                            width: 160,
                            ellipsis: true,
                            render: (note: string) => (
                                <span style={{ color: '#94a3b8' }}>
                                    {note || '-'}
                                </span>
                            ),
                        },
                        {
                            title: '创建时间',
                            dataIndex: 'createdAt',
                            key: 'createdAt',
                            width: 180,
                            render: (text: string) => formatDateTime(text),
                        },
                        {
                            title: '更新时间',
                            dataIndex: 'updatedAt',
                            key: 'updatedAt',
                            width: 180,
                            render: (text: string) => formatDateTime(text),
                        },

                    ]}
                    loading={uploadHistoryLoading}
                    scroll={{ x: 'max-content' }}
                    pagination={{
                        current: uploadHistoryPage,
                        pageSize: uploadHistoryPageSize,
                        total: uploadHistoryTotal,
                        showSizeChanger: true,
                        showTotal: (total) => `共 ${total} 条记录`,
                        onChange: handleUploadHistoryPageChange,
                    }}
                    rowKey={(record, index) => record.task_id || record.resource_id || index}
                    size="small"
                />
            </Modal>

            {/* 预览弹窗 */}
            {previewVisible && previewItem && (
                <Modal
                    title={
                        <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                            <div style={{ width: 4, height: 20, background: 'linear-gradient(180deg, #6366f1 0%, #8b5cf6 100%)', borderRadius: 2 }} />
                            <span style={{ fontSize: 16, fontWeight: 700, background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)', WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent', backgroundClip: 'text' }}>
                                {previewItem.title || '预览'}
                            </span>
                        </div>
                    }
                    open={previewVisible}
                    onCancel={handleClosePreview}
                    width={1200}
                    footer={
                        <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 12, padding: '16px 24px', background: '#fff', borderTop: '1px solid #f1f5f9' }}>
                            <Button
                                type="primary"
                                icon={<DownloadOutlined />}
                                onClick={() => {
                                    if (videoRef.current) {
                                        videoRef.current.pause();
                                    }
                                    const url = `${import.meta.env.VITE_API_BASE || "http://localhost:8000"}${previewItem.videoUrl || previewItem.imageUrl}&download=1`;
                                    const link = document.createElement('a');
                                    link.href = url;
                                    link.download = '';
                                    document.body.appendChild(link);
                                    link.click();
                                    document.body.removeChild(link);
                                }}
                                style={{ borderRadius: 8, background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)', border: 'none', boxShadow: '0 4px 16px rgba(99, 102, 241, 0.35)', fontWeight: 600, padding: '8px 24px' }}
                                disabled={isMediaExpired(previewItem.videoUrl || previewItem.imageUrl)}
                            >
                                {isMediaExpired(previewItem.videoUrl || previewItem.imageUrl) ? '资源已过期' : '下载'}
                            </Button>
                            <Button
                                type="primary"
                                icon={<DeleteOutlined />}
                                onClick={() => {
                                    let deleteId = '';
                                    let confirmContent: React.ReactNode = '';

                                    if (filterType === 'shot_replicate') {
                                        deleteId = previewItem.shotSegmentId;
                                        confirmContent = (
                                            <div>
                                                <div style={{ marginBottom: 8 }}>以下内容所连带的图片和视频都将被删除：</div>
                                                <ul style={{ margin: 0, paddingLeft: 20 }}>
                                                    <li style={{ marginBottom: 4, color: '#334155' }}>
                                                        {previewItem.shotReplicateProjectTitle}—  —{previewItem.shotSegmentLabel}
                                                    </li>
                                                </ul>
                                                <div style={{ marginTop: 12 }}>确定删除吗？</div>
                                            </div>
                                        );
                                    } else if (filterType === 'hot_opening_replicate') {
                                        deleteId = previewItem.moduleProjectId;
                                        confirmContent = (
                                            <div>
                                                <div style={{ marginBottom: 8 }}>爆款开头复刻中以下内容所连带的图片和视频都将被删除：</div>
                                                <ul style={{ margin: 0, paddingLeft: 20 }}>
                                                    <li style={{ marginBottom: 4, color: '#334155' }}>
                                                        {previewItem.moduleProjectTitle}
                                                    </li>
                                                </ul>
                                                <div style={{ marginTop: 12 }}>确定删除吗？</div>
                                            </div>
                                        );
                                    } else {
                                        deleteId = previewItem.id;
                                        confirmContent = '确定删除该记录吗？';
                                    }

                                    if (!deleteId) {
                                        message.warning('无法获取删除ID');
                                        return;
                                    }

                                    Modal.confirm({
                                        title: '确认删除',
                                        content: confirmContent,
                                        okText: '确定删除',
                                        cancelText: '取消',
                                        okButtonProps: { danger: true },
                                        onOk: async () => {
                                            let historySource = '';
                                            if (filterType === 'project') {
                                                historySource = 'generation_record';
                                            } else if (filterType === 'creation') {
                                                historySource = 'chat_task';
                                            } else if (filterType === 'hot_opening_replicate') {
                                                historySource = 'hot_opening_replicate';
                                            } else if (filterType === 'shot_replicate') {
                                                historySource = 'shot_replicate';
                                            }

                                            let params = {
                                                history_source: historySource,
                                                ids: [deleteId],
                                            }


                                            try {
                                                await deleteResourcesMaterial(params); // 调用删除接口
                                                message.success('删除成功');
                                                handleClosePreview();
                                                setPagebreak(prev => ({ ...prev, page: 1 }));
                                                loadRecordList();
                                            } catch (error) {
                                                message.error('删除失败，请重试');
                                            }
                                        },
                                    });
                                }}
                                style={{ borderRadius: 8, background: 'linear-gradient(135deg, #bf0b0a 0%, #ff8165 100%)', fontWeight: 600, padding: '8px 24px' }}
                                disabled={isMediaExpired(previewItem.videoUrl || previewItem.imageUrl)}
                            >
                                删除
                            </Button>
                            <Button
                                onClick={handleSinglePushToMedia}
                                style={{ borderRadius: 8, background: '#f8f9fc', border: '1px solid #e2e8f0', color: '#64748b', fontWeight: 600, padding: '8px 24px' }}
                                disabled={isMediaExpired(previewItem.videoUrl || previewItem.imageUrl)}
                            >
                                推送媒体后台
                            </Button>
                        </div>
                    }
                    style={{ borderRadius: 16, overflow: 'hidden' }}
                    styles={{
                        body: { height: 500, display: 'flex', flexDirection: 'column', padding: 0 },
                        header: { background: '#fff', borderBottom: '1px solid #f1f5f9', padding: '16px 24px' },
                        mask: { backgroundColor: 'rgba(0, 0, 0, 0.5)' },
                    }}
                >
                    <div style={{
                        width: '100%',
                        display: 'flex',
                        height: '100%',
                        background: '#f8fafc',
                    }}>
                        <div style={{
                            width: '70%',
                            height: '100%',
                            display: 'flex',
                            justifyContent: 'center',
                            alignItems: 'center',

                            padding: 20,
                        }}>
                            {isMediaExpired(previewItem.videoUrl || previewItem.imageUrl) ? (
                                <div style={{ textAlign: 'center', padding: '40px', backgroundColor: '#fff', borderRadius: 12 }}>
                                    <div style={{ fontSize: 48, marginBottom: 16 }}>⚠️</div>
                                    <p style={{ fontSize: 15, color: '#ef4444', fontWeight: 500, marginBottom: 8 }}>资源已过期</p>
                                    <p style={{ fontSize: 13, color: '#94a3b8' }}>请刷新页面重新加载</p>
                                </div>
                            ) : filterMedia === 'video' ? (
                                <video
                                    ref={videoRef}
                                    src={`${import.meta.env.VITE_API_BASE || "http://localhost:8000"}${previewItem.videoUrl}`}
                                    controls
                                    autoPlay
                                    style={{
                                        maxWidth: '100%',
                                        maxHeight: '100%',
                                        borderRadius: 12,
                                        objectFit: 'contain',
                                    }}
                                />
                            ) : (
                                <img
                                    src={`${import.meta.env.VITE_API_BASE || "http://localhost:8000"}/static${previewItem.imageUrl}&w=300&q=50`}
                                    alt="预览"
                                    style={{
                                        maxWidth: '100%',
                                        maxHeight: '100%',
                                        objectFit: 'contain',
                                        borderRadius: 12,
                                    }}
                                />
                            )}
                        </div>

                        <div style={{
                            width: '30%',
                            height: '100%',
                            overflowY: 'auto',
                            scrollbarWidth: 'none',
                            backgroundColor: '#fff',
                            padding: 24,
                            borderLeft: '1px solid #f1f5f9',
                        }}>
                            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 20 }}>
                                <div style={{ width: 2, height: 18, background: 'linear-gradient(180deg, #6366f1 0%, #8b5cf6 100%)', borderRadius: 1 }} />
                                <Typography.Text strong style={{ fontSize: 15, color: '#1e293b', fontWeight: 600 }}>
                                    文件信息
                                </Typography.Text>
                            </div>

                            <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
                                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                                    <span style={{ color: '#94a3b8', fontSize: 13, fontWeight: 500 }}>类型</span>
                                    <span style={{ color: '#334155', fontSize: 13, fontWeight: 600 }}>
                                        {filterMedia === 'video' ? '视频' : '图片'}
                                    </span>
                                </div>
                                {filterType === 'hot_opening_replicate' && (
                                    <div style={{ display: 'flex', justifyContent: 'space-between', gap: 4 }}>
                                        <span style={{ color: '#94a3b8', fontSize: 13, fontWeight: 500 }}>类属</span>
                                        <span style={{ color: '#334155', fontSize: 13, fontWeight: 500, wordBreak: 'break-all', lineHeight: '1.5' }}>
                                            爆款复刻——{previewItem.moduleProjectTitle}
                                        </span>
                                    </div>
                                )}
                                {filterType === 'shot_replicate' && (
                                    <div style={{ display: 'flex', justifyContent: 'space-between', gap: 4 }}>
                                        <span style={{ color: '#94a3b8', fontSize: 13, fontWeight: 500 }}>类属</span>
                                        <span style={{ color: '#334155', fontSize: 13, fontWeight: 500, wordBreak: 'break-all', lineHeight: '1.5' }}>
                                            {previewItem.shotReplicateProjectTitle}—  —{previewItem.shotSegmentLabel}
                                        </span>
                                    </div>
                                )}

                                <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
                                    <span style={{ color: '#94a3b8', fontSize: 13, fontWeight: 500 }}>请求</span>
                                    <span style={{ color: '#334155', fontSize: 13, fontWeight: 500, wordBreak: 'break-all', lineHeight: '1.5' }}>
                                        {previewItem.originalPrompt}
                                    </span>
                                </div>

                                {filterMedia === 'image' && (
                                    <>
                                        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                                            <span style={{ color: '#94a3b8', fontSize: 13, fontWeight: 500 }}>比例</span>
                                            <span style={{ color: '#334155', fontSize: 13, fontWeight: 600 }}>
                                                {previewItem.imageProportion}
                                            </span>
                                        </div>
                                        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                                            <span style={{ color: '#94a3b8', fontSize: 13, fontWeight: 500 }}>分辨率</span>
                                            <span style={{ color: '#334155', fontSize: 13, fontWeight: 600 }}>
                                                {previewItem.imageSize}
                                            </span>
                                        </div>
                                        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                                            <span style={{ color: '#94a3b8', fontSize: 13, fontWeight: 500 }}>尺寸</span>
                                            <span style={{ color: '#334155', fontSize: 13, fontWeight: 600 }}>
                                                {previewItem.imagePx}
                                            </span>
                                        </div>
                                    </>
                                )}

                                {filterMedia === 'video' && (
                                    <>
                                        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                                            <span style={{ color: '#94a3b8', fontSize: 13, fontWeight: 500 }}>比例</span>
                                            <span style={{ color: '#334155', fontSize: 13, fontWeight: 600 }}>
                                                {previewItem.aspectRatio}
                                            </span>
                                        </div>
                                        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                                            <span style={{ color: '#94a3b8', fontSize: 13, fontWeight: 500 }}>分辨率</span>
                                            <span style={{ color: '#334155', fontSize: 13, fontWeight: 600 }}>
                                                {previewItem.resolution}
                                            </span>
                                        </div>
                                        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                                            <span style={{ color: '#94a3b8', fontSize: 13, fontWeight: 500 }}>时长</span>
                                            <span style={{ color: '#334155', fontSize: 13, fontWeight: 600 }}>
                                                {`${previewItem.duration}秒` || '-'}
                                            </span>
                                        </div>
                                    </>
                                )}

                                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                                    <span style={{ color: '#94a3b8', fontSize: 13, fontWeight: 500 }}>创建时间</span>
                                    <span style={{ color: '#334155', fontSize: 13, fontWeight: 600 }}>
                                        {formatDateTime(previewItem.createdAt || previewItem.generatedDate)}
                                    </span>
                                </div>

                                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                                    <span style={{ color: '#94a3b8', fontSize: 13, fontWeight: 500 }}>生成引擎</span>
                                    <span style={{ color: '#334155', fontSize: 13, fontWeight: 600 }}>
                                        {previewItem.engine || previewItem.engineName || '-'}
                                    </span>
                                </div>
                            </div>

                            <div style={{ borderTop: '1px solid #f1f5f9', margin: '20px 0' }} />

                            {previewItem.mediaReferences && previewItem.mediaReferences.length > 0 && !['hot_opening_replicate', 'shot_replicate'].includes(filterType) && (
                                <>
                                    <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 16 }}>
                                        <div style={{ width: 2, height: 18, background: 'linear-gradient(180deg, #3b82f6 0%, #60a5fa 100%)', borderRadius: 1 }} />
                                        <Typography.Text strong style={{ fontSize: 15, color: '#1e293b', fontWeight: 600 }}>
                                            依靠附件
                                        </Typography.Text>
                                    </div>
                                    {previewItem.mediaReferences.map((item, index) => (
                                        <div
                                            key={item.url}
                                            onClick={() => {
                                                if (videoRef.current) {
                                                    videoRef.current.pause();
                                                }
                                                const url = `${import.meta.env.VITE_API_BASE || "http://localhost:8000"}${item.url}`;
                                                window.open(url, '_blank');
                                            }}
                                            style={{
                                                display: 'flex',
                                                alignItems: 'center',
                                                gap: 10,
                                                padding: '10px 12px',
                                                borderRadius: 8,
                                                cursor: 'pointer',
                                                backgroundColor: '#f8fafc',
                                                marginBottom: 8,
                                                transition: 'all 0.25s ease',
                                                border: '1px solid transparent',
                                            }}
                                            onMouseEnter={(e) => {
                                                const el = e.currentTarget as HTMLElement;
                                                el.style.backgroundColor = '#e0f2fe';
                                                el.style.borderColor = '#bae6fd';
                                            }}
                                            onMouseLeave={(e) => {
                                                const el = e.currentTarget as HTMLElement;
                                                el.style.backgroundColor = '#f8fafc';
                                                el.style.borderColor = 'transparent';
                                            }}
                                        >
                                            {item.type === 'image' ? (
                                                <PictureOutlined style={{ color: '#3b82f6', fontSize: 16 }} />
                                            ) : (
                                                <VideoCameraOutlined style={{ color: '#f59e0b', fontSize: 16 }} />
                                            )}
                                            <span style={{ color: '#334155', fontSize: 13, fontWeight: 500 }}>
                                                {item.name || `媒体${index + 1}`}
                                            </span>
                                        </div>
                                    ))}
                                </>
                            )}
                        </div>
                    </div>
                </Modal>
            )}

            {/* 推送配置弹窗 */}
            <Modal
                title={selectedItems.size === 1 ? '推送配置' : '批量推送配置'}
                open={uploadConfigModalVisible}
                onCancel={() => {
                    setUploadConfigModalVisible(false);
                    setAccountIdLists([[]]);
                    setAccountIdInputs(['']);
                    setSelectedOauthItems([undefined]);
                    setMaterialFileNames(new Map());
                    setUnifiedFileName('');
                }}
                footer={null}
                width={900}
                mask={{ closable: false }}
            >
                <div style={{ padding: '16px 0' }}>
                    <Typography.Text strong style={{ fontSize: 14, color: '#475569', marginBottom: 8, display: 'block' }}>
                        选中素材 ({selectedItems.size}个)
                    </Typography.Text>
                    <div style={{ marginBottom: 16 }}>
                        <div style={{
                            display: 'flex',
                            gap: 8,
                            marginBottom: 12,
                            alignItems: 'center',
                        }}>
                            <Typography.Text style={{ fontSize: 12, color: '#64748b' }}>统一修改名称：</Typography.Text>
                            <Input
                                value={unifiedFileName}
                                onChange={(e) => setUnifiedFileName(e.target.value)}
                                placeholder="输入名称后点击应用"
                                style={{ flex: 1, borderRadius: 8 }}
                                size="small"
                            />
                            <Button
                                type="primary"
                                size="small"
                                onClick={() => {
                                    if (unifiedFileName.trim() && selectedItems.size > 0) {
                                        handleBatchUpdateFileName(Array.from(selectedItems), unifiedFileName);
                                    }
                                }}
                                disabled={!unifiedFileName.trim() || selectedItems.size === 0}
                                style={{ borderRadius: 8 }}
                            >
                                应用
                            </Button>
                        </div>
                        <div style={{
                            maxHeight: 300,
                            overflow: 'auto',
                            border: '1px solid #f0f0f0',
                            borderRadius: 8,
                            padding: 12,
                        }}>
                            {(() => {
                                const itemMap = new Map<string, any>();
                                recordlist.forEach((group: any) => {
                                    group.items.forEach((item: any) => {
                                        const resourceId = getItemResourceId(item);
                                        itemMap.set(resourceId, item);
                                    });
                                });
                                return Array.from(selectedItems).map((itemId) => {
                                    const item = itemMap.get(itemId);
                                    return (
                                        <div
                                            key={itemId}
                                            style={{
                                                display: 'flex',
                                                alignItems: 'center',
                                                gap: 12,
                                                padding: '8px 0',
                                                borderBottom: '1px solid #f5f5f5',
                                            }}
                                        >
                                            <div style={{
                                                width: 60,
                                                height: 40,
                                                borderRadius: 4,
                                                backgroundColor: '#f5f5f5',
                                                display: 'flex',
                                                alignItems: 'center',
                                                justifyContent: 'center',
                                                overflow: 'hidden',
                                                flexShrink: 0,
                                            }}>
                                                {(() => {
                                                    const coverField = filterMedia === 'video' ? item?.videoCoverUrl : item?.imageUrl;
                                                    if (!coverField) {
                                                        return <Typography.Text style={{ fontSize: 12, color: '#94a3b8' }}>预览</Typography.Text>;
                                                    }
                                                    const baseUrl = import.meta.env.VITE_API_BASE || "http://localhost:8000";
                                                    const cleanPath = coverField.startsWith('/') ? coverField.slice(1) : coverField;
                                                    const cleanBase = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
                                                    const coverUrl = `${cleanBase}/static/${cleanPath}&w=300&q=50`;
                                                    return (
                                                        <img
                                                            src={coverUrl}
                                                            alt=""
                                                            style={{ width: '100%', height: '100%', objectFit: 'cover' }}
                                                        />
                                                    );
                                                })()}
                                            </div>
                                            <div style={{ flex: 1, minWidth: 0 }}>
                                                <Typography.Text style={{ fontSize: 12, color: '#1e293b' }}>
                                                    {item?.fileName || `素材 ${item.id}`}
                                                </Typography.Text>
                                            </div>
                                            <Input
                                                value={materialFileNames.has(itemId) ? materialFileNames.get(itemId)! : item?.fileName || ''}
                                                onChange={(e) => {
                                                    const newName = e.target.value;
                                                    const newNames = new Map(materialFileNames);
                                                    newNames.set(itemId, newName);
                                                    setMaterialFileNames(newNames);
                                                }}
                                                onBlur={() => {
                                                    const newName = materialFileNames.get(itemId) || item?.fileName || '';
                                                    if (newName.trim()) {
                                                        handleUpdateFileName(itemId, newName);
                                                    }
                                                }}
                                                onKeyDown={(e) => {
                                                    if (e.key === 'Enter') {
                                                        const newName = materialFileNames.get(itemId) || item?.fileName || '';
                                                        if (newName.trim()) {
                                                            handleUpdateFileName(itemId, newName);
                                                        }
                                                    }
                                                }}
                                                placeholder="输入新名称"
                                                style={{ width: 200, borderRadius: 4 }}
                                                size="small"
                                            />
                                        </div>
                                    );
                                });
                            })()}
                        </div>
                    </div>

                    <div style={{ display: 'flex', gap: 16, marginBottom: 16 }}>
                        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                            <Typography.Text style={{ fontSize: 14, color: '#475569' }}>是否开启前测：</Typography.Text>
                            <Select
                                value={isPreTest}
                                onChange={(value) => {
                                    setIsPreTest(value);
                                    if (value !== '1') {
                                        setPreTestTemplate('');
                                    } else {
                                        getDefaultPreTest().then((res) => {
                                            setPreTestTemplate(res?.data?.id || '');
                                        }).catch(() => {
                                        });
                                    }
                                }}
                                style={{ width: 120 }}
                                options={[
                                    { value: '1', label: '是' },
                                    { value: '2', label: '否' },
                                ]}
                            />
                        </div>
                        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                            <Typography.Text style={{ fontSize: 14, color: '#475569' }}>前测模板：</Typography.Text>
                            <Select
                                value={preTestTemplate}
                                onChange={(value) => setPreTestTemplate(value)}
                                style={{ width: 200 }}
                                disabled={isPreTest !== '1'}
                                loading={preTestTemplatesLoading}
                                placeholder={isPreTest !== '1' ? '请先开启前测' : '选择前测模板'}
                                options={preTestTemplates.map((item) => ({
                                    value: item.id,
                                    label: item.name,
                                }))}
                            />
                        </div>
                    </div>
                    <Tabs
                        size="small"
                        activeKey={accountTab}
                        onChange={(key) => {
                            setAccountTab(key as 'new' | 'history');
                            if (key === 'history') {
                                loadHistoryOAuthList();
                            }
                        }}
                        items={[
                            {
                                key: 'new',
                                label: '新增账户',
                            },
                            {
                                key: 'history',
                                label: '历史账户',
                            },
                        ]}
                    />
                    {accountTab === 'new' && (
                        <div>
                            {selectedOauthItems.map((oauthItem, index) => (
                                <div key={index} style={{ marginBottom: 16, padding: 12, border: '1px solid #e2e8f0', borderRadius: 8 }}>
                                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 }}>
                                        <Typography.Text strong style={{ fontSize: 14, color: '#475569' }}>
                                            授权账户 {index + 1}
                                        </Typography.Text>
                                        {selectedOauthItems.length > 1 && (
                                            <Button
                                                type="text"
                                                danger
                                                onClick={() => {
                                                    const newOauthItems = [...selectedOauthItems];
                                                    const newAccountIdInputs = [...accountIdInputs];
                                                    const newAccountIdLists = [...accountIdLists];
                                                    const newOauthSelectOpens = [...oauthSelectOpens];
                                                    newOauthItems.splice(index, 1);
                                                    newAccountIdInputs.splice(index, 1);
                                                    newAccountIdLists.splice(index, 1);
                                                    newOauthSelectOpens.splice(index, 1);
                                                    setSelectedOauthItems(newOauthItems);
                                                    setAccountIdInputs(newAccountIdInputs);
                                                    setAccountIdLists(newAccountIdLists);
                                                    setOauthSelectOpens(newOauthSelectOpens);
                                                }}
                                            >
                                                删除
                                            </Button>
                                        )}
                                    </div>
                                    <Select
                                        value={oauthItem}
                                        onChange={(value) => {
                                            const newOauthItems = [...selectedOauthItems];
                                            newOauthItems[index] = value as { value: string; label: string } | undefined;
                                            setSelectedOauthItems(newOauthItems);
                                        }}
                                        placeholder="点击选择授权账户"
                                        style={{ width: '100%', marginBottom: 12, borderRadius: 8 }}
                                        popupRender={() => (
                                            <div style={{ padding: 8, width: 800, maxHeight: 500, overflow: 'auto' }}>
                                                <Table
                                                    dataSource={oauthList}
                                                    columns={[
                                                        {
                                                            title: '授权账户ID',
                                                            dataIndex: 'accountId',
                                                            key: 'accountId',
                                                            width: 120,
                                                        },
                                                        {
                                                            title: '授权账户名称',
                                                            dataIndex: 'accountName',
                                                            key: 'accountName',
                                                            width: 120,
                                                        },
                                                        {
                                                            title: '授权账户角色',
                                                            dataIndex: 'accountRole',
                                                            key: 'accountRole',
                                                            width: 160,
                                                            render: (role: string) => {
                                                                const roleMap: Record<string, string> = {
                                                                    ADVERTISER: '客户',
                                                                    CUSTOMER_ADMIN: '普通版工作台-管理员',
                                                                    CUSTOMER_OPERATOR: '普通版工作台-协作者',
                                                                    AGENT: '代理商',
                                                                    CHILD_AGENT: '二级代理商',
                                                                    PLATFORM_ROLE_STAR: '星图账户',
                                                                    PLATFORM_ROLE_SHOP_ACCOUNT: '抖音店铺账户',
                                                                    PLATFORM_ROLE_QIANCHUAN_AGENT: '千川代理商',
                                                                    PLATFORM_ROLE_STAR_AGENT: '星图代理商',
                                                                    PLATFORM_ROLE_AWEME: '抖音号',
                                                                    PLATFORM_ROLE_STAR_MCN: '星图MCN机构',
                                                                    PLATFORM_ROLE_STAR_ISV: '星图服务商',
                                                                    AGENT_SYSTEM_ACCOUNT: '代理商系统账户',
                                                                    PLATFORM_ROLE_LOCAL_AGENT: '本地推代理商',
                                                                    PLATFORM_ROLE_YUNTU_BRAND_ISV_ADMIN: '云图品牌服务商管理员',
                                                                    PLATFORM_ROLE_LIFE: '抖音来客账户',
                                                                    PLATFORM_ROLE_ENTERPRISE_BP_ADMIN: '升级版工作台管理员',
                                                                    PLATFORM_ROLE_ENTERPRISE_BP_OPERATOR: '升级版工作台协作者',
                                                                };
                                                                return roleMap[role] || role;
                                                            },
                                                        },
                                                        {
                                                            title: '授权账户用户名',
                                                            dataIndex: 'accountUsername',
                                                            key: 'accountUsername',
                                                            width: 120,
                                                            render: (text: string) => <span style={{ color: text ? '#1e293b' : '#94a3b8' }}>{text || '-'}</span>,
                                                        },
                                                        {
                                                            title: '授权用户ID',
                                                            dataIndex: 'accountUserid',
                                                            key: 'accountUserid',
                                                            width: 120,
                                                        },
                                                    ]}
                                                    loading={oauthLoading}
                                                    pagination={{
                                                        current: oauthPage,
                                                        pageSize: oauthPageSize,
                                                        total: oauthTotal,
                                                        showSizeChanger: true,
                                                        showTotal: (total) => `共 ${total} 条记录`,
                                                        onChange: (page, size) => {
                                                            setOauthPage(page);
                                                            setOauthPageSize(size);
                                                            loadOAuthList(page, size);
                                                        },
                                                    }}
                                                    rowKey="id"
                                                    size="small"
                                                    scroll={{ x: 'max-content' }}
                                                    onRow={(record) => ({
                                                        onClick: () => {
                                                            const id = String(record.id);
                                                            const newOauthItems = [...selectedOauthItems];
                                                            newOauthItems[index] = { value: id, label: String(record.accountId) + '-' + (record.accountName || '-') };
                                                            setSelectedOauthItems(newOauthItems);
                                                            const newOauthSelectOpens = [...oauthSelectOpens];
                                                            newOauthSelectOpens[index] = false;
                                                            setOauthSelectOpens(newOauthSelectOpens);
                                                        },
                                                        style: {
                                                            cursor: 'pointer',
                                                            backgroundColor: oauthItem?.value === String(record.id) ? '#e6f7ff' : undefined,
                                                        },
                                                    })}
                                                />
                                            </div>
                                        )}
                                        open={oauthSelectOpens[index]}
                                        onOpenChange={(open) => {
                                            const newOauthSelectOpens = [...oauthSelectOpens];
                                            newOauthSelectOpens[index] = open;
                                            setOauthSelectOpens(newOauthSelectOpens);
                                            if (open) {
                                                loadOAuthList(1, oauthPageSize);
                                            }
                                        }}
                                        labelInValue
                                        fieldNames={{ label: 'accountUserid', value: 'id' }}
                                    />
                                    <Typography.Text strong style={{ fontSize: 14, color: '#475569', marginBottom: 8, display: 'block' }}>
                                        粘贴账户ID（每行一个或用逗号分隔）
                                    </Typography.Text>
                                    <Input.TextArea
                                        value={accountIdInputs[index]}
                                        onChange={(e) => {
                                            const value = e.target.value;
                                            const newAccountIdInputs = [...accountIdInputs];
                                            newAccountIdInputs[index] = value;
                                            setAccountIdInputs(newAccountIdInputs);
                                            const ids = value.split(/[\n,]/)
                                                .map(line => line.trim())
                                                .filter(line => line.length > 0);
                                            const uniqueIds = [...new Set(ids)];
                                            const textAccounts = uniqueIds.map(id => ({ accountId: id }));
                                            const seen = new Set<string>();
                                            const finalAccounts = textAccounts.filter(a => {
                                                if (seen.has(a.accountId)) return false;
                                                seen.add(a.accountId);
                                                return true;
                                            });
                                            const newAccountIdLists = [...accountIdLists];
                                            newAccountIdLists[index] = finalAccounts;
                                            setAccountIdLists(newAccountIdLists);
                                        }}
                                        placeholder="粘贴账户ID，每行一个或用逗号分隔，例如：
    10001,10002,10003
    10004"
                                        rows={3}
                                        style={{ borderRadius: 8 }}
                                    />
                                </div>
                            ))}
                            <Button
                                type="dashed"
                                block
                                onClick={() => {
                                    setSelectedOauthItems([...selectedOauthItems, undefined]);
                                    setAccountIdInputs([...accountIdInputs, '']);
                                    setAccountIdLists([...accountIdLists, []]);
                                    setOauthSelectOpens([...oauthSelectOpens, false]);
                                }}
                                style={{ borderRadius: 8, marginBottom: 16 }}
                            >
                                + 新增授权账户组
                            </Button>
                        </div>
                    )}
                    {accountTab === 'history' && (
                        <div style={{ padding: 8 }}>
                            {historyOAuthLoading ? (
                                <div style={{ textAlign: 'center', padding: 40 }}>加载中...</div>
                            ) : historyOAuthList.length === 0 ? (
                                <Empty description="暂无可选账户" />
                            ) : (
                                <Transfer
                                    style={{ width: '100%' }}
                                    dataSource={historyOAuthList
                                        .filter(item => item.advertiserId)
                                        .map((item, index) => ({
                                            key: String(item.advertiserId) || `item-${index}`,
                                            title: String(item.advertiserId),
                                            description: item.advertiserName || '',
                                            ...item,
                                        }))}
                                    targetKeys={selectedHistoryAccounts
                                        .filter(item => item.advertiserId)
                                        .map(item => String(item.advertiserId))}
                                    onChange={(targetKeys) => {
                                        const newSelected = historyOAuthList.filter(item =>
                                            item.advertiserId && targetKeys.includes(String(item.advertiserId))
                                        );
                                        setSelectedHistoryAccounts(newSelected);
                                    }}
                                    titles={['可选账户列表', '已选账户列表']}
                                    showSearch
                                    filterOption={(inputValue, item) =>
                                        String(item.advertiserId).toLowerCase().includes(inputValue.toLowerCase()) ||
                                        (item.advertiserName && item.advertiserName.toLowerCase().includes(inputValue.toLowerCase()))
                                    }
                                >
                                    {({
                                        direction,
                                        filteredItems,
                                        onItemSelect,
                                        onItemSelectAll,
                                        selectedKeys: listSelectedKeys,
                                        disabled: listDisabled,
                                    }) => {
                                        const columns = [
                                            {
                                                title: '账户ID',
                                                dataIndex: 'advertiserId',
                                                key: 'advertiserId',
                                                width: 120,
                                            },
                                            {
                                                title: '账户名称',
                                                dataIndex: 'advertiserName',
                                                key: 'advertiserName',
                                                width: 150,
                                            },
                                        ];
                                        const rowSelection = {
                                            getCheckboxProps: () => ({ disabled: listDisabled }),
                                            onChange: (selectedRowKeys: string[]) => {
                                                onItemSelectAll(selectedRowKeys, 'replace');
                                            },
                                            selectedRowKeys: listSelectedKeys,
                                            selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT, Table.SELECTION_NONE],
                                        };
                                        return (
                                            <Table
                                                rowSelection={rowSelection}
                                                columns={columns}
                                                dataSource={filteredItems}
                                                size="small"
                                                style={{ pointerEvents: listDisabled ? 'none' : undefined }}
                                                pagination={false}
                                                scroll={{ x: 'max-content', y: 400 }}
                                                onRow={({ key, disabled: itemDisabled }) => ({
                                                    onClick: () => {
                                                        if (itemDisabled || listDisabled) {
                                                            return;
                                                        }
                                                        onItemSelect(key, !listSelectedKeys.includes(key));
                                                    },
                                                })}
                                            />
                                        );
                                    }}
                                </Transfer>
                            )}
                        </div>
                    )}
                    {/* 操作按钮 */}
                    <div style={{
                        display: 'flex',
                        gap: 12,
                        justifyContent: 'flex-end',
                    }}>
                        <Button
                            onClick={() => {
                                setUploadConfigModalVisible(false);
                                setAccountIdLists([[]]);
                                setAccountIdInputs(['']);
                                setSelectedOauthItems([undefined]);
                                setMaterialFileNames(new Map());
                                setUnifiedFileName('');
                            }}
                            style={{ borderRadius: 8 }}
                        >
                            取消
                        </Button>
                        <Button
                            type="primary"
                            onClick={handleStartBatchUpload}
                            loading={uploading}
                            disabled={uploading || (accountTab === 'new' ? accountIdLists.every(list => list.length === 0) : selectedHistoryAccounts.length === 0)}
                            style={{ borderRadius: 8 }}
                        >
                            {uploading ? '推送中...' : '开始推送'}
                        </Button>
                    </div>
                </div>
            </Modal>
        </div>
    );
};

// 文件大小格式化
function formatFileSize(bytes: number): string {
    if (bytes === 0) return '0 B';
    const k = 1024;
    const sizes = ['B', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

// 添加旋转动画样式
const styleSheet = document.createElement('style');
styleSheet.textContent = `
    @keyframes spin {
        from { transform: rotate(0deg); }
        to { transform: rotate(360deg); }
    }
`;
document.head.appendChild(styleSheet);

// 日期格式化（年月日时分秒）
function formatDateTime(dateString: string): string {
    if (!dateString) return '-';
    const date = new Date(dateString);
    if (isNaN(date.getTime())) return '-';

    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    const hours = String(date.getHours()).padStart(2, '0');
    const minutes = String(date.getMinutes()).padStart(2, '0');
    const seconds = String(date.getSeconds()).padStart(2, '0');

    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}

export default GeneratedRecord;
