import { toExcelColumnName } from "@/common/converter";
import { TagStatus, UploadWrongLocalHeaderError } from "@/components";
import ExamOrgScoreReportController from "@/services/apis/ExamOrgScoreReportController";
import { CaretDownOutlined, CaretRightOutlined, InboxOutlined, RightOutlined } from "@ant-design/icons";
import { ProCard, ProColumns, ProTable } from "@ant-design/pro-components";
import { Alert, App, Button, Space, Typography, UploadFile, UploadProps, theme } from "antd";
import Upload, { RcFile } from "antd/es/upload";
import { useState } from "react";

type TemplateCompareType = {
    [key: number | string]: {
        name?: string;
        isMatched?: boolean;
    } | string
};

const OrgSchoolExamScoreCourseReport: React.FC<{
    data: API.ExamOrgScoreReportItem;
    sequence: number;
    reportable: boolean;
    onUploaded: () => void;
}> = ({ reportable, data, onUploaded }) => {
    const { token } = theme.useToken();

    const [fileList, setFileList] = useState<UploadFile[]>([]);
    const [uploading, setUploading] = useState(false);
    const [collapsed, setCollapsed] = useState(true);
    const [uploadData, setUploadData] = useState<API.UploadExamOrgScoreReportOutput>();

    const { message } = App.useApp();

    const uploadProps: UploadProps = {
        onRemove: () => {
            setFileList([]);
        },
        beforeUpload: (file) => {
            setFileList([file]);
            return false;
        },
        fileList,
        multiple: false,
        accept: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel',
    };

    // const { data: courseScore, run: loadCourseScore } = useRequest(() => ExamOrgScoreReportController.queryOne({
    //     examPlanId: data.examPlanId,
    //     examGradeId: data.examGradeId,
    //     courseId: data.courseId,
    // }), { manual: true });

    // 监测科目模板配置
    const sconfig = JSON.parse(data.scoreReportConfig as string) as API.ExamCourseScoreReportConfig;
    // 模板列定义
    const tplColumns: ProColumns<TemplateCompareType>[] = sconfig?.headerColumnNames?.map((c, ci) => ({
        title: toExcelColumnName(ci),
        dataIndex: [ci, 'name'],
        align: 'center',
        ellipsis: true,
        render: (v, r) => {
            const rv = r[ci] as any;
            if (r.type === 'data') {
                return rv;
            }

            if (r.type === 'template') {
                return v;
            }
            return <span style={{ color: rv.isMatched ? token.colorSuccess : token.colorError }}>{rv.name}</span>
        },
    })) ?? [];

    let ds: TemplateCompareType = {};
    sconfig.headerColumnNames?.forEach((c, ci) => { ds[ci] = { name: c, }; });
    ds.key = 'rt';
    ds.type = 'template';
    ds.typeName = '模板列名';
    const [list, setList] = useState<TemplateCompareType[]>([ds]);

    // 上传
    const handleUpload = async () => {
        const formData = new FormData();
        formData.append('examPlanId', `${data.examPlanId}`);
        formData.append('examGradeId', `${data.examGradeId}`);
        formData.append('gradeId', `${data.gradeId}`);
        formData.append('courseId', `${data.courseId}`);
        fileList.forEach((file) => {
            formData.append('file', file as RcFile);
        });
        setUploading(true);
        try {
            const res = await ExamOrgScoreReportController.upload(formData);
            setUploadData(res);
            setList([
                ds,
                {
                    key: 'ru',
                    type: 'upload',
                    typeName: '上传列名',
                    ...res?.columns
                },
                ...res?.rows.filter((t, i) => i < 10).map((t, i) => ({
                    key: `rd-${i}`,
                    type: 'data',
                    typeName: `${i + 1}`,
                    ...t
                })) ?? [],
            ]);
            onUploaded?.();
            if (res?.isSuccess) {
                // loadCourseScore();
                setCollapsed(true);
                message.success('已上传');
            }
            else {
                message.error('上传失败');
            }
        }
        catch { }
        finally {
            setUploading(false);
        }
    }

    const tplColCount = sconfig.headerColumnNames?.length ?? 0;
    const getCompareDesc = (a: number, b: number) => {
        if (a === b) {
            return '与模板要求相符';
        }
        if (a > b) {
            return '少于模板要求';
        }
        return '多于模板要求';
    }

    const isUploaded = data.fileSize !== '0';

    return (
        <ProCard
            title={
                <Space size="large">
                    {reportable &&
                        <Button
                            type="text"
                            icon={collapsed ? <CaretRightOutlined /> : <CaretDownOutlined />}
                            onClick={() => { setCollapsed(v => !v); }}
                            style={{ marginRight: -token.margin }}
                        />
                    }
                    <Typography.Title level={4} style={{ marginBottom: 0 }}>
                        {data.gradeName}
                        （{data.gradeBeginYear}级）
                        <span style={{ marginRight: token.margin }}>-</span>
                        {data.courseName}
                    </Typography.Title>
                    {isUploaded ? <TagStatus status="success">已上传</TagStatus> : <TagStatus status="error">未上传</TagStatus>}
                </Space>
            }
            headerBordered
            style={{ marginBottom: token.marginLG }}
            extra={
                reportable ?
                    <Button
                        type={isUploaded ? 'default' : 'primary'}
                        onClick={() => { setCollapsed(v => !v); }}
                    >
                        {isUploaded ? '重新上传' : '上传成绩'}
                        <RightOutlined />
                    </Button> :
                    null
            }
            bordered
            collapsed={collapsed}
        >
            <Space direction="vertical" style={{ width: '100%' }}>
                <Upload.Dragger {...uploadProps}>
                    <p className="ant-upload-drag-icon"><InboxOutlined /></p>
                    <p className="ant-upload-text">点击或拖入文件到此处</p>
                </Upload.Dragger>

                <Space>
                    <Button
                        type="primary"
                        disabled={fileList.length === 0}
                        loading={uploading}
                        onClick={handleUpload}
                    >{uploading ? '上传中' : '立即上传'}</Button>
                    <UploadWrongLocalHeaderError />
                </Space>

                {uploadData &&
                    <Alert
                        type={uploadData?.isSuccess ? 'success' : 'error'}
                        showIcon
                        message={uploadData.isSuccess ? '文件验证通过，上传成功！' : '文件验证未通过，上传失败！'}
                        description={
                            <Typography.Paragraph style={{ marginBottom: 0 }}>
                                模板要求【{tplColCount}】列，实际上传文件为【{uploadData.columnsCount}】列
                                {getCompareDesc(tplColCount, uploadData.columnsCount)}
                                {uploadData.errorColumnCount > 0 && `，其中有【${uploadData.errorColumnCount}】列错误（参照下方表格中红色字体标注，请仔细核对）`}。
                                上传文件中共【{uploadData?.rowCount}】行数据。
                            </Typography.Paragraph>
                        }
                    />
                }

                <ProTable
                    rowKey="key"
                    cardProps={false}
                    columns={[
                        {
                            title: '类型',
                            dataIndex: 'typeName',
                            fixed: 'left',
                            width: 80,
                            align: 'center',
                            rowScope: 'row',
                        },
                        ...tplColumns,
                    ]}
                    size="small"
                    pagination={false}
                    search={false}
                    options={false}
                    bordered
                    dataSource={list}
                    scroll={{ x: 'max-content' }}
                    toolbar={{
                        title: <Typography.Title level={5} style={{ marginBottom: 0 }}>模板与上传成绩文件对比情况</Typography.Title>,
                        subTitle: '下表仅显示上传表格除标题前10行数据',
                        // actions: [
                        //     <Button key="detail">查看完整数据</Button>
                        // ],
                    }}
                />
            </Space>
        </ProCard>
    );
}

export default OrgSchoolExamScoreCourseReport;
