import { toValueEnum } from "@/common/converter";
import { AuditModal, CardStepTitle, FileLink, SuperTable, TabBadge } from "@/components";
import { AuditFormValueType } from "@/components/AuditModal";
import ExamAbsentReplaceDetailDrawer from "@/pages/exam-org/absent-replace/OrgExamAbsentReplaceReport/components/ExamAbsentReplaceDetailDrawer";
import ExamAbsentReplaceAuditController from "@/services/apis/ExamAbsentReplaceAuditController";
import ExamAbsentReplaceController from "@/services/apis/ExamAbsentReplaceController";
import ExamGradeController from "@/services/apis/ExamGradeController";
import ExamOrgDataReportController from "@/services/apis/ExamOrgDataReportController";
import SysOrgController from "@/services/apis/SysOrgController";
import { AuditStatus, DataReportStatus, DataReportType } from "@/services/enums";
import { AuditOutlined } from "@ant-design/icons";
import { ActionType, PageContainer, ProCard, ProColumns, ProDescriptions, ProDescriptionsItemProps } from "@ant-design/pro-components";
import { history, useModel, useParams } from "@umijs/max";
import { useRequest } from "ahooks";
import { Alert, App, Button, Space, Tag, Typography, theme } from "antd";
import { useCallback, useRef, useState } from "react";

/**
 * 缺测替补学生审核学校详细
 */
const ExamAbsentReplaceAuditOrg: React.FC = () => {
    const reqParams = useParams() as unknown as { examPlanId: number, sysOrgId: number };

    const { token } = theme.useToken();
    const { getDictValueEnum, getKeyDict, getDict } = useModel('useDict');
    const auditStatusDict = getKeyDict('audit_status');
    const dataReportStatusDict = getKeyDict('data_report_status');

    const [selectedRowKeys, setSelectedRowKeys] = useState<number[]>([]);
    const [auditShow, setAuditShow] = useState<{ open: boolean, ids: number[] } | undefined>();
    const [activeKey, setActiveKey] = useState<React.Key>('2');
    const [statusCount, seStatusCount] = useState<Record<number, number>>({});

    const [detailOpen, setDetailOpen] = useState(false);

    const actionRef = useRef<ActionType>();
    const currentRef = useRef<Partial<API.ExamAbsentReplaceOutput>>();

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

    // 加载上报数据
    const { data, loading } = useRequest(async () => {
        // 上报数据
        const reportData = await ExamOrgDataReportController.getByTypeExamPlanId({
            type: DataReportType.ABSENT_REPLACE,
            examplanid: reqParams.examPlanId,
            sysorgid: reqParams.sysOrgId,
        });
        // 校区
        const orgBranch = await SysOrgController.getOrgBranchByOrgId({ orgid: reqParams.sysOrgId });
        // 监测年级
        const examGrades = await ExamGradeController.getListByExamPlanId({ examplanid: reqParams.examPlanId });

        return {
            reportData,
            examGrades,
            hasOrgBranch: (orgBranch?.length ?? 0) > 0,
        };
    });

    const auditable = data?.reportData?.examOrgDataReport?.status === DataReportStatus.REPORTED;

    // 加载数量统计
    const loadCount = useCallback(async (params: API.ExamAbsentReplacePageInput) => {
        const m = await ExamAbsentReplaceController.queryStatusCount(params);
        const tc = m?.reduce((a, b) => a + b.count, 0) ?? 0;

        const d: Record<number, number> = { 0: tc };
        m?.forEach((t) => { d[t.status] = t.count; });

        seStatusCount(d);
    }, []);

    // 审核
    const handleAudit = async (ids: number[], formValues: AuditFormValueType) => {
        return new Promise<boolean>((resolve, reject) => {
            modal.confirm({
                title: '提交确认',
                content: '确认立即提交吗？',
                okText: '确定',
                cancelText: '取消',
                centered: true,
                onOk: async () => {
                    try {
                        await ExamAbsentReplaceAuditController.audit({ ids, ...formValues });
                        message.success('已提交');
                        resolve(true);
                        setSelectedRowKeys([]);
                        actionRef.current?.reload();
                    }
                    catch {
                        reject(false);
                    }
                },
                onCancel: () => resolve(false),
            });
        });
    }

    // 反审
    const handleReaudit = useCallback(async (id: number) => {
        modal.confirm({
            title: '提交确认',
            content: '确认立即反审吗？',
            okText: '确定',
            cancelText: '取消',
            centered: true,
            onOk: async () => {
                await ExamAbsentReplaceAuditController.reaudit({ id })
                message.success('已反审');
                setSelectedRowKeys([]);
                actionRef.current?.reload();
            },
        });
    }, []);

    // 明细表列定义
    const detailColumns: ProColumns<API.ExamAbsentReplaceOutput>[] = [
        {
            title: '审核状态',
            dataIndex: 'status',
            hideInSearch: true,
            width: 96,
            align: 'center',
            valueEnum: getDictValueEnum('audit_status', true),
            render: (_, r) => {
                const s = auditStatusDict[r.status];
                return (
                    <Space direction="vertical" size="small" style={{ lineHeight: 1 }}>
                        <Tag color={s.antStatus} style={{ marginRight: 0 }}>{s.name}</Tag>
                        <Typography.Text
                            type={r.isReplaced ? 'warning' : 'danger'}
                            style={{ fontSize: token.fontSizeSM }}
                        >
                            {r.isReplaced ? '有替补' : '无替补'}
                        </Typography.Text>
                    </Space>
                );
            },
        },
        ...(data?.hasOrgBranch ? [
            {
                title: '校区',
                dataIndex: ['sysOrgBranch', 'name'],
                width: 88,
                align: 'center',
            } as ProColumns,
        ] : []),
        {
            title: '年级',
            dataIndex: 'gradeId',
            width: 80,
            align: 'center',
            valueEnum: toValueEnum(data?.examGrades?.map(t => ({ id: t.gradeId, name: `${t.grade.name}（${t.gradeBeginName}）` })) ?? []),
            render: (_, r) => {
                return (
                    <Space size="small" direction="vertical" style={{ lineHeight: 1 }}>
                        {r.examGrade?.grade.name}
                        <Typography.Text type="secondary" style={{ fontSize: token.fontSizeSM }}>（{r.examGrade?.gradeBeginName}）</Typography.Text>
                    </Space>
                );
            },
        },
        {
            title: '班级',
            dataIndex: 'classNumber',
            valueType: 'digit',
            width: 56,
            align: 'center',
            render: (_, r) => `${r.classNumber}班`,
        },
        {
            title: '姓名',
            dataIndex: 'absentName',
            width: 112,
            align: 'center',
            render: (v, r) => <a onClick={() => { currentRef.current = r; setDetailOpen(true); }}>{v}</a>,
        },
        {
            title: '监测号',
            dataIndex: 'absentExamNumber',
            width: 112,
            align: 'center',
        },
        {
            title: '缺测替补原因',
            dataIndex: 'absentReason',
            hideInSearch: true,
            // width: 240,
        },
        {
            title: '缺测科目',
            dataIndex: 'absentCourseList',
            // width: 240,
            hideInSearch: true,
            render: (_, r) => {
                return r.absentCourseList?.map(t => t.name).join('、');
            },
        },
        {
            title: '家长电话',
            dataIndex: 'patriarchTel',
            hideInSearch: true,
            // width: 128,
            align: 'center',
        },
        {
            title: '替补学生姓名',
            dataIndex: 'replaceName',
            width: 112,
            align: 'center',
        },
        {
            title: '替补学生监测号',
            dataIndex: 'replaceExamNumber',
            width: 120,
            align: 'center',
        },
        {
            title: '备注',
            dataIndex: 'remark',
            hideInSearch: true,
            className: 'minw-64',
            // width: 160,
        },
        {
            title: '佐证材料',
            valueType: 'option',
            hideInSearch: true,
            hideInDescriptions: true,
            width: 280,
            fixed: 'right',
            render: (_, r) => {
                const li = r.attachmentList?.map((t, i) => {
                    return (
                        <FileLink
                            key={i}
                            fileExtName={t.fileExtName}
                            fileName={t.fileName}
                            fileId={t.fileId}
                            thumbFileId={t.thumbFileId}
                            card
                        />
                    );
                });
                return (
                    <Space direction="vertical" style={{ width: 280 }}>
                        {li}
                    </Space>
                );
            },
        },
        {
            title: '佐证材料',
            hideInSearch: true,
            hideInTable: true,
            width: 280,
            fixed: 'right',
            render: (_, r) => {
                const li = r.attachmentList?.map((t, i) => {
                    return (
                        <FileLink
                            key={i}
                            fileExtName={t.fileExtName}
                            fileName={t.fileName}
                            fileId={t.fileId}
                            thumbFileId={t.thumbFileId}
                            url={`${AppConfig.fileViewRoot}?id=${t.fileId}`}
                            thumbUrl={t.thumbFileId && t.thumbFileId !== '0' ? `${AppConfig.fileViewRoot}?id=${t.thumbFileId}` : undefined}
                            card
                        />
                    );
                });
                return (
                    <Space direction="vertical" style={{ width: '100%' }}>
                        {li?.length === 0 ? '未上传' : li}
                    </Space>
                );
            },
        },
        {
            title: '操作',
            valueType: 'option',
            width: 64,
            align: 'center',
            fixed: 'right',
            render: (_, r) => {
                if (!auditable) {
                    return null;
                }

                if ([AuditStatus.AUDIT, AuditStatus.APPROVE_CANCELED].includes(r.status)) {
                    return (
                        <Button
                            type="link"
                            size="small"
                            onClick={() => { setAuditShow({ open: true, ids: [r.id] }); }}
                        >审核</Button>
                    );
                }
                if (r.status === AuditStatus.APPROVED) {
                    return (
                        <Button
                            type="link"
                            size="small"
                            onClick={() => handleReaudit(r.id)}
                        >反审</Button>
                    );
                }
                return null;
            },
        }
    ];

    // 呈现状态 tab
    const renderTabItems = useCallback(() => {
        let items: { key: string; label: React.ReactNode }[] = [];
        items = items.concat(
            getDict('audit_status')?.filter(t => t.value > 1)?.sort((a, b) => a.sort - b.sort)?.map((t) => ({
                key: `${t.value}`,
                label: (
                    <span>
                        {t.name}
                        <TabBadge color={t.antColor} count={statusCount[t.value] ?? 0} active={activeKey === `${t.value}`} />
                    </span>
                ),
            })),
        );
        items.push({
            key: '0',
            label: (<span>全部<TabBadge count={statusCount[0]} active={activeKey === 0} /></span>),
        });
        return items;
    }, [activeKey, statusCount]);

    return (
        <PageContainer
            title={`${data?.reportData?.examOrgDataReport?.examOrg?.sysOrg?.fullName ?? ''} - 缺测替补学生审核`}
            onBack={() => history.back()}
            loading={loading}
        >
            <ProCard
                bodyStyle={{ paddingBottom: 0 }}
                title={<CardStepTitle>基本情况</CardStepTitle>}
                extra={data?.reportData?.examOrgDataReport?.status &&
                    <Space>
                        <span>学校上报状态</span>
                        <Tag
                            style={{ marginRight: 0 }}
                            color={dataReportStatusDict[data?.reportData.examOrgDataReport.status].antColor}
                        >
                            {dataReportStatusDict[data?.reportData.examOrgDataReport.status].name}
                        </Tag>
                    </Space>
                }
            >
                <ProDescriptions>
                    <ProDescriptions.Item label="监测计划">
                        {data?.reportData?.examPlan?.name}
                    </ProDescriptions.Item>
                    <ProDescriptions.Item label="学校名称">
                        {data?.reportData?.examOrgDataReport?.examOrg?.sysOrg?.fullName}
                    </ProDescriptions.Item>
                    <ProDescriptions.Item label="上报时间">
                        {data?.reportData?.examOrgDataReport?.reportTime}
                    </ProDescriptions.Item>
                </ProDescriptions>
            </ProCard>

            <ProCard
                style={{ marginTop: token.margin }}
                title={<CardStepTitle>《缺测替补学生明细表》和《会议记录》打印签字盖章电子文件</CardStepTitle>}
            >
                <Space direction="vertical" style={{ width: '100%' }}>
                    {data?.reportData?.examOrgDataReport?.attachmentList?.map((t, i) => <FileLink key={i} {...t} card />) ?? null}
                </Space>
            </ProCard>

            <ProCard
                style={{ marginTop: token.margin }}
                title={<CardStepTitle>缺测替补学生审核明细列表</CardStepTitle>}
                subTitle={<Typography.Text type="warning">右侧学校上报状态为 “已上报” 时才能审核</Typography.Text>}
                extra={data?.reportData?.examOrgDataReport?.status &&
                    <Space>
                        <span>学校上报状态</span>
                        <Tag
                            style={{ marginRight: 0 }}
                            color={dataReportStatusDict[data?.reportData.examOrgDataReport.status].antColor}
                        >
                            {dataReportStatusDict[data?.reportData.examOrgDataReport.status].name}
                        </Tag>
                    </Space>
                }
            >
                <SuperTable<API.ExamAbsentReplaceOutput>
                    actionRef={actionRef}
                    scroll={{ x: 'max-content' }}
                    rowKey="id"
                    columns={detailColumns}
                    search={{
                        filterType: 'light',
                    }}
                    cardProps={false}
                    options={{ setting: false, fullScreen: false }}
                    toolbar={{
                        // title: <CardStepTitle>缺测替补学生明细</CardStepTitle>,
                        // subTitle: <Typography.Text type="danger">右上角上报状态为 “已上报” 时才能审核</Typography.Text>,
                        menu: {
                            type: 'tab',
                            activeKey: activeKey,
                            items: renderTabItems(),
                            onChange: (key) => {
                                setSelectedRowKeys([]);
                                setActiveKey(key as React.Key);
                                actionRef.current?.reload();
                            },
                        },
                        actions: [
                            <Button
                                key="audit"
                                type="primary"
                                icon={<AuditOutlined />}
                                disabled={(selectedRowKeys.length ?? 0) === 0}
                                onClick={() => { setAuditShow({ open: true, ids: selectedRowKeys }); }}
                            >批量审核</Button>
                        ],
                    }}
                    request={async (params, sort) => {
                        return SuperTable.requestPageAgent({ params, sort }, async (p) => {
                            const qparams = {
                                ...p,
                                examPlanId: reqParams.examPlanId,
                                sysOrgId: reqParams.sysOrgId,
                            };
                            await loadCount(qparams);
                            const res = await ExamAbsentReplaceController.queryPageList({
                                ...qparams,
                                status: activeKey !== '0' ? parseInt(activeKey as string) : undefined,
                            });
                            return res;
                        });
                    }}
                    rowSelection={{
                        selectedRowKeys,
                        getCheckboxProps: (r) => {
                            return { disabled: !auditable || ![AuditStatus.AUDIT, AuditStatus.APPROVE_CANCELED].includes(r.status) };
                        },
                        onSelect: (record, selected, selectedRows) => {
                            setSelectedRowKeys(selectedRows.map((t) => t.id) || []);
                        },
                        onSelectAll: (_, selectedRows) => {
                            setSelectedRowKeys(selectedRows.map((t) => t.id) || []);
                        },
                    }}
                    tableAlertOptionRender={({ onCleanSelected }) => {
                        return (<a onClick={() => { setSelectedRowKeys([]); onCleanSelected(); }}>取消选择</a>);
                    }}
                />
            </ProCard>

            {auditShow?.open && auditShow.ids.length > 0 &&
                <AuditModal
                    alert={
                        <Alert
                            type="info"
                            showIcon
                            style={{ marginBottom: token.margin }}
                            message={`本次审核 ${auditShow.ids.length} 个缺测替补学生`}
                        />
                    }
                    title="缺测替补学生审核"
                    onAudit={async (res) => await handleAudit(auditShow.ids, res)}
                    onClose={() => setAuditShow({ open: false, ids: [] })}
                />
            }
            {detailOpen && currentRef.current &&
                <ExamAbsentReplaceDetailDrawer
                    data={currentRef.current}
                    columns={detailColumns as ProDescriptionsItemProps<Partial<API.ExamAbsentReplaceOutput>>[]}
                    onClose={() => setDetailOpen(false)}
                />
            }
        </PageContainer>
    );
}

export default ExamAbsentReplaceAuditOrg;
