import { downloadFileByBlob } from "@/common/net/download";
import { FileIcon, FileLink, StatusIcon, SuperTable } from "@/components";
import ExamOrgController from "@/services/apis/ExamOrgController";
import ExamOrgResultController from "@/services/apis/ExamOrgResultController";
import { DeleteOutlined, SendOutlined, UploadOutlined } from "@ant-design/icons";
import { ActionType, PageContainer, ProColumns, ProTable } from "@ant-design/pro-components";
import { history, useParams } from "@umijs/max";
import { useRequest } from "ahooks";
import { App, Button, Space, Upload, UploadFile, UploadProps, theme } from "antd";
import { RcFile } from "antd/es/upload";
import lodash from 'lodash';
import { useCallback, useRef, useState } from "react";

type UploadItem = {
    key: number;
    examOrgId?: number;
    sysOrgId?: number;
    sysOrg?: API.SysOrgLiteOutput;
    file?: UploadFile;
    progress: number;
    success: boolean;
};

type ResultItem = API.ExamOrgResultOutput & { isFirstRow: boolean, rowSpan: number };


const ExamResultDetail: React.FC = () => {
    const reqParams = useParams() as unknown as { examPlanId: number; publishId: number; };

    const [fileList, setFileList] = useState<UploadFile[]>([]);
    const [uploading, setUploading] = useState(false);

    const [selectedRowKeys, setSelectedRowKeys] = useState<number[]>([]);

    const { data: orgs } = useRequest(() => ExamOrgController.queryPageList({ pageIndex: 1, pageSize: 9999, examPlanId: reqParams.examPlanId }));
    const [uploadItems, setUploadItems] = useState<UploadItem[]>([]);

    const { message, modal } = App.useApp();
    const { token } = theme.useToken();
    const actionRef = useRef<ActionType>();

    const uploadProps: UploadProps = {
        // onRemove: (file) => {
        //     const index = fileList.indexOf(file);
        //     const newFileList = fileList.slice();
        //     newFileList.splice(index, 1);
        //     setFileList(newFileList);
        // },
        beforeUpload: (file) => {
            setFileList(fs => {
                if (fs.findIndex(t => t.name === file.name) > -1) {
                    return fs;
                }
                const ss = [...fs, file];
                let uis: UploadItem[] = [];
                let k = 0;
                ss.forEach(t => {
                    const fns = t.name.split('-');
                    let o: API.ExamOrgOutput | undefined;
                    if (fns.length > 1) {
                        o = orgs?.items?.find((u: any) => u.sysOrg?.code === fns[0] || u.sysOrg?.fullName === fns[0]);
                    }
                    else {
                        const f = t.name.split('.');
                        o = orgs?.items?.find((u: any) => u.sysOrg?.fullName === f[0]);
                    }
                    if (o) {
                        uis.push({
                            key: k++,
                            examOrgId: o.id,
                            sysOrgId: o.sysOrgId,
                            sysOrg: o.sysOrg,
                            file: t,
                            progress: 0,
                            success: true,
                        });
                    }
                    else {
                        uis.push({
                            key: k++,
                            file: t,
                            progress: 0,
                            success: false,
                        });
                    }
                });
                setUploadItems(uis);
                return ss;
            });
            return false;
        },
        fileList,
        multiple: true,
        itemRender: () => null,
        // itemRender: (originNode, file, fileList, actions) => <p>{file.name}</p>,
        // accept: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel',
    };

    // 批量上传机构文件
    const handleUpload = async () => {
        setUploading(true);
        try {
            const uis = uploadItems.filter(t => t.progress === 0 && t.success);
            let i = 0;
            let ps: Promise<any>[] = [];
            for (; i < uis.length; i++) {
                const row = uis[i];
                const formData = new FormData();
                formData.append('examPlanId', `${reqParams.examPlanId}`);
                formData.append('examDataPublishId', `${reqParams.publishId}`);
                formData.append('examOrgId', `${row.examOrgId}`);
                formData.append('sysOrgId', `${row.sysOrgId}`);
                formData.append('file', row.file as RcFile);
                ps.push(ExamOrgResultController.upload(formData, {
                    onUploadProgress: (p: any) => {
                        let fi = uploadItems.findIndex(t => t.key === row.key);
                        uploadItems[fi].progress = parseFloat((p.loaded / p.total * 100).toFixed(1));
                        setUploadItems([...uploadItems]);
                    }
                }));
                // const ps = uis.map(row => {
                //     const formData = new FormData();
                //     formData.append('examPlanId', `${reqParams.examPlanId}`);
                //     formData.append('examDataPublishId', `${reqParams.publishId}`);
                //     formData.append('examOrgId', `${row.examOrgId}`);
                //     formData.append('sysOrgId', `${row.sysOrgId}`);
                //     formData.append('file', row.file as RcFile);

                //     return ExamOrgResultController.upload(formData, {
                //         onUploadProgress: (p: any) => {
                //             let fi = uploadItems.findIndex(t => t.key === row.key);
                //             uploadItems[fi].progress = parseFloat((p.loaded / p.total * 100).toFixed(1));
                //             setUploadItems([...uploadItems]);
                //         }
                //     });
                // });
                if (i > 0 && (i % 5 === 0 || i === uis.length - 1)) {
                    await Promise.all(ps);
                    actionRef.current?.reload();
                    ps = [];
                }
            }
        }
        catch { }
        finally {
            setUploading(false);
        }
    }

    // 移出待上传文件
    const handleRemove = async (keys: number[]) => {
        setSelectedRowKeys([]);
        const uis = uploadItems.filter(t => !keys.includes(t.key));
        setUploadItems(uis);
        const fls = uis.map(t => t.file) as UploadFile[];
        if (fls?.length > 0) {
            setFileList(fls);
        }
        else {
            setFileList([]);
        }
    }

    // 删除机构文件
    const handleDelete = useCallback(async (id: number) => {
        modal.confirm({
            title: '警告',
            content: '确定立即删除吗',
            okText: '确定',
            cancelText: '取消',
            centered: true,
            onOk: async () => {
                await ExamOrgResultController.del({ id });
                message.success('已删除');
                actionRef.current?.reload();
            },
        });
    }, []);

    // 文件上传列定义
    const uploadColumns: ProColumns<UploadItem>[] = [
        {
            title: '文件名称',
            dataIndex: ['file', 'name'],
            render: (v, r) => {
                const fss = r.file?.name.split('.') ?? [];
                let extName = 'unknown';
                if (fss.length > 1) {
                    extName = fss[fss?.length - 1];
                }
                return (
                    <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
                        <FileIcon type={extName} style={{ marginRight: token.marginXXS }} />
                        {v}
                    </div>
                );
            },
        },
        {
            title: '文件大小',
            dataIndex: 'fileSize',
            width: 96,
            align: 'right',
            render: (_, r) => {
                const fsize = parseFloat(`${r.file?.size ?? 0}`);
                if (fsize < 1024 * 1024) {
                    return `${(fsize / 1024).toFixed(0)} KB`;
                }
                return `${(fsize / 1024 / 1024).toFixed(2)} MB`;
            },
        },
        {
            title: '匹配结果',
            valueType: 'option',
            width: 80,
            align: 'center',
            render: (_, r) => <StatusIcon status={r.success ? 'success' : 'error'} filled />
        },
        {
            title: '匹配机构名称',
            dataIndex: ['sysOrg', 'fullName'],
            width: 320,
            ellipsis: true,
        },
        {
            title: '上传进度',
            dataIndex: 'progress',
            width: 120,
            valueType: (r) => ({
                type: 'progress',
                status: r.progress >= 100 ? 'success' : 'active',
                precision: 1,
            }),
        },
        {
            title: '操作',
            valueType: 'option',
            width: 72,
            align: 'center',
            render: (_, r) => {
                return (
                    <Button
                        type="link"
                        size="small"
                        onClick={() => handleRemove([r.key])}
                        disabled={r.progress > 0}
                    >移出</Button>
                );
            },
        },
    ];

    // 机构反馈文件列定义
    const orgColumns: ProColumns<ResultItem>[] = [
        {
            title: '序',
            valueType: 'option',
            width: 40,
            align: 'center',
            render: (_, r, ri) => ri + 1,
        },
        {
            title: '机构代码',
            dataIndex: ['examOrg', 'sysOrg', 'code'],
            width: 80,
            align: 'center',
            onCell: (r) => {
                if (r.isFirstRow) {
                    if (r.rowSpan > 1) {
                        return { rowSpan: r.rowSpan };
                    }
                    return {};
                }
                return { rowSpan: 0 };
            },
        },
        {
            title: '机构全称',
            dataIndex: ['examOrg', 'sysOrg', 'fullName'],
            width: 320,
            ellipsis: true,
            onCell: (r) => {
                if (r.isFirstRow) {
                    if (r.rowSpan > 1) {
                        return { rowSpan: r.rowSpan };
                    }
                    return {};
                }
                return { rowSpan: 0 };
            },
        },
        {
            title: '文件名称',
            dataIndex: 'fileName',
            ellipsis: true,
            render: (_, r) => {
                if (!r.filePath) {
                    return null;
                }
                return (
                    <FileLink
                        fileExtName={r.fileExtName}
                        fileName={r.fileName}
                        fileSize={r.fileSize}
                        onDownload={async () => {
                            const res = await ExamOrgResultController.download({ id: r.id });
                            if (res) {
                                downloadFileByBlob(res.data, res.fileName);
                            }
                        }}
                    />
                );
                // return (
                //     <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
                //         <FileIcon type={r.fileExtName} style={{ marginRight: token.marginXXS }} />
                //         {v}
                //     </div>
                // );
            },
        },
        {
            title: '上传时间',
            dataIndex: 'createTime',
            width: 144,
            align: 'center',
            render: (v, r) => {
                if (r.filePath) {
                    return v;
                }
                return null;
            },
        },
        {
            title: '文件大小',
            dataIndex: 'fileSize',
            width: 96,
            align: 'right',
            render: (_, r) => {
                if (!r.filePath) {
                    return null;
                }
                const fsize = parseFloat(`${r.fileSize ?? 0}`);
                if (fsize < 1024 * 1024) {
                    return `${(fsize / 1024).toFixed(0)} KB`;
                }
                return `${(fsize / 1024 / 1024).toFixed(2)} MB`;
            },
        },
        {
            title: '操作',
            valueType: 'option',
            width: 72,
            align: 'center',
            render: (_, r) => {
                if (!r.filePath) {
                    return null;
                }
                return (<Button type="link" size="small" onClick={() => handleDelete(r.id)}>删除</Button>);
            },
        },
    ];

    return (
        <PageContainer
            title="结果管理"
            onBack={() => history.back()}
        >
            <ProTable
                columns={uploadColumns}
                size="small"
                bordered
                dataSource={uploadItems}
                search={false}
                pagination={false}
                options={false}
                toolbar={{
                    title: '按机构上传文件',
                    actions: [
                        <Upload key="addFile" {...uploadProps}>
                            <Button icon={<UploadOutlined />} disabled={uploading}>添加文件...</Button>
                        </Upload>,
                        <Button
                            key="upload"
                            disabled={fileList.length === 0 || uploading}
                            loading={uploading}
                            onClick={handleUpload}
                            type="primary"
                            icon={<SendOutlined />}
                        >开始上传</Button>,
                        <Button
                            key="clear"
                            icon={<DeleteOutlined />}
                            disabled={fileList.length === 0 || uploading}
                            onClick={() => {
                                setUploadItems([]);
                                setFileList([]);
                                setSelectedRowKeys([]);
                            }}
                        >清空列表</Button>
                    ]
                }}
                rowSelection={{
                    getCheckboxProps: (r) => ({ disabled: r.progress > 0 }),
                    selectedRowKeys,
                    onSelect: (record, selected, selectedRows) => {
                        const sks = selectedRows.map((t) => t.key) || [];
                        setSelectedRowKeys(sks);
                    },
                    onSelectAll: (_, selectedRows) => {
                        setSelectedRowKeys(selectedRows.map((t) => t.key) || []);
                    },
                }}
                tableAlertRender={({ selectedRowKeys, onCleanSelected }) => {
                    return (
                        <Space size="large">
                            <span>已选 {selectedRowKeys.length} 项</span>
                            <a onClick={() => {
                                setSelectedRowKeys([]);
                                onCleanSelected();
                            }}>取消选择</a>
                        </Space>
                    );
                }}
                tableAlertOptionRender={({ selectedRowKeys }) => {
                    return (
                        <Space size="large">
                            <a onClick={() => handleRemove(selectedRowKeys as number[])}>批量移出</a>
                        </Space>
                    );
                }}
            />

            <SuperTable<ResultItem>
                style={{ marginTop: token.margin }}
                actionRef={actionRef}
                headerTitle="机构文件列表"
                columns={orgColumns}
                size="small"
                bordered
                search={false}
                pagination={false}
                options={{ setting: false }}
                columnEmptyText=""
                scroll={{ x: 640, y: 640 }}
                // virtual
                request={async () => {
                    const res = await ExamOrgResultController.getByPublishId({ publishid: reqParams.publishId });
                    const gcc = lodash.countBy(res, 'examOrgId');
                    const list = res?.map((t, i) => ({
                        ...t,
                        isFirstRow: res.findIndex(f => f.examOrgId === t.examOrgId) === i,
                        rowSpan: gcc[t.examOrgId] ?? 1,
                    } as ResultItem));

                    return {
                        success: true,
                        data: list,
                    };
                }}
            />

        </PageContainer>
    );
}

export default ExamResultDetail;