import * as React from 'react';
import { Modal, Form, Input, Select, Upload, UploadProps, message, Spin, Tooltip, Button } from 'antd';
import { InboxOutlined, QuestionCircleOutlined } from '@ant-design/icons';
import { apis } from '@/apis';
import { getHeaders } from '@/apis/config';
import { RecordKonwledge } from '../types'
const FormItem = Form.Item;
const { Option } = Select;
const { TextArea } = Input;
const { Dragger } = Upload;

interface Props {
    open: boolean;
    knowledgeId: string;
    knowledgeDetail: RecordKonwledge;
    onCancel: () => void;
    onSuccess: () => void;
}

const UploadModal: React.FC<Props> = (props: Props) => {
    const { open, knowledgeId, onCancel, onSuccess, knowledgeDetail } = props;
    const [form] = Form.useForm();
    const [uploadLoading, setUploadLoading] = React.useState<boolean>(false);
    const [standardClass, setStandardClass] = React.useState<any[]>([]);// 选择分类-下拉选项
    const [parsingTypeList, setParsingTypeList] = React.useState<any[]>([]);// 解析工具-下拉选项
    const [parsingTypeListBackup, setParsingTypeListBackup] = React.useState<any[]>([]);// 解析工具-下拉选项-备份数据
    const [standardClassification, setStandardClassification] = React.useState<string>() // 选择分类
    const [parsingType, setParsingType] = React.useState<string>() // 选择解析工具
    const [splittingOldList, setSplittingOldList] = React.useState<any[]>([]); // 旧的切分规则列表
    const [splittingType, setSplittingType] = React.useState<any>([]); // 选择切分规则 
    const [fileOssList, setFileOssList] = React.useState<any>([]); // 选中的列表OSS信息
    const [oldFileList, setOldFileList] = React.useState<any>([]); // 选中的本地文件列表
    const [oldfileName, setOldfileName] = React.useState<any>(''); // 选中的本地文件的信息
    const [isVisibleSlice, setIsVisibleSlice] = React.useState(false);
    const [formatb, setFormatb] = React.useState('md,txt,pdf,doc,docx,odt,rtf,ods,ppt,pptx,odp,jpg,png,jpeg'); // 默认是通用
    const oldFileListRef = React.useRef(oldFileList);

    React.useEffect(() => {
        oldFileListRef.current = oldFileList;
    }, [oldFileList]);
    
    // 获取解析工具
    const fetchParsingTypeList = async () => {
        try {
            const res = await apis.fetchTakaiAppTypeList('parsing_type');
            const list = res.data.map((item: any) => {
                return {
                    label: item.dictLabel,
                    value: item.dictValue,
                }
            });
            setParsingTypeList(list);
            setParsingTypeListBackup(list);
            form.setFieldsValue({
                parsingType: list[0]?.value
            })
        } catch (error: any) {
            console.error(error);
        }
    }
    // 获取向默认切分规则
    const fetchsplittingType = async () => {
        try {
            const res = await apis.fetchTakaiAppTypeList('splitting_type');
            const list = res.data.map((item: any) => {
                return {
                    label: item.dictLabel,
                    value: item.dictValue,
                    remark: item.remark,
                }
            });
            setSplittingType(list);
            setSplittingOldList(list);
            form.setFieldsValue({
                customSeparator: '2',
                sliceValue: knowledgeDetail.sliceValue,
            })

            if (knowledgeDetail.splittingType === '0') {
                setIsVisibleSlice(!isVisibleSlice);
            }
        } catch (error: any) {
            console.error(error);
        }
    }
    const onChangeF = (value: string) => {
        if (value === '0') {
            setIsVisibleSlice(!isVisibleSlice);
        } else {
            setIsVisibleSlice(false);
        }
    };
    // 批量删除oss文件
    const onDeleteOssFileApi = async (ossIds: string) => {
        try {
            const res: any = await apis.deleteOssFileApi(ossIds);
            if (res.code !== 200) {
                message.error('删除oss文件失败');
            }
        } catch (error) {
            console.error('删除oss文件失败:', error);
        }
    };
    // 手动上传单个文件
    const uploadOneFile = (fileItem: any) => {
        return new Promise((resolve, reject) => {
            if (fileItem.response && fileItem.response.code === 200) {
                resolve(fileItem.response.data);
                return;
            }
            const formData = new FormData();
            formData.append('file', fileItem.originFileObj);

            const xhr = new XMLHttpRequest();
            xhr.open('POST', '/api/resource/oss/upload', true);
            const headers: any = getHeaders();
            for (const key in headers) {
                xhr.setRequestHeader(key, headers[key]);
            }

            xhr.upload.onprogress = (event) => {
                if (event.lengthComputable) {
                    const percent = parseInt(((event.loaded / event.total) * 100).toFixed(0));
                    setOldFileList((prev: any[]) => prev.map(f => {
                        if (f.uid === fileItem.uid) {
                            return { ...f, percent, status: 'uploading' };
                        }
                        return f;
                    }));
                }
            };

            xhr.onload = () => {
                if (xhr.status === 200) {
                    const response = JSON.parse(xhr.responseText);
                    if (response.code === 200) {
                        setOldFileList((prev: any[]) => prev.map(f => {
                            if (f.uid === fileItem.uid) {
                                return { ...f, status: 'done', percent: 100, response };
                            }
                            return f;
                        }));
                        resolve(response.data);
                    } else {
                        setOldFileList((prev: any[]) => prev.map(f => {
                            if (f.uid === fileItem.uid) {
                                return { ...f, status: 'error' };
                            }
                            return f;
                        }));
                        message.error(response.msg || '上传失败');
                        reject(response.msg);
                    }
                } else {
                    setOldFileList((prev: any[]) => prev.map(f => {
                        if (f.uid === fileItem.uid) {
                            return { ...f, status: 'error' };
                        }
                        return f;
                    }));
                    message.error('上传失败');
                    reject('Http Error');
                }
            };

            xhr.onerror = () => {
                setOldFileList((prev: any[]) => prev.map(f => {
                    if (f.uid === fileItem.uid) {
                        return { ...f, status: 'error' };
                    }
                    return f;
                }));
                message.error('网络错误');
                reject('Network Error');
            };

            xhr.send(formData);
        });
    };

    // 上传组件的参数
    const uploadProps: UploadProps = {
        name: 'file',
        // 根据选择的分类决定是否允许多选与最大数量：分类为 '3' 时只允许单文件，其余允许最多 5 个
        multiple: standardClassification !== '3',
        maxCount: standardClassification === '3' ? 1 : 5,
        headers: getHeaders(),
        // 使用受控 fileList，便于自定义已上传文件列表的展示和管理
        fileList: oldFileList,
        beforeUpload(file, fileList) {
            const maxCount = standardClassification === '3' ? 1 : 5;
            const currentCount = (oldFileList || []).length;
            const incomingCount = fileList?.length || 1;
            if (currentCount + incomingCount > maxCount) {
                message.error(`最多只能上传 ${maxCount} 个文件`);
                return Upload.LIST_IGNORE;
            }
            const allowedExtensions = formatb ? formatb.split(',') : ['*'];
            const nextFormatb = ['exe', 'msi', 'bat', 'cmd', 'com', 'sh', 'run', 'bin', 'app', 'dmg', 'pkg', 'jar', 'py'];
            // 检查文件类型
            const fileExt: string = file.name.split('.').pop()?.toLowerCase() || '';
            if(nextFormatb.includes(fileExt)){
                message.error(`不支持 ${fileExt} 格式的文件上传-12`);
                return Upload.LIST_IGNORE;
            }
            if(formatb === '*'){
                // 支持所有格式
            }else if (!fileExt || !allowedExtensions.includes(fileExt)) {
                message.error(`不支持 ${fileExt} 格式的文件上传`);
                return Upload.LIST_IGNORE;
            }

            // 检查文件大小
            const fileSizeMB = file.size / 1024 / 1024;
            if (fileSizeMB > 50) {
                message.error('单个文件不能大于50M');
                return Upload.LIST_IGNORE;
            }

            if (['jpg', 'png', 'jpeg'].includes(fileExt!) && fileSizeMB > 5) {
                message.error('单张图片不能大于5M');
                return Upload.LIST_IGNORE;
            }

            let totalSize = fileSizeMB;
            for (const f of oldFileList) {
                totalSize += (f.size / 1024 / 1024);
            }
            if (totalSize > 150) {
                message.error('文件总大小超过150M');
                return Upload.LIST_IGNORE;
            }

            // 阻止自动上传
            return false;
        },
        onChange(info) {
            setOldFileList(info.fileList);
            if (standardClassification === '3' && info.fileList.length > 0) {
                const latest = info.fileList[info.fileList.length - 1];
                if (latest && latest.originFileObj) {
                    const nameParts = latest.name.split('.');
                    const nameWithoutExt = nameParts.length > 1 ? nameParts.slice(0, -1).join('.') : latest.name;
                    form.setFieldsValue({
                        name: nameWithoutExt
                    });
                    setOldfileName(latest.name);
                }
            }
        },
        onDrop(e) {
            console.log('Dropped files', e.dataTransfer.files);
        },
        onRemove(file) {
            // 先从本地受控 fileList 中移除
            setOldFileList((prev: any[]) => (prev || []).filter((f) => f.uid !== file.uid));
            // 如果该文件已上传并携带后端返回数据，则尝试删除 OSS 记录
            const resFile = file?.response?.data;
            if (resFile?.ossId) {
                onDeleteOssFileApi(`${resFile.ossId}`);
                setFileOssList((pre: any[]) => (pre || []).filter((item: any) => item.ossId !== resFile.ossId));
            }
            return true;
        }

    };
    // 获取选择分类
    const fetchAppstandardClass = async () => {
        try {
            const res = await apis.fetchTakaiAppTypeList('standard_classification');
            const list = res.data.map((item: any) => {
                return {
                    label: item.dictLabel,
                    value: item.dictValue,
                    remark: item.remark,
                }
            });
            setStandardClass(list);
            form.setFieldsValue({
                standardClassification: list[1]?.value
            })
            setStandardClassification(list[1]?.value)
        } catch (error: any) {
            console.error(error);
        }
    }
    React.useEffect(() => {
        if (open) {
            form.resetFields();
            fetchParsingTypeList();
            fetchsplittingType();
            fetchAppstandardClass();
        }
    }, [open]);

    // 点击确定
    const handleClickConfirm = () => {
        form.validateFields().then(async (values) => {
            // 这里可以处理表单数据的提交
            const maxCount = standardClassification === '3' ? 1 : 5;
            if (!oldFileList || oldFileList.length === 0) {
                message.warning('请选择文件')
                return
            }
            if (oldFileList.length > maxCount) {
                message.warning(`最多只能上传 ${maxCount} 个文件`)
                return
            }

            setUploadLoading(true);

            try {
                // 上传所有文件
                const uploadResults = await Promise.all(oldFileList.map((file: any) => uploadOneFile(file)));

                // 构造 ossItems
                let ossItems = oldFileList.map((f: any, index: number) => {
                    const data = uploadResults[index];
                    const nameParts = f.name.split('.');
                    return {
                        uid: f.uid,
                        name: nameParts.length > 1 ? nameParts.slice(0, -1).join('.') : f.name.split('.')[0],
                        ...data
                    };
                });

                // 过滤掉已经在过程中被删除的文件
                const currentUids = oldFileListRef.current?.map((f: any) => f.uid) || [];
                const removedItems = ossItems.filter((item: any) => !currentUids.includes(item.uid));
                ossItems = ossItems.filter((item: any) => currentUids.includes(item.uid));
                removedItems.forEach((resFile: any) =>{
                    if (resFile.ossId)
                    onDeleteOssFileApi(`${resFile.ossId}`);
                })

                setFileOssList(ossItems);

                const params = {
                    ...values,
                    parsingType: values.parsingType,
                    standardClassification,
                    fileList: ossItems.map((item: any) => ({
                        ...item,
                        suffix: (item.fileName || item.name || '').split('.').pop(),
                    })),
                }

                // checkFileApi 检查文件是否存在 如果已存在就提示 未存在成功
                const checkParams = {
                    ...values,
                    parsingType: values.parsingType,
                    standardClassification,
                    ossParms: ossItems,
                    knowledgeId: knowledgeId
                }

                const checkRes: any = await apis.checkFileApi(checkParams);
                const checkResData = checkRes.data || [];

                if (!checkResData?.length) {
                    await onUploadDocumentApi(params);
                    setUploadLoading(false);
                } else {
                    setUploadLoading(false);
                    Modal.confirm({
                        title: '提示',
                        content: checkResData.map((item: any) => {
                            return <div key={item.ossId}>文件“{item.newName}”已存在，知识库中已存在的文件名是“{item.oldName}”</div>
                        }),
                        onOk: async () => {
                            setUploadLoading(true);
                            // 过滤掉已存在的文件（根据 ossId）
                            const filtered = ossItems.filter((f: any) => !checkResData.some((d: any) => d.ossId === f.ossId));

                            if (!filtered || filtered.length === 0) {
                                // 所有文件都已存在，提示并结束
                                message.warning('选中文件均已存在知识库，未执行上传。');
                                setUploadLoading(false);
                                return;
                            }

                            // 构建参数并继续上传剩余文件
                            const nextParams = {
                                ...values,
                                parsingType: values.parsingType,
                                standardClassification,
                                fileList: filtered.map((item: any) => ({
                                    ...item,
                                    suffix: (item.fileName || item.name || '').split('.').pop(),
                                })),
                            };
                            await onUploadDocumentApi(nextParams);
                            setUploadLoading(false);
                        },
                        onCancel: () => {
                            setUploadLoading(false);
                        }
                    });
                }
            } catch (error) {
                setUploadLoading(false);
                console.error(error);
            }
        }).catch((error) => {
            console.error(error);
        });
    };
    const onUploadDocumentApi = async (params: any) => {
        const res = await apis.uploadDocumentApi(knowledgeId, params)

        if (res.code === 200) {
            // 上传逻辑已在上传组件的 onChange 中处理
            message.success('操作成功');
            onCancel();
            onSuccess();
            form.resetFields();
        }
    }
    // 点击取消
    const handleClickCancel = () => {
        form.resetFields();
        onCancel();
    };
    return (
        <Modal
            width={600}
            title='上传知识文件'
            maskClosable={false}
            centered={true}
            open={open}
            onCancel={handleClickCancel}
            footer={
                <div>
                    <Button
                        className="ant-btn ant-btn-default"
                        onClick={handleClickCancel}
                        style={{ marginRight: 8 }}
                    >
                        取消
                    </Button>
                    <Button
                        className="ant-btn ant-btn-primary"
                        onClick={handleClickConfirm}
                        loading={uploadLoading}
                    >
                        确定
                    </Button>
                </div>
            }
        >
            <Spin spinning={false}>
                <Form form={form} layout='vertical'>
                    <FormItem
                        label='选择分类'
                        name='standardClassification'
                        rules={[{ required: true, message: '请选择分类' }]}
                    >
                        <Select
                            style={{ width: '100%' }}
                            placeholder='请选择分类'
                            optionLabelProp="label"
                            allowClear={true}
                            value={standardClassification}
                            onChange={(e) => {
                                // form.setFieldsValue({
                                //     standardClassification: e,
                                // })
                                let nextFormatb = 'md,txt,pdf,doc,docx,odt,rtf,ods,ppt,pptx,odp';

                                if(e === '0') {
                                    nextFormatb = 'md,txt,pdf,doc,docx,odt,rtf,ods,ppt,pptx,odp';
                                }
                                if(e === '1') {
                                    nextFormatb = 'md,txt,pdf,doc,docx,odt,rtf,ods,ppt,pptx,odp,jpg,png,jpeg';
                                }
                                if(e === '2') {
                                    nextFormatb = 'xlsx';
                                }
                                if(e === '3') {
                                    // nextFormatb = 'md,txt,pdf,jpg,png,jpeg,doc,docx,odt,rtf,xls,xlsx,ppt,pptx,odp';
                                    nextFormatb = '*';
                                }
                                // 切换分类时，判断是新的类型是否支持当前选中的这些文件 如果不支持就给提示让手动去清除
                                const allowedExtensions = nextFormatb.split(',');
                                const invalidFiles = oldFileList.filter((file: any) => {
                                    const fileExt = file.name.split('.').pop()?.toLowerCase();
                                    return fileExt && !allowedExtensions.includes(fileExt);
                                });
                                if (invalidFiles.length > 0) {
                                    // 还原Select选中值
                                    form.setFieldsValue({
                                        standardClassification: standardClassification
                                    });
                                    Modal.confirm({
                                        title: '提示',
                                        content: invalidFiles.map((item: any) => {
                                            return <div key={item.uid}>文件“{item.name}”,与所选分类不匹配</div>
                                        }),
                                        onOk: () => {
                                            
                                        }
                                    })
                                    return;
                                }

                                setStandardClassification(e);
                                const oldfileOssIds = fileOssList.map((item: any) => item.ossId).join(',');
                                if (oldfileOssIds) {
                                    onDeleteOssFileApi(oldfileOssIds);
                                }
                                // setOldFileList([]);
                                // setFileOssList([]);
                                setOldfileName('');
                                if (e === '0') {
                                    // 标准规范
                                    const newSplittingList = splittingOldList.filter((item: any) => item.value === '3');
                                    setSplittingType(newSplittingList);
                                    form.setFieldsValue({
                                        customSeparator: newSplittingList[0]?.value,
                                    });

                                    const newParsingTypeList = parsingTypeListBackup.filter((item: any) => item.value === '0');
                                    setParsingTypeList(newParsingTypeList);

                                    form.setFieldsValue({
                                        parsingType: newParsingTypeList[0]?.value,
                                    })
                                } else {
                                    setSplittingType(splittingOldList);
                                    // parsingTypeListBackup
                                    setParsingTypeList(parsingTypeListBackup);
                                }
                                if (e === '1') {
                                    // 通用规范
                                    form.setFieldsValue({
                                        customSeparator: '2',
                                    });
                                }
                                setFormatb(nextFormatb);
                                // 清空文件名称
                                form.setFieldsValue({
                                    name: '',
                                });
                            }}
                        >
                            {
                                standardClass.map((item, index) => {
                                    return <Option value={item.value} key={index} label={item.label}>
                                        {item.label}
                                        <Tooltip title={item.remark} >
                                            <QuestionCircleOutlined style={{ color: '#FF9800', marginLeft: '3px' }} />
                                        </Tooltip>
                                    </Option>
                                })
                            }
                        </Select>
                    </FormItem>
                    <div style={{ marginBottom: 20, width: '100%', minHeight: '150px' }}>
                        <Dragger {...uploadProps}>
                            <p className="ant-upload-drag-icon">
                                <InboxOutlined />
                            </p>
                            <p>
                                点击上传,或拖放文件到此处
                            </p>
                            {standardClassification==='3'?<p className="ant-upload-hint">
                                支持常规日程工作中的大部分文件格式
                            </p>:
                            <p className="ant-upload-hint">
                                支持文件格式{formatb}
                                ,<br/>单个文件 ≤ 50M
                            </p>}
                        </Dragger>
                    </div>
                    {(standardClassification === '0' || standardClassification === '1') &&
                        <><FormItem
                            label='解析工具'
                            name='parsingType'
                            rules={[{ required: true, message: '请解析工具' }]}
                        >
                            <Select
                                style={{ width: '100%' }}
                                placeholder='请解析工具'
                                allowClear={true}
                                onChange={(e) => {
                                    setParsingType(e)
                                    if (e === '2') {
                                        const newSplittingList = splittingOldList.filter((item: any) => item.value !== '3');
                                        setSplittingType(newSplittingList);
                                        form.setFieldsValue({
                                            customSeparator: newSplittingList[0]?.value,
                                        });
                                    } else {
                                        setSplittingType(splittingOldList);
                                    }
                                }}
                            >
                                {
                                    parsingTypeList.map((item, index) => {
                                        return <Option value={item.value} key={index}>
                                            {item.label}
                                        </Option>
                                    })
                                }
                            </Select>
                        </FormItem>
                            <FormItem
                                label='默认切分规则'
                                name='customSeparator'
                                rules={[{ required: true, message: '默认切分规则不能为空' }]}
                            >
                                {
                                    <Select
                                        style={{ width: '100%' }}
                                        placeholder='请选择默认切分规则'
                                        allowClear={true}
                                        onChange={onChangeF}
                                        optionLabelProp="label"
                                    >
                                        {
                                            splittingType.map((item: any, index: any) => {
                                                return <Option value={item.value} key={index} label={item.label}>
                                                    {item.label}
                                                    <Tooltip title={item.remark} >
                                                        <QuestionCircleOutlined style={{ color: '#FF9800', marginLeft: '3px' }} />
                                                    </Tooltip>
                                                </Option>
                                            })
                                        }
                                    </Select>
                                }
                            </FormItem></>}
                    {isVisibleSlice &&
                        <FormItem
                            label='分隔符'
                            name='sliceValue'
                            rules={[{ required: true, message: '自定义切片设置不能为空' }]}
                        >
                            <Input max={1024}
                            />
                        </FormItem>
                    }
                    {standardClassification === '3' && <><FormItem
                        label='文件名称'
                        name='name'
                        rules={[{ required: true, message: '文件名称不能为空', whitespace: true }]}
                    >
                        <Input placeholder='请输入文件名称' />
                    </FormItem>
                        <FormItem
                            label='描述'
                            name='remark'
                            rules={[{ required: true, message: '描述不能为空', whitespace: true }]}
                        >
                            <TextArea
                                placeholder='请输入描述信息'
                                showCount={true}
                                rows={6}
                                maxLength={500}
                            />
                        </FormItem></>}
                </Form>
            </Spin>
        </Modal>
    );
};

export default UploadModal;

