import { toValueEnum } from '@/common/converter';
import { MovableModalForm } from '@/components';
import ExamAbsentReplaceController from '@/services/apis/ExamAbsentReplaceController';
import ExamSampleStudentController from '@/services/apis/ExamSampleStudentController';
import { FormInstance, ProFormDependency, ProFormDigit, ProFormRadio, ProFormSelect, ProFormText, ProFormTextArea } from '@ant-design/pro-components';
import { useModel } from '@umijs/max';
import { Alert, App, Col, Row, theme } from 'antd';
import { useRef, useState } from 'react';

export type GradeBranchData = {
    examGrades: API.ExamGradeOutput[];
    branches: API.SysOrgLiteOutput[];
};

/** 修改监测缺测替补学生信息 */
const ExamAbsentReplaceEditModal: React.FC<{
    examPlanId: number;
    data: Partial<API.ExamAbsentReplaceOutput>;
    gradeBranch: GradeBranchData;
    onFinish: () => void;
    onClose?: () => void;
}> = ({ examPlanId, data, gradeBranch, onFinish, onClose }) => {
    const [open, setOpen] = useState<boolean>(true);
    const handleClose = () => { setOpen(false); setTimeout(() => onClose?.(), 300); };

    const formRef = useRef<FormInstance>();
    const { message } = App.useApp();
    const { initialState } = useModel('@@initialState');
    const { currentUser } = initialState ?? {};
    const { token } = theme.useToken();
    const { baseData } = useModel('useBaseData');
    const hasBranch = gradeBranch.branches && gradeBranch.branches.length > 0;

    const handleReset = () => {
        let enPrefix = '';

        const gid = formRef.current?.getFieldValue('examGradeId') ?? 0;
        const grade = gradeBranch.examGrades.find(t => t.id === gid);
        const classNumber = formRef.current?.getFieldValue('classNumber');
        if (currentUser?.sysOrg?.code && grade && classNumber) {
            enPrefix = `${currentUser.sysOrg.code.padStart(3, '0')}${grade.grade.gradeNumber.toString().padStart(2, '0')}${classNumber.toString().padStart(2, '0')}`;
        }

        formRef.current?.setFieldsValue({
            'absentExamNumber': enPrefix,
            'absentName': '',
            'patriarchTel': '',
            'replaceExamNumber': enPrefix,
            'replaceName': '',
        });
    }

    return (
        <MovableModalForm<API.ExamAbsentReplaceOutput & { courseIds: string[] }>
            title={`${data.id === 0 ? '添加' : '修改'}缺测替补学生信息`}
            width={800}
            open={open}
            formRef={formRef}
            initialValues={{
                ...data,
                examGradeId: data.examGradeId !== undefined ? data.examGradeId : undefined,
                sysOrgBranchId: data.sysOrgBranchId !== undefined ? data.sysOrgBranchId : undefined,
                courseIds: (data.absentCourseList?.length ?? 0) > 0 ? data.absentCourseList?.map(t => `${t.id}`) : undefined,
            }}
            modalProps={{
                centered: true,
                maskClosable: false,
                onCancel: () => {
                    formRef?.current?.resetFields();
                    handleClose();
                },
            }}
            onFinish={async (values) => {
                const { examGradeId, courseIds, isReplaced, replaceExamNumber, ...restValues } = values;
                if (values.isReplaced && values.absentExamNumber === values.replaceExamNumber) {
                    message.error('缺测学生监测号不能与替补学生监测号相同');
                    return;
                }
                const grade = gradeBranch.examGrades.find(t => t.id === examGradeId);
                if (!grade) {
                    return;
                }

                const cs = baseData?.courses?.filter(t => courseIds.includes(`${t.id}`))?.map(t => ({ id: t.id, name: t.name, shortName: t.shortName }));

                let p: API.AddExamAbsentReplaceInput = {
                    ...restValues,
                    examPlanId,
                    examGradeId,
                    gradeId: grade.gradeId,
                    absentCourses: JSON.stringify(cs),
                    isReplaced,
                    replaceExamNumber: isReplaced ? replaceExamNumber : '',
                };
                if (data.id !== 0) {
                    const up = { id: data.id ?? 0, ...p } as API.UpdateExamAbsentReplaceInput;
                    await ExamAbsentReplaceController.update(up);
                }
                else {
                    await ExamAbsentReplaceController.add(p);
                }
                message.success('已保存');

                onFinish();
                handleClose();
            }}
        >
            <Alert
                showIcon
                closable
                type="warning"
                message="温馨提示：请先选择年级、校区（若有）、班级，选择后会自动生成监测号前 7 位，输入正确的 11 位监测号后自动填充姓名。"
                style={{ marginBottom: token.margin }}
            />
            <Row gutter={[24, 0]}>
                <Col span={8}>
                    <ProFormSelect
                        label="年级"
                        name="examGradeId"
                        options={gradeBranch?.examGrades?.sort((a, b) => a.grade.gradeNumber - b.grade.gradeNumber)?.map(t => ({ label: `${t.grade.fullName}（${t.gradeBeginName}）`, value: t.id }))}
                        required
                        rules={[{ required: true }]}
                        // disabled={data.id !== 0}
                        fieldProps={{
                            onChange: handleReset,
                        }}
                    />
                </Col>
                {hasBranch &&
                    <Col span={8}>
                        <ProFormSelect
                            label="校区"
                            name="sysOrgBranchId"
                            options={gradeBranch.branches.map(t => ({ label: t.name, value: t.id }))}
                            required
                            rules={[{ required: true }]}
                            fieldProps={{
                                onChange: handleReset,
                            }}
                        />
                    </Col>

                }
                <Col span={8}>
                    <ProFormDigit
                        label="班级"
                        tooltip="班级最小1，最大35"
                        name="classNumber"
                        min={1}
                        max={35}
                        required
                        rules={[{ required: true }]}
                        fieldProps={{
                            onChange: handleReset,
                        }}
                    />
                </Col>
            </Row>
            <Row gutter={[24, 0]}>
                <Col span={8}>
                    <ProFormDependency name={['examGradeId', 'sysOrgBranchId', 'classNumber', 'replaceExamNumber']}>
                        {({ examGradeId, sysOrgBranchId, classNumber, replaceExamNumber }) =>
                            <ProFormText
                                label="缺测学生监测号（11位）"
                                name="absentExamNumber"
                                required
                                rules={[
                                    { required: true, max: 11 },
                                    ({ setFieldsValue }) => ({
                                        validator: async (_, value) => {
                                            const vlen = (value || '').length;
                                            if (vlen === 0 || vlen === 11) {
                                                if (vlen === 11) {
                                                    if (value === replaceExamNumber) {
                                                        return Promise.reject('不能与替补学生监测号相同');
                                                    }
                                                    if (!examGradeId || (hasBranch && !sysOrgBranchId) || !classNumber) {
                                                        return Promise.reject(`请先选择年级、${hasBranch ? '校区、' : ''}班级`);
                                                    }
                                                    const res = await ExamSampleStudentController.queryExamSampleStudent({
                                                        examPlanId,
                                                        examNumber: value,
                                                        examGradeId,
                                                        sysOrgBranchId,
                                                        classNumber
                                                    })
                                                    if (!res) {
                                                        return Promise.reject('监测号无效，未找到相应考试生');
                                                    }
                                                    else {
                                                        setFieldsValue({ 'absentName': res.examStudent?.name });
                                                    }
                                                }
                                                return Promise.resolve();
                                            }
                                            return Promise.reject('请输入11位监测号！');
                                        },
                                    }),
                                ]}
                                fieldProps={{
                                    maxLength: 11,
                                    showCount: true,
                                }}
                            />
                        }
                    </ProFormDependency>
                </Col>
                <Col span={8}>
                    <ProFormText
                        label="缺测学生姓名"
                        name="absentName"
                        // readonly
                        required
                        rules={[{ required: true, min: 2, max: 100 }]}
                        fieldProps={{
                            minLength: 2,
                            maxLength: 100,
                            showCount: true,
                        }}
                    />
                </Col>
                <Col span={8}>
                    <ProFormText
                        label="缺测学生家长电话"
                        name="patriarchTel"
                        fieldProps={{
                            maxLength: 50,
                            showCount: true
                        }}
                        required
                        rules={[{ required: true, min: 8 }]}
                    />
                </Col>
                <Col span={8}>
                    <ProFormRadio.Group
                        label="是否有填补学生"
                        name="isReplaced"
                        options={[{ label: '有', value: true }, { label: '无', value: false }]}
                        required
                        rules={[{ required: true }]}
                    />
                </Col>
                <ProFormDependency name={['isReplaced', 'examGradeId', 'sysOrgBranchId', 'classNumber', 'absentExamNumber']}>
                    {({ isReplaced, examGradeId, sysOrgBranchId, classNumber, absentExamNumber }) =>
                        <>
                            <Col span={8}>
                                <ProFormText
                                    label="替补学生监测号（11位）"
                                    name="replaceExamNumber"
                                    required={isReplaced}
                                    disabled={!isReplaced}
                                    rules={isReplaced ? [
                                        { required: true, max: 11 },
                                        ({ setFieldsValue }) => ({
                                            validator: async (_, value) => {
                                                const vlen = (value || '').length;
                                                if (vlen === 0 || vlen === 11) {
                                                    if (vlen === 11) {
                                                        if (value === absentExamNumber) {
                                                            return Promise.reject('不能与缺测学生监测号相同');
                                                        }
                                                        if (!examGradeId || (hasBranch && !sysOrgBranchId) || !classNumber) {
                                                            return Promise.reject(`请先选择年级、${hasBranch ? '校区、' : ''}班级`);
                                                        }
                                                        const res = await ExamSampleStudentController.queryExamSampleStudent({
                                                            examPlanId,
                                                            examNumber: value,
                                                            examGradeId,
                                                            sysOrgBranchId,
                                                            classNumber,
                                                        });
                                                        if (!res) {
                                                            return Promise.reject('监测号无效，未找到相应考试生');
                                                        }
                                                        else {
                                                            setFieldsValue({ 'replaceName': res.examStudent?.name });
                                                        }
                                                    }
                                                    return Promise.resolve();
                                                }
                                                return Promise.reject('请输入11位监测号！');
                                            },
                                        }),
                                    ] : []}
                                    fieldProps={{
                                        maxLength: 11,
                                        showCount: true,
                                    }}
                                />

                            </Col>
                            <Col span={8}>
                                <ProFormText
                                    label="替补学生姓名"
                                    name="replaceName"
                                    required={isReplaced}
                                    disabled={!isReplaced}
                                    rules={isReplaced ? [{ required: true, min: 2, max: 100 }] : []}
                                    fieldProps={{
                                        minLength: 2,
                                        maxLength: 100,
                                        showCount: true,
                                    }}
                                />
                            </Col>
                        </>
                    }
                </ProFormDependency>
                <Col span={24}>
                    <ProFormDependency name={['examGradeId']}>
                        {({ examGradeId }) =>
                            <ProFormSelect
                                label="缺测科目"
                                name="courseIds"
                                mode="multiple"
                                disabled={!examGradeId}
                                // valueEnum={toValueEnum(baseData?.courses ?? [])}
                                valueEnum={toValueEnum(gradeBranch?.examGrades?.find(t => t.id === examGradeId)?.examCourses?.map(t => t.course) ?? [])}
                                required
                                rules={[{ required: true }]}
                            />
                        }
                    </ProFormDependency>
                </Col>
                <Col span={24}>
                    <ProFormTextArea
                        label="缺测原因"
                        name="absentReason"
                        fieldProps={{
                            maxLength: 200,
                            rows: 2,
                            showCount: true,
                        }}
                        required
                        rules={[{ required: true }]}
                    />
                </Col>
            </Row>

            <ProFormTextArea
                label="备注"
                name="remark"
                fieldProps={{
                    maxLength: 200,
                    rows: 2,
                    showCount: true,
                }}
            />
        </MovableModalForm >
    );
};

export default ExamAbsentReplaceEditModal;
