import { toValueEnum } from "@/common/converter";
import { CardStepTitle, FileLink, SuperTable } from "@/components";
import ReportButton from "@/components/ReportButton";
import ExamGradeController from "@/services/apis/ExamGradeController";
import ExamOrgDataReportController from "@/services/apis/ExamOrgDataReportController";
import ExamPlanController from "@/services/apis/ExamPlanController";
import ExamStudentController from "@/services/apis/ExamStudentController";
import SysOrgController from "@/services/apis/SysOrgController";
import { DataReportStatus, DataReportType, EducationStage, ExamStatus } from "@/services/enums";
import { BulbOutlined, PlusOutlined, ReloadOutlined, UploadOutlined } from "@ant-design/icons";
import { ActionType, PageContainer, ProCard, ProColumns, ProDescriptions, ProTable } from "@ant-design/pro-components";
import { history, useModel, useParams } from "@umijs/max";
import { useRequest } from "ahooks";
import { Alert, App, Badge, Button, Drawer, Space, Tag, Tour, Typography, theme } from "antd";
import { useCallback, useRef, useState } from "react";
import ExamStudentEditModal from "./components/ExamStudentEditModal";

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

    const { token } = theme.useToken();
    const { getDictValueEnum, getKeyDict } = useModel('useDict');
    const examStatusDict = getKeyDict('exam_status');
    const dataReportStatusDict = getKeyDict('data_report_status');
    const dataReportTypeDict = getKeyDict('data_report_type');
    const { baseData } = useModel('useBaseData');

    const { initialState } = useModel('@@initialState');
    const { currentUser } = initialState ?? {};

    const [remarkOpen, setRemarkOpen] = useState(false);
    const [editOpen, setEditOpen] = useState(false);
    const actionRef = useRef<ActionType>();
    const currentRef = useRef<Partial<API.ExamStudentOutput>>();

    const [tourOpen, setTourOpen] = useState(false);
    const tourReportRef = useRef(null);

    const { message, modal } = App.useApp();

    const { data: gradeBranchData } = useRequest(async () => {
        const res1 = await ExamGradeController.getListByExamPlanId({ examplanid: reqParams.examPlanId });
        const res2 = await SysOrgController.getOrgBranchByOrgId({ orgid: currentUser?.sysOrgId ?? 0 });
        const res3 = await ExamPlanController.getById({ id: reqParams.examPlanId });
        return {
            examGrades: res1 ?? [],
            branches: res2 ?? [],
            hasDistrict: (res2?.length ?? 0) > 0,
            hasNceeCourseComb: res3?.educationStage === EducationStage.SENIOR_HIGH_SCHOOL_STAGE,
        };
    });

    // 加载上报数据
    const { data: reportData, run: loadReport } = useRequest(() => {
        return ExamOrgDataReportController.getByTypeExamPlanId({ type: DataReportType.STUDENT, examplanid: reqParams.examPlanId });
    });

    // 加载统计数据
    const { data: studentCountData, run: loadStudentCount, loading } = useRequest(() => {
        return ExamStudentController.getOrgGradeClassStudentCount({ examplanid: reqParams.examPlanId });
    });

    // 统计数据列定义
    let studentCountColumns: ProColumns<any>[] = [
        {
            title: '年级',
            dataIndex: ['Grade', 'name'],
            width: 64,
            align: 'center',
            fixed: 'left',
        },
        {
            title: '合计',
            dataIndex: 'GradeTotal',
            width: 64,
            align: 'center',
            fixed: 'left',
        },
    ];
    studentCountData?.classNumberList?.forEach(t => {
        studentCountColumns.push({
            title: `${t}班`,
            dataIndex: `${t}`,
            width: 56,
            align: 'center',
        });
    });
    studentCountColumns.push({});

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

    // 清空
    const handleClear = useCallback(() => {
        modal.confirm({
            title: '谨慎操作',
            content: '确定立即清空所有学生信息吗',
            okText: '确定',
            cancelText: '取消',
            centered: true,
            onOk: async () => {
                await ExamStudentController.clear({ examPlanId: reqParams.examPlanId });
                message.success('已清空');
                actionRef.current?.reload();
                loadStudentCount();
            },
        });
    }, []);

    // 上报
    const handleSubmit = useCallback(() => {
        return new Promise<void>((resolve, reject) => {
            let content = `共 ${studentCountData?.total ?? 0} 个学生，上报后不能再修改，确定立即上报吗？`;
            modal.confirm({
                title: '警告',
                content,
                okText: '确定',
                cancelText: '取消',
                centered: true,
                onOk: async () => {
                    try {
                        await ExamOrgDataReportController.submit({ examPlanId: reqParams.examPlanId, type: DataReportType.STUDENT })
                        message.success('已上报');
                        loadReport();
                        resolve();
                    }
                    catch { reject(); }
                },
                onCancel: () => reject(),
            });
        });
    }, [studentCountData]);

    const reportable = (reportData?.examDataReport?.status === ExamStatus.ACTIVE && reportData?.isExpired === false &&
        (reportData?.examOrgDataReport?.status === DataReportStatus.UNREPORT ||
            reportData?.examOrgDataReport?.status === DataReportStatus.REJECTED));

    let detailActions = [];
    if (reportable) {
        detailActions.push(
            <Button
                key="import"
                type="primary"
                icon={<UploadOutlined />}
                disabled={!reportable}
                onClick={() => history.push(`/exam-s/stu/import/${reqParams.examPlanId}`)}
            >批量导入</Button>
        );
        detailActions.push(
            <Button
                key="add"
                disabled={!reportable}
                icon={<PlusOutlined />}
                onClick={() => {
                    currentRef.current = { id: '0' };
                    setEditOpen(true);
                }}
            >添加学生</Button>
        );
        detailActions.push(
            <Button
                key="clear"
                disabled={!reportable}
                onClick={handleClear}
            >清空数据</Button>
        );
    }
    // detailActions.push(
    //     <Button
    //         key="download"
    //     >批量导出</Button>
    // );

    const columns: ProColumns<API.ExamStudentOutput>[] = [
        ...(gradeBranchData?.hasDistrict ? [{
            title: '校区',
            dataIndex: 'sysOrgBranchId',
            width: 96,
            align: 'center',
            hideInSearch: !gradeBranchData?.hasDistrict,
            valueEnum: toValueEnum(gradeBranchData?.branches ?? []),
        } as ProColumns] : []),
        {
            title: '年级',
            dataIndex: 'gradeId',
            width: 144,
            align: 'center',
            valueEnum: toValueEnum(gradeBranchData?.examGrades?.map(t => ({ id: t.gradeId, name: `${t.grade.name}（${t.gradeBeginName}）` })) ?? []),
        },
        {
            title: '班级',
            dataIndex: 'classNumber',
            valueType: 'digit',
            width: 64,
            align: 'center',
            render: (_, r) => `${r.classNumber}班`,
        },
        {
            title: '姓名',
            dataIndex: 'name',
            align: 'center',
            className: 'minw-80',
        },
        {
            title: '证件类型',
            dataIndex: 'certificateType',
            valueEnum: getDictValueEnum('certificate_type'),
            width: 112,
            align: 'center',
            search: {
                transform: (v) => ({ certificateType: JSON.parse(v) })
            },
        },
        {
            title: '证件号码',
            dataIndex: 'idNumber',
            width: 160,
            align: 'center',
        },
        // {
        //     title: '学籍号码',
        //     width: 168,
        //     align: 'center',
        // },
        {
            title: '自编监测号',
            dataIndex: 'examNumber',
            width: 120,
            align: 'center',
        },
        ...(gradeBranchData?.hasNceeCourseComb ? [{
            title: '选科组合',
            dataIndex: 'nceeCourseCombId',
            valueEnum: toValueEnum((baseData?.nceeCourseCombs ?? []).map(t => ({ ...t, name: t.shortName }))),
            width: 80,
            align: 'center',
        } as ProColumns] : []),
        {
            title: '考场号',
            dataIndex: 'roomNumber',
            width: 64,
            align: 'center',
        },
        {
            title: '座位号',
            dataIndex: 'seatNumber',
            width: 64,
            align: 'center',
        },
        {
            title: '备注',
            dataIndex: 'remark',
            hideInSearch: true,
            className: 'minw-64',
        },
        {
            title: '操作',
            valueType: 'option',
            width: 112,
            align: 'center',
            fixed: 'right',
            hideInTable: !reportable,
            render: (_, r) => {
                return (
                    <>
                        <Button
                            type="link"
                            size="small"
                            onClick={() => {
                                currentRef.current = r;
                                setEditOpen(true);
                            }}
                        >修改</Button>
                        <Button
                            type="link"
                            size="small"
                            onClick={() => handleDelete(r.id)}
                        >删除</Button>
                    </>
                );
            },
        }
    ];

    return (
        <PageContainer
            title={`${reportData?.examPlan?.fullName ?? ''} - 学生信息上报`}
            onBack={() => history.back()}
            extra={reportable &&
                <Button
                    type="link"
                    icon={<BulbOutlined />}
                    onClick={() => {
                        window.scrollTo({ top: 0 });
                        setTourOpen(true);
                    }}
                >查看操作指引</Button>
            }
        >
            <ProCard
                title={<CardStepTitle>基本情况</CardStepTitle>}
                extra={reportData?.examOrgDataReport?.status &&
                    <Tag
                        style={{ marginRight: 0 }}
                        color={dataReportStatusDict[reportData.examOrgDataReport.status].antColor}
                    >
                        {dataReportStatusDict[reportData.examOrgDataReport.status].name}
                    </Tag>
                }
            >
                <ProDescriptions>
                    <ProDescriptions.Item label="上报类型">
                        {reportData?.examDataReport?.type ? dataReportTypeDict[reportData?.examDataReport?.type].name : ''}
                    </ProDescriptions.Item>
                    <ProDescriptions.Item label="监测上报">
                        {reportData?.examDataReport?.status &&
                            <Badge
                                status={examStatusDict[reportData.examDataReport.status].antStatus as any}
                                text={examStatusDict[reportData.examDataReport.status].name}
                            />
                        }
                    </ProDescriptions.Item>
                    <ProDescriptions.Item label="截止时间">
                        <Typography.Text strong>
                            {reportData?.examDataReport?.endTime}
                            {reportData?.isExpired && reportData.examDataReport?.status === ExamStatus.ACTIVE &&
                                <Typography.Text type="danger">（已截止）</Typography.Text>
                            }
                        </Typography.Text>
                    </ProDescriptions.Item>
                    <ProDescriptions.Item label="上报人员">{reportData?.examOrgDataReport?.reportSysUser?.name}</ProDescriptions.Item>
                    <ProDescriptions.Item label="上报时间">{reportData?.examOrgDataReport?.reportTime}</ProDescriptions.Item>
                    <ProDescriptions.Item label="备注说明">{reportData?.examOrgDataReport?.remark}</ProDescriptions.Item>

                </ProDescriptions>
                <ProDescriptions layout="vertical" column={1}>
                    <ProDescriptions.Item label="上报说明">
                        <Typography.Text ellipsis>{reportData?.examDataReport?.remark || '无'}</Typography.Text>
                        {reportData?.examDataReport?.remark && <Button type="link" size="small" onClick={() => setRemarkOpen(true)}>详情</Button>}
                    </ProDescriptions.Item>
                    {reportData?.examDataReport?.attachmentList &&
                        <ProDescriptions.Item label="附件文件">
                            <Space direction="vertical" style={{ width: '100%' }}>
                                {reportData?.examDataReport?.attachmentList?.map((t, i) => (
                                    <FileLink key={i} {...t} card />
                                ))}
                            </Space>
                        </ProDescriptions.Item>
                    }
                </ProDescriptions>
                <Drawer open={remarkOpen} title="上报说明" width={720} maskClosable onClose={() => setRemarkOpen(false)}>
                    <pre>{reportData?.examDataReport?.remark || '无'}</pre>
                </Drawer>
            </ProCard>
            <Alert
                type="warning"
                showIcon
                closable
                style={{ marginTop: token.margin, color: token.colorError }}
                message="确认各年级各班级填报无误后一次性上报，上报后不能再修改和上报！"
            />
            <ProTable<any>
                style={{ marginTop: token.margin }}
                search={false}
                pagination={false}
                scroll={{ x: 'max-content' }}
                size="small"
                bordered
                options={{ setting: false, density: false, reloadIcon: <ReloadOutlined onClick={loadStudentCount} /> }}
                rowKey="GradeId"
                loading={loading}
                columns={studentCountColumns}
                columnEmptyText=""
                dataSource={studentCountData?.items ?? []}
                toolbar={{
                    title: (<CardStepTitle>数量统计</CardStepTitle>),
                    actions: reportable ? [
                        <span key="tooltip">离上报结束还有</span>,
                        <ReportButton
                            key="time"
                            buttonRef={tourReportRef}
                            showIcon
                            expireTime={reportData?.examDataReport?.endTime}
                            onSubmit={handleSubmit}
                            onTimerFinish={() => loadReport()}
                        />
                    ] : [],
                }}
            />

            <SuperTable<API.ExamStudentOutput>
                headerTitle={<CardStepTitle>学生明细</CardStepTitle>}
                style={{ marginTop: token.margin }}
                actionRef={actionRef}
                scroll={{ x: 'max-content' }}
                rowKey="id"
                columns={columns}
                search={{ showHiddenNum: false }}
                options={{ setting: false, fullScreen: false }}
                toolbar={{
                    actions: detailActions,
                }}
                request={async (params, sort) => {
                    return SuperTable.requestPageAgent({ params, sort }, async (p) => {
                        const res = await ExamStudentController.queryPageList({ ...p, examPlanId: reqParams.examPlanId });
                        return res;
                    });
                }}
            // rowSelection={reportable ? {} : false}
            />
            {editOpen && currentRef.current && gradeBranchData &&
                <ExamStudentEditModal
                    examPlanId={reqParams.examPlanId}
                    data={currentRef.current}
                    gradeBranch={gradeBranchData}
                    onFinish={() => {
                        actionRef.current?.reload();
                        loadStudentCount();
                    }}
                    onClose={() => setEditOpen(false)}
                />
            }

            <Tour
                steps={[
                    {
                        title: '上报学生信息',
                        description: '仔细确认各年级各班级人数和学生明细无误后，点击“立即上报”按钮完成学生信息上报。',
                        target: () => tourReportRef.current,
                    },
                ]}
                open={tourOpen}
                onClose={() => setTourOpen(false)}
            />
        </PageContainer>
    );
}

export default OrgExamStudentReport;
