import { toValueEnum } from '@/common/converter';
import { validateIdCard } from '@/common/validator';
import { MovableModalForm } from '@/components';
import ExamStudentController from '@/services/apis/ExamStudentController';
import { CertificateType } from '@/services/enums';
import { FormInstance, ProFormDigit, ProFormRadio, ProFormSelect, ProFormText, ProFormTextArea } from '@ant-design/pro-components';
import { useModel } from '@umijs/max';
import { App, Col, Row } from 'antd';
import { useEffect, useRef, useState } from 'react';

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

/** 修改监测学生信息 */
const ExamStudentEditModal: React.FC<{
    examPlanId: number;
    data: Partial<API.ExamStudentOutput>;
    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 { getDictValueEnum, } = useModel('useDict');
    const { baseData } = useModel('useBaseData');

    const [certType, setCertType] = useState(data.certificateType);
    const [grade, setGrade] = useState<API.ExamGradeOutput>();

    useEffect(() => {
        if (!data.examGradeId) {
            return;
        }
        const g = gradeBranch?.examGrades.find(t => t.id === data.examGradeId);
        setGrade(g);
    }, []);

    return (
        <>
            <MovableModalForm<API.ExamStudentOutput>
                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,
                    certificateType: data.certificateType !== undefined ? `${data.certificateType}` : undefined,
                    gender: data.gender !== undefined ? `${data.gender}` : undefined,
                    nceeCourseCombId: data.nceeCourseCombId !== undefined ? `${data.nceeCourseCombId}` : undefined,
                }}
                modalProps={{
                    centered: true,
                    maskClosable: false,
                    onCancel: () => {
                        formRef?.current?.resetFields();
                        handleClose();
                    },
                }}
                onFinish={async (values) => {
                    const { examGradeId, certificateType, gender, ...restValues } = values;
                    const grade = gradeBranch.examGrades.find(t => t.id === examGradeId);
                    if (!grade) {
                        return;
                    }

                    let p: API.AddExamStudentInput = {
                        ...restValues,
                        examPlanId,
                        examGradeId,
                        gradeId: grade.gradeId,
                        certificateType: JSON.parse(certificateType as any),
                        gender: JSON.parse(gender as any),
                    };
                    if (data.id !== '0') {
                        const up = { id: data.id ?? 0, ...p } as API.UpdateExamStudentInput;
                        await ExamStudentController.update(up);
                    }
                    else {
                        await ExamStudentController.add(p);
                    }
                    message.success('已保存');

                    onFinish();
                    handleClose();
                }}
            >
                <Row gutter={[24, 0]}>
                    <Col span={12}>
                        <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'}
                            onChange={(e: number) => {
                                const g = gradeBranch?.examGrades.find(t => t.id === e);
                                setGrade(g);
                                formRef.current?.validateFields(['examNumber']);
                            }}
                        />
                    </Col>
                    {gradeBranch.branches && gradeBranch.branches.length > 0 &&
                        <Col span={12}>
                            <ProFormSelect
                                label="校区"
                                name="sysOrgBranchId"
                                options={gradeBranch.branches.map(t => ({ label: t.name, value: t.id }))}
                                required
                                disabled={data.id !== '0'}
                                rules={[{ required: true }]}
                            />
                        </Col>
                    }
                    <Col span={12}>
                        <ProFormDigit
                            label="班级"
                            tooltip="班级最小1，最大35"
                            name="classNumber"
                            min={1}
                            max={35}
                            required
                            rules={[{ required: true }]}
                        />
                    </Col>
                    <Col span={12}>
                        <ProFormText
                            label="姓名"
                            name="name"
                            required
                            rules={[{ required: true, min: 2, max: 100 }]}
                            fieldProps={{
                                minLength: 2,
                                maxLength: 100,
                                showCount: true,
                            }}
                        />
                    </Col>
                    <Col span={12}>
                        <ProFormSelect
                            label="证件类型"
                            name="certificateType"
                            rules={[{ required: true }]}
                            valueEnum={getDictValueEnum('certificate_type')}
                            onChange={(v) => setCertType(JSON.parse(v as string))}
                        />
                    </Col>
                    <Col span={12}>
                        <ProFormText
                            label="证件号码"
                            name="idNumber"
                            dependencies={['certificateType']}
                            fieldProps={{
                                maxLength: 18,
                                showCount: true,
                            }}
                            required={certType !== CertificateType.NONE}
                            rules={[
                                ({ getFieldValue, setFieldsValue }) => ({
                                    validator: (_, value) => {
                                        const ct = JSON.parse(getFieldValue("certificateType"));
                                        if (ct === CertificateType.NONE) {
                                            return Promise.resolve();
                                        }
                                        if (ct === CertificateType.ID_CARD) {
                                            const idc = validateIdCard(value);
                                            if (idc.success) {
                                                setFieldsValue({ gender: `${idc.gender}` });
                                                return Promise.resolve();
                                            }
                                            else {
                                                return Promise.reject(`身份证号${idc.errorMessage}有误`);
                                            }
                                        }
                                        if (value.length > 0) {
                                            return Promise.resolve();
                                        }
                                        return Promise.reject('证件号码必须输入');
                                    },
                                }),
                            ]}
                        />
                    </Col>
                    <Col span={12}>
                        <ProFormRadio.Group
                            label="性别"
                            name="gender"
                            valueEnum={getDictValueEnum('gender')}
                            required
                            rules={[{ required: true }]}
                        />
                    </Col>
                    <Col span={12}>
                        <ProFormText
                            // label="自编监测号"
                            label={`自编监测号${grade?.isRequiredSelfExamNumber ? `（当前年级必录，长度为${grade?.selfExamNumberLength}位）` : ''}`}
                            name="examNumber"
                            // tooltip="仅有明确要求时填写"
                            fieldProps={{
                                maxLength: grade?.isRequiredSelfExamNumber ? grade?.selfExamNumberLength : 20,
                                showCount: true
                            }}
                            required={grade?.isRequiredSelfExamNumber}
                            rules={[
                                () => ({
                                    validator: (_, value) => {
                                        if (!grade?.isRequiredSelfExamNumber) {
                                            return Promise.resolve();
                                        }
                                        if ((value ?? '').length !== grade?.selfExamNumberLength) {
                                            return Promise.reject(`当前年级必录，长度为${grade?.selfExamNumberLength}位`);
                                        }
                                        return Promise.resolve();
                                    },
                                }),
                            ]}
                        />
                    </Col>
                    {gradeBranch.hasNceeCourseComb &&
                        <Col span={12}>
                            <ProFormSelect
                                label="选科组合"
                                name="nceeCourseCombId"
                                tooltip="仅高中学段填写"
                                valueEnum={toValueEnum(baseData?.nceeCourseCombs?.map(t => ({ id: t.id, name: t.shortName })) ?? [])}
                            />
                        </Col>
                    }
                    <Col span={12}>
                        <ProFormText
                            label="考场号"
                            name="roomNumber"
                            fieldProps={{
                                maxLength: 20,
                                showCount: true
                            }}
                        />
                    </Col>
                    <Col span={12}>
                        <ProFormText
                            label="座位号"
                            name="seatNumber"
                            fieldProps={{
                                maxLength: 20,
                                showCount: true
                            }}
                        />
                    </Col>
                </Row>
                <ProFormTextArea
                    label="备注"
                    name="remark"
                    fieldProps={{
                        maxLength: 200,
                        rows: 4,
                        showCount: true,
                    }}
                />
            </MovableModalForm >
        </>
    );
};

export default ExamStudentEditModal;
