import React, { useEffect, useState, useCallback, useMemo } from 'react';
import {
  Tabs,
  Card,
  Descriptions,
  Table,
  Button,
  Modal,
  Form,
  Input,
  Select,
  DatePicker,
  InputNumber,
  Upload,
  Tag,
  Space,
  Popconfirm,
  Empty,
  Row,
  Col,
  Statistic,
  Spin,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import {
  PlusOutlined,
  UploadOutlined,
  InboxOutlined,
  EyeOutlined,
  CloseOutlined,
  FileTextOutlined,
  ReloadOutlined,
} from '@ant-design/icons';
import dayjs from 'dayjs';
import api from '../../api';
import { maskPhone, maskIdNumber } from '../../utils/sensitive';
import { useViewSensitive } from '../../hooks/useViewSensitive';
import { message } from '../../ui/app-message';
import EditableCell from '../EditableCell';

// ---- Types ----

interface StudentInfo {
  id: number;
  name: string;
  phone: string;
  idNumber: string;
  studentNo: string;
  gender?: string;
  ethnicity?: string;
  emergencyContact?: string;
  emergencyPhone?: string;
  organizationId?: number;
  organization?: { id?: number; name?: string } | null;
  supervisor?: string;
  status: string;
}

interface ProfileData {
  targetCollege?: string;
  targetMajor?: string;
  collegeSchool?: string;
  collegeMajor?: string;
  subjectDirection?: string;
  grade?: string;
  profileDate?: string;
  notes?: string;
}

interface EnrollmentRecord {
  id: number;
  courseCategory: string;
  classType: string;
  className?: string;
  headTeacher?: string;
  subjectTeacher?: string;
  startDate?: string;
  endDate?: string;
  status: string;
}

interface ExamScoreRecord {
  id: number;
  examId?: number;
  exam?: { class?: { name?: string } };
  examType: string;
  examName?: string;
  subject: string;
  score: number | null;
  classAvg?: number;
  rank?: number;
  examDate?: string;
  enrollmentId?: number;
}

interface LearningRecord {
  id: number;
  recordDate: string;
  recordType: string;
  content: string;
  followUpMethod?: string;
  nextStep?: string;
}

interface ResultData {
  cultureFinalScore?: number;
  professionalFinalScore?: number;
  admissionStatus?: string;
  admittedCollege?: string;
  admittedMajor?: string;
}

interface AttachmentRecord {
  id: number;
  category: string;
  fileName: string;
  fileSize: number;
}

interface AttendanceRecordItem {
  id: number;
  attendanceDate: string;
  session: string;
  status: string;
  source?: string;
  remark?: string | null;
  punchTime?: string | null;
  punchDeviceName?: string | null;
  punchDeviceId?: string | null;
  schedule?: { subject?: string } | null;
  class?: { name?: string } | null;
}

interface StudentProfileAggregate {
  student: StudentInfo;
  profile: ProfileData | null;
  enrollments: EnrollmentRecord[];
  examScores: ExamScoreRecord[];
  learningRecords: LearningRecord[];
  result: ResultData | null;
  attachments: AttachmentRecord[];
  attendances: AttendanceRecordItem[];
}

export interface StudentProfileContentProps {
  studentId: number;
  inDrawer?: boolean;
  onClose?: () => void;
}

// ---- Constants ----

const ADMISSION_STATUS_MAP: Record<string, { text: string; color: string }> = {
  admitted: { text: '已录取', color: 'green' },
  pending: { text: '待录取', color: 'orange' },
  rejected: { text: '未录取', color: 'red' },
  withdrawn: { text: '放弃', color: '#999' },
};

const EXAM_TYPE_OPTIONS = [
  { value: 'monthly', label: '月考' },
  { value: 'midterm', label: '期中' },
  { value: 'final', label: '期末' },
  { value: 'mock', label: '模拟考' },
  { value: 'entrance', label: '入学测试' },
  { value: 'other', label: '其他' },
];

const RECORD_TYPE_OPTIONS = [
  { value: 'study_feedback', label: '学习反馈' },
  { value: 'parent_communication', label: '家长沟通' },
  { value: 'behavior_note', label: '行为记录' },
  { value: 'meeting', label: '会议记录' },
  { value: 'other', label: '其他' },
];

const ENROLLMENT_STATUS_MAP: Record<string, { text: string; color: string }> = {
  active: { text: '报读中', color: 'green' },
  completed: { text: '已结课', color: 'blue' },
  withdrawn: { text: '已退训', color: 'red' },
};

const COURSE_CATEGORY_OPTIONS = [
  { value: 'culture', label: '文化课' },
  { value: 'professional', label: '专业课' },
  { value: 'comprehensive', label: '综合' },
];

const CLASS_TYPE_OPTIONS = [
  { value: 'one_on_one', label: '一对一' },
  { value: 'small_group', label: '小班' },
  { value: 'large_class', label: '大班' },
  { value: 'online', label: '线上' },
  { value: 'offline', label: '线下' },
];

const getOptionLabel = (
  options: Array<{ value: string; label: string }>,
  value?: string | null,
): string => {
  if (!value) return '-';
  return options.find((option) => option.value === value)?.label || value;
};

const getCourseCategoryLabel = (value?: string | null): string =>
  getOptionLabel(COURSE_CATEGORY_OPTIONS, value);

const getClassTypeLabel = (value?: string | null): string =>
  getOptionLabel(CLASS_TYPE_OPTIONS, value);

const getEnrollmentStatus = (value?: string | null): { text: string; color: string } => {
  if (!value) return { text: '-', color: 'default' };
  return ENROLLMENT_STATUS_MAP[value] || { text: value, color: 'default' };
};

const formatEnrollmentDisplayName = (enrollment: EnrollmentRecord): string =>
  enrollment.className ||
  (enrollment.courseCategory
    ? getCourseCategoryLabel(enrollment.courseCategory)
    : String(enrollment.id));

const ATTACHMENT_CATEGORY_OPTIONS = [
  { value: 'id_card', label: '身份证' },
  { value: 'transcript', label: '成绩单' },
  { value: 'certificate', label: '证书' },
  { value: 'contract', label: '合同' },
  { value: 'photo', label: '照片' },
  { value: 'other', label: '其他' },
];

const formatFileSize = (bytes: number): string => {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
};

// ---- Tab Components ----

const ATTENDANCE_STATUS_MAP: Record<string, { text: string; color: string }> = {
  present: { text: '出勤', color: 'green' },
  late: { text: '迟到', color: 'orange' },
  absent: { text: '缺勤', color: 'red' },
  leave: { text: '请假', color: 'blue' },
  pending: { text: '待确认', color: 'default' },
};

const SESSION_LABELS: Record<string, string> = {
  morning_reading: '早自习',
  morning: '上午',
  afternoon: '下午',
  evening_study: '晚自习',
  night_check: '晚寝',
};

const AttendanceTab: React.FC<{ data: AttendanceRecordItem[] }> = ({ data }) => {
  const columns: ColumnsType<AttendanceRecordItem> = [
    { title: '日期', dataIndex: 'attendanceDate', width: 120 },
    {
      title: '课程',
      render: (_: unknown, record) => record.schedule?.subject || record.class?.name || '课程考勤',
    },
    {
      title: '时段',
      dataIndex: 'session',
      width: 100,
      render: (value: string) => SESSION_LABELS[value] || value || '-',
    },
    {
      title: '结果',
      dataIndex: 'status',
      width: 90,
      render: (value: string) => {
        const meta = ATTENDANCE_STATUS_MAP[value] || { text: value || '-', color: 'default' };
        return <Tag color={meta.color}>{meta.text}</Tag>;
      },
    },
    {
      title: '打卡时间',
      dataIndex: 'punchTime',
      width: 170,
      render: (value?: string | null) => (value ? dayjs(value).format('YYYY-MM-DD HH:mm:ss') : '-'),
    },
    {
      title: '打卡设备',
      render: (_: unknown, record) => {
        const name = record.punchDeviceName?.trim();
        const id = record.punchDeviceId?.trim();
        if (name && id && name !== id) return `${name}（${id}）`;
        return name || id || (record.source === 'manual' ? '老师手动标记' : '-');
      },
    },
    { title: '备注', dataIndex: 'remark', render: (value?: string | null) => value || '-' },
  ];

  return data.length > 0 ? (
    <Table<AttendanceRecordItem>
      columns={columns}
      dataSource={data}
      rowKey="id"
      scroll={{ x: 900 }}
      pagination={{ defaultPageSize: 15, showSizeChanger: true, pageSizeOptions: [15, 30, 50] }}
    />
  ) : (
    <Empty description="暂无出勤记录" />
  );
};

interface TabProps {
  studentId: number;
  onRefresh: () => void;
}

const InlineArchiveSummary: React.FC<{
  studentId: number;
  student: StudentInfo;
  profile: ProfileData | null;
  result: ResultData | null;
  organizations: Array<{ id: number; name: string }>;
  onRefresh: () => void;
  onViewSensitive: (fieldLabel: string, value: string) => void;
}> = ({ studentId, student, profile, result, organizations, onRefresh, onViewSensitive }) => {
  const saveStudent = async (field: keyof StudentInfo, value: unknown) => {
    await api.put(`/students/${studentId}`, { [field]: value });
    message.success('学生资料已保存');
    onRefresh();
  };

  const saveProfile = async (field: keyof ProfileData, value: unknown) => {
    await api.put(`/archive/${studentId}/profile`, { [field]: value });
    message.success('档案已保存');
    onRefresh();
  };

  const saveResult = async (field: keyof ResultData, value: unknown) => {
    await api.put(`/archive/${studentId}/result`, { [field]: value });
    message.success('录取信息已保存');
    onRefresh();
  };

  const admissionStatus = getOptionLabel(
    Object.entries(ADMISSION_STATUS_MAP).map(([value, meta]) => ({
      value,
      label: meta.text,
    })),
    result?.admissionStatus,
  );

  return (
    <Descriptions bordered column={3} size="small" style={{ marginBottom: 24 }}>
      <Descriptions.Item label="手机号">
        <EditableCell
          value={student.phone}
          permission="student:edit"
          onSave={(next) => saveStudent('phone', next)}
        >
          {student.phone ? (
            <span>
              <span style={{ marginRight: 8 }}>{maskPhone(student.phone)}</span>
              <a onClick={() => onViewSensitive('电话', student.phone)}>
                <EyeOutlined style={{ fontSize: 12, color: '#999' }} />
              </a>
            </span>
          ) : (
            '-'
          )}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="姓名">
        <EditableCell
          value={student.name}
          permission="student:edit"
          required
          onSave={(next) => saveStudent('name', next)}
        >
          {student.name || '-'}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="学号">
        <EditableCell
          value={student.studentNo}
          permission="student:edit"
          onSave={(next) => saveStudent('studentNo', next)}
        >
          {student.studentNo || '-'}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="性别">
        <EditableCell
          value={student.gender}
          permission="student:edit"
          onSave={(next) => saveStudent('gender', next)}
        >
          {student.gender || '-'}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="身份证号">
        <EditableCell
          value={student.idNumber}
          permission="student:edit"
          onSave={(next) => saveStudent('idNumber', next)}
        >
          {student.idNumber ? (
            <span>
              <span style={{ marginRight: 8 }}>{maskIdNumber(student.idNumber)}</span>
              <a onClick={() => onViewSensitive('身份证号', student.idNumber)}>
                <EyeOutlined style={{ fontSize: 12, color: '#999' }} />
              </a>
            </span>
          ) : (
            '-'
          )}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="民族">
        <EditableCell
          value={student.ethnicity}
          permission="student:edit"
          onSave={(next) => saveStudent('ethnicity', next)}
        >
          {student.ethnicity || '-'}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="紧急联系人">
        <EditableCell
          value={student.emergencyContact}
          permission="student:edit"
          onSave={(next) => saveStudent('emergencyContact', next)}
        >
          {student.emergencyContact || '-'}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="紧急联系人电话">
        <EditableCell
          value={student.emergencyPhone}
          permission="student:edit"
          onSave={(next) => saveStudent('emergencyPhone', next)}
        >
          {student.emergencyPhone ? (
            <span>
              <span style={{ marginRight: 8 }}>{maskPhone(student.emergencyPhone)}</span>
              <a onClick={() => onViewSensitive('紧急联系人电话', student.emergencyPhone || '')}>
                <EyeOutlined style={{ fontSize: 12, color: '#999' }} />
              </a>
            </span>
          ) : (
            '-'
          )}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="所属机构">
        <EditableCell
          value={student.organizationId}
          editor="select"
          options={organizations.map((item) => ({ value: item.id, label: item.name }))}
          permission="student:edit"
          onSave={(next) => saveStudent('organizationId', next)}
        >
          {student.organization?.name ? <Tag color="purple">{student.organization.name}</Tag> : '-'}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="负责人">
        <EditableCell
          value={student.supervisor}
          permission="student:edit"
          onSave={(next) => saveStudent('supervisor', next)}
        >
          {student.supervisor || '-'}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="目标院校">
        <EditableCell
          value={profile?.targetCollege}
          permission="student:edit"
          onSave={(next) => saveProfile('targetCollege', next)}
        >
          {profile?.targetCollege || '-'}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="目标专业">
        <EditableCell
          value={profile?.targetMajor}
          permission="student:edit"
          onSave={(next) => saveProfile('targetMajor', next)}
        >
          {profile?.targetMajor || '-'}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="大专院校">
        <EditableCell
          value={profile?.collegeSchool}
          permission="student:edit"
          onSave={(next) => saveProfile('collegeSchool', next)}
        >
          {profile?.collegeSchool || '-'}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="大专专业">
        <EditableCell
          value={profile?.collegeMajor}
          permission="student:edit"
          onSave={(next) => saveProfile('collegeMajor', next)}
        >
          {profile?.collegeMajor || '-'}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="选科方向">
        <EditableCell
          value={profile?.subjectDirection}
          permission="student:edit"
          onSave={(next) => saveProfile('subjectDirection', next)}
        >
          {profile?.subjectDirection || '-'}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="年级">
        <EditableCell
          value={profile?.grade}
          permission="student:edit"
          onSave={(next) => saveProfile('grade', next)}
        >
          {profile?.grade || '-'}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="建档日期">
        <EditableCell
          value={profile?.profileDate}
          editor="date"
          permission="student:edit"
          onSave={(next) => saveProfile('profileDate', next)}
        >
          {profile?.profileDate || '-'}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="档案备注">
        <EditableCell
          value={profile?.notes}
          editor="textarea"
          permission="student:edit"
          onSave={(next) => saveProfile('notes', next)}
        >
          {profile?.notes || '-'}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="文化课最终分">
        <EditableCell
          value={result?.cultureFinalScore}
          editor="number"
          min={0}
          permission="student:edit"
          onSave={(next) => saveResult('cultureFinalScore', next)}
        >
          {result?.cultureFinalScore ?? '-'}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="专业课最终分">
        <EditableCell
          value={result?.professionalFinalScore}
          editor="number"
          min={0}
          permission="student:edit"
          onSave={(next) => saveResult('professionalFinalScore', next)}
        >
          {result?.professionalFinalScore ?? '-'}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="录取状态">
        <EditableCell
          value={result?.admissionStatus}
          editor="select"
          options={Object.entries(ADMISSION_STATUS_MAP).map(([value, meta]) => ({
            value,
            label: meta.text,
          }))}
          permission="student:edit"
          onSave={(next) => saveResult('admissionStatus', next)}
        >
          {admissionStatus}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="录取院校">
        <EditableCell
          value={result?.admittedCollege}
          permission="student:edit"
          onSave={(next) => saveResult('admittedCollege', next)}
        >
          {result?.admittedCollege || '-'}
        </EditableCell>
      </Descriptions.Item>
      <Descriptions.Item label="录取专业">
        <EditableCell
          value={result?.admittedMajor}
          permission="student:edit"
          onSave={(next) => saveResult('admittedMajor', next)}
        >
          {result?.admittedMajor || '-'}
        </EditableCell>
      </Descriptions.Item>
    </Descriptions>
  );
};

const EnrollmentsTab: React.FC<TabProps & { data: EnrollmentRecord[] }> = ({
  data,
  studentId,
  onRefresh,
}) => {
  const [modalOpen, setModalOpen] = useState(false);
  const [form] = Form.useForm();
  const [saving, setSaving] = useState(false);

  const handleAdd = async () => {
    try {
      const values = await form.validateFields();
      setSaving(true);
      await api.post(`/archive/${studentId}/enrollments`, {
        ...values,
        startDate: values.startDate?.format('YYYY-MM-DD'),
        endDate: values.endDate?.format('YYYY-MM-DD'),
      });
      message.success('报读记录已添加');
      setModalOpen(false);
      form.resetFields();
      onRefresh();
    } catch (e: unknown) {
      const err = e as { message?: string };
      if (err?.message) message.error(err.message);
    } finally {
      setSaving(false);
    }
  };

  const saveCell = async (record: EnrollmentRecord, field: string, value: unknown) => {
    await api.put(`/archive/enrollments/${record.id}`, { [field]: value });
    message.success('报读记录已保存');
    onRefresh();
  };

  const columns: ColumnsType<EnrollmentRecord> = [
    {
      title: '课程类别',
      dataIndex: 'courseCategory',
      render: (v: string, r) => (
        <EditableCell
          value={v}
          editor="select"
          options={COURSE_CATEGORY_OPTIONS}
          permission="student:edit"
          required
          onSave={(next) => saveCell(r, 'courseCategory', next)}
        >
          {getCourseCategoryLabel(v)}
        </EditableCell>
      ),
    },
    {
      title: '班型',
      dataIndex: 'classType',
      render: (v: string, r) => (
        <EditableCell
          value={v}
          editor="select"
          options={CLASS_TYPE_OPTIONS}
          permission="student:edit"
          required
          onSave={(next) => saveCell(r, 'classType', next)}
        >
          {getClassTypeLabel(v)}
        </EditableCell>
      ),
    },
    {
      title: '班级名称',
      dataIndex: 'className',
      render: (v: string, r) => (
        <EditableCell
          value={v}
          permission="student:edit"
          onSave={(next) => saveCell(r, 'className', next)}
        >
          {v || '-'}
        </EditableCell>
      ),
    },
    {
      title: '班主任',
      dataIndex: 'headTeacher',
      render: (v: string, r) => (
        <EditableCell
          value={v}
          permission="student:edit"
          onSave={(next) => saveCell(r, 'headTeacher', next)}
        >
          {v || '-'}
        </EditableCell>
      ),
    },
    {
      title: '任课教师',
      dataIndex: 'subjectTeacher',
      render: (v: string, r) => (
        <EditableCell
          value={v}
          permission="student:edit"
          onSave={(next) => saveCell(r, 'subjectTeacher', next)}
        >
          {v || '-'}
        </EditableCell>
      ),
    },
    {
      title: '开始日期',
      dataIndex: 'startDate',
      render: (v: string, r) => (
        <EditableCell
          value={v}
          editor="date"
          permission="student:edit"
          onSave={(next) => saveCell(r, 'startDate', next)}
        >
          {v || '-'}
        </EditableCell>
      ),
    },
    {
      title: '结束日期',
      dataIndex: 'endDate',
      render: (v: string, r) => (
        <EditableCell
          value={v}
          editor="date"
          permission="student:edit"
          onSave={(next) => saveCell(r, 'endDate', next)}
        >
          {v || '-'}
        </EditableCell>
      ),
    },
    {
      title: '状态',
      dataIndex: 'status',
      render: (v: string, r) => {
        const status = getEnrollmentStatus(v);
        return (
          <EditableCell
            value={v}
            editor="select"
            options={Object.entries(ENROLLMENT_STATUS_MAP).map(([value, item]) => ({
              value,
              label: item.text,
            }))}
            permission="student:edit"
            onSave={(next) => saveCell(r, 'status', next)}
          >
            <Tag color={status.color}>{status.text}</Tag>
          </EditableCell>
        );
      },
    },
  ];

  return (
    <div>
      <Button
        icon={<PlusOutlined />}
        type="primary"
        onClick={() => {
          form.resetFields();
          setModalOpen(true);
        }}
        style={{ marginBottom: 16 }}
      >
        添加报读记录
      </Button>
      <Table<EnrollmentRecord>
        columns={columns}
        dataSource={data}
        rowKey="id"
        pagination={{
          defaultPageSize: 15,
          showSizeChanger: true,
          pageSizeOptions: [15, 30, 50],
        }}
      />
      <Modal
        title="添加报读记录"
        open={modalOpen}
        onOk={handleAdd}
        onCancel={() => setModalOpen(false)}
        confirmLoading={saving}
      >
        <Form form={form} layout="vertical">
          <Form.Item
            name="courseCategory"
            label="课程类别"
            rules={[{ required: true, message: '请选择课程类别' }]}
          >
            <Select options={COURSE_CATEGORY_OPTIONS} placeholder="请选择" />
          </Form.Item>
          <Form.Item
            name="classType"
            label="班型"
            rules={[{ required: true, message: '请选择班型' }]}
          >
            <Select options={CLASS_TYPE_OPTIONS} placeholder="请选择" />
          </Form.Item>
          <Form.Item name="className" label="班级名称">
            <Input placeholder="如：2024届冲刺班" />
          </Form.Item>
          <Form.Item name="headTeacher" label="班主任">
            <Input placeholder="班主任姓名" />
          </Form.Item>
          <Form.Item name="subjectTeacher" label="任课教师">
            <Input placeholder="任课教师姓名" />
          </Form.Item>
          <Form.Item name="startDate" label="开始日期">
            <DatePicker style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="endDate" label="结束日期">
            <DatePicker style={{ width: '100%' }} />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

const ExamScoresTab: React.FC<
  TabProps & { data: ExamScoreRecord[]; enrollments: EnrollmentRecord[] }
> = ({ data, studentId, enrollments, onRefresh }) => {
  const [modalOpen, setModalOpen] = useState(false);
  const [form] = Form.useForm();
  const [saving, setSaving] = useState(false);

  const handleAdd = async () => {
    try {
      const values = await form.validateFields();
      setSaving(true);
      await api.post(`/archive/${studentId}/exam-scores`, {
        ...values,
        examDate: values.examDate?.format('YYYY-MM-DD'),
      });
      message.success('考试成绩已添加');
      setModalOpen(false);
      form.resetFields();
      onRefresh();
    } catch (e: unknown) {
      const err = e as { message?: string };
      if (err?.message) message.error(err.message);
    } finally {
      setSaving(false);
    }
  };

  const saveCell = async (record: ExamScoreRecord, field: string, value: unknown) => {
    await api.put(`/archive/exam-scores/${record.id}`, { [field]: value });
    message.success('考试成绩已保存');
    onRefresh();
  };

  const columns: ColumnsType<ExamScoreRecord> = [
    {
      title: '考试类型',
      dataIndex: 'examType',
      render: (v: string, r) => (
        <EditableCell
          value={v}
          editor="select"
          options={EXAM_TYPE_OPTIONS}
          permission="student:edit"
          disabled={!!r.examId}
          required
          onSave={(next) => saveCell(r, 'examType', next)}
        >
          {EXAM_TYPE_OPTIONS.find((o) => o.value === v)?.label || v}
        </EditableCell>
      ),
    },
    {
      title: '考试名称',
      dataIndex: 'examName',
      render: (v: string, r) => (
        <EditableCell
          value={v}
          permission="student:edit"
          disabled={!!r.examId}
          onSave={(next) => saveCell(r, 'examName', next)}
        >
          {v || '-'}
        </EditableCell>
      ),
    },
    {
      title: '科目',
      dataIndex: 'subject',
      render: (v: string, r) => (
        <EditableCell
          value={v}
          required
          permission="student:edit"
          disabled={!!r.examId}
          onSave={(next) => saveCell(r, 'subject', next)}
        >
          {v}
        </EditableCell>
      ),
    },
    {
      title: '成绩',
      dataIndex: 'score',
      render: (v: number | null, r) => (
        <EditableCell
          value={v ?? undefined}
          editor="number"
          min={0}
          permission="student:edit"
          disabled={!!r.examId}
          onSave={(next) => saveCell(r, 'score', next)}
        >
          {v ?? '-'}
        </EditableCell>
      ),
    },
    {
      title: '班级均分',
      dataIndex: 'classAvg',
      render: (v: number | undefined, r) => (
        <EditableCell
          value={v}
          editor="number"
          min={0}
          permission="student:edit"
          disabled={!!r.examId}
          onSave={(next) => saveCell(r, 'classAvg', next)}
        >
          {v !== undefined ? v : '-'}
        </EditableCell>
      ),
    },
    {
      title: '排名',
      dataIndex: 'rank',
      render: (v: number | undefined, r) => (
        <EditableCell
          value={v}
          editor="number"
          min={1}
          permission="student:edit"
          disabled={!!r.examId}
          onSave={(next) => saveCell(r, 'rank', next)}
        >
          {v !== undefined ? v : '-'}
        </EditableCell>
      ),
    },
    {
      title: '考试日期',
      dataIndex: 'examDate',
      render: (v: string, r) => (
        <EditableCell
          value={v}
          editor="date"
          permission="student:edit"
          disabled={!!r.examId}
          onSave={(next) => saveCell(r, 'examDate', next)}
        >
          {v || '-'}
        </EditableCell>
      ),
    },
    {
      title: '关联报读',
      dataIndex: 'enrollmentId',
      render: (v: number | undefined, r) => (
        <EditableCell
          value={v}
          editor="select"
          options={enrollments.map((item) => ({
            value: item.id,
            label: formatEnrollmentDisplayName(item),
          }))}
          permission="student:edit"
          disabled={!!r.examId}
          onSave={(next) => saveCell(r, 'enrollmentId', next)}
        >
          {(() => {
            if (r.examId) return r.exam?.class?.name || '-';
            if (v === undefined) return '-';
            const enr = enrollments.find((e) => e.id === v);
            return enr ? formatEnrollmentDisplayName(enr) : String(v);
          })()}
        </EditableCell>
      ),
    },
  ];

  return (
    <div>
      <Button
        icon={<PlusOutlined />}
        type="primary"
        onClick={() => {
          form.resetFields();
          setModalOpen(true);
        }}
        style={{ marginBottom: 16 }}
      >
        添加考试成绩
      </Button>
      <Table<ExamScoreRecord>
        columns={columns}
        dataSource={data}
        rowKey="id"
        pagination={{
          defaultPageSize: 15,
          showSizeChanger: true,
          pageSizeOptions: [15, 30, 50],
        }}
      />
      <Modal
        title="添加考试成绩"
        open={modalOpen}
        onOk={handleAdd}
        onCancel={() => setModalOpen(false)}
        confirmLoading={saving}
      >
        <Form form={form} layout="vertical">
          <Form.Item
            name="examType"
            label="考试类型"
            rules={[{ required: true, message: '请选择考试类型' }]}
          >
            <Select options={EXAM_TYPE_OPTIONS} placeholder="请选择" />
          </Form.Item>
          <Form.Item name="examName" label="考试名称">
            <Input placeholder="如：2024第一次月考" />
          </Form.Item>
          <Form.Item
            name="subject"
            label="科目"
            rules={[{ required: true, message: '请输入科目' }]}
          >
            <Input placeholder="如：数学" />
          </Form.Item>
          <Form.Item name="score" label="成绩" rules={[{ required: true, message: '请输入成绩' }]}>
            <InputNumber min={0} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="classAvg" label="班级均分">
            <InputNumber min={0} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="rank" label="排名">
            <InputNumber min={1} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="examDate" label="考试日期">
            <DatePicker style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="enrollmentId" label="关联报读">
            <Select
              allowClear
              placeholder="选择关联的报读记录"
              options={enrollments.map((e) => ({
                value: e.id,
                label: `${formatEnrollmentDisplayName(e)}（${getClassTypeLabel(e.classType)}）`,
              }))}
            />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

const LearningTab: React.FC<TabProps & { data: LearningRecord[] }> = ({
  data,
  studentId,
  onRefresh,
}) => {
  const [modalOpen, setModalOpen] = useState(false);
  const [form] = Form.useForm();
  const [saving, setSaving] = useState(false);

  const handleAdd = async () => {
    try {
      const values = await form.validateFields();
      setSaving(true);
      await api.post(`/archive/${studentId}/learning-records`, {
        ...values,
        recordDate: values.recordDate?.format('YYYY-MM-DD'),
      });
      message.success('学情记录已添加');
      setModalOpen(false);
      form.resetFields();
      onRefresh();
    } catch (e: unknown) {
      const err = e as { message?: string };
      if (err?.message) message.error(err.message);
    } finally {
      setSaving(false);
    }
  };

  const saveCell = async (record: LearningRecord, field: string, value: unknown) => {
    await api.put(`/archive/learning-records/${record.id}`, { [field]: value });
    message.success('学情记录已保存');
    onRefresh();
  };

  const columns: ColumnsType<LearningRecord> = [
    {
      title: '记录日期',
      dataIndex: 'recordDate',
      render: (v: string, r) => (
        <EditableCell
          value={v}
          editor="date"
          permission="student:edit"
          required
          onSave={(next) => saveCell(r, 'recordDate', next)}
        >
          {v}
        </EditableCell>
      ),
    },
    {
      title: '记录类型',
      dataIndex: 'recordType',
      render: (v: string, r) => (
        <EditableCell
          value={v}
          editor="select"
          options={RECORD_TYPE_OPTIONS}
          permission="student:edit"
          required
          onSave={(next) => saveCell(r, 'recordType', next)}
        >
          {RECORD_TYPE_OPTIONS.find((o) => o.value === v)?.label || v}
        </EditableCell>
      ),
    },
    {
      title: '内容',
      dataIndex: 'content',
      ellipsis: true,
      render: (v: string, r) => (
        <EditableCell
          value={v}
          editor="textarea"
          permission="student:edit"
          required
          onSave={(next) => saveCell(r, 'content', next)}
        >
          {v}
        </EditableCell>
      ),
    },
    {
      title: '跟进方式',
      dataIndex: 'followUpMethod',
      render: (v: string, r) => (
        <EditableCell
          value={v}
          permission="student:edit"
          onSave={(next) => saveCell(r, 'followUpMethod', next)}
        >
          {v || '-'}
        </EditableCell>
      ),
    },
    {
      title: '下一步计划',
      dataIndex: 'nextStep',
      render: (v: string, r) => (
        <EditableCell
          value={v}
          editor="textarea"
          permission="student:edit"
          onSave={(next) => saveCell(r, 'nextStep', next)}
        >
          {v || '-'}
        </EditableCell>
      ),
    },
  ];

  return (
    <div>
      <Button
        icon={<PlusOutlined />}
        type="primary"
        onClick={() => {
          form.resetFields();
          setModalOpen(true);
        }}
        style={{ marginBottom: 16 }}
      >
        添加学情记录
      </Button>
      <Table<LearningRecord>
        columns={columns}
        dataSource={data}
        rowKey="id"
        pagination={{
          defaultPageSize: 15,
          showSizeChanger: true,
          pageSizeOptions: [15, 30, 50],
        }}
      />
      <Modal
        title="添加学情记录"
        open={modalOpen}
        onOk={handleAdd}
        onCancel={() => setModalOpen(false)}
        confirmLoading={saving}
      >
        <Form form={form} layout="vertical">
          <Form.Item
            name="recordDate"
            label="记录日期"
            rules={[{ required: true, message: '请选择日期' }]}
          >
            <DatePicker style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item
            name="recordType"
            label="记录类型"
            rules={[{ required: true, message: '请选择记录类型' }]}
          >
            <Select options={RECORD_TYPE_OPTIONS} placeholder="请选择" />
          </Form.Item>
          <Form.Item
            name="content"
            label="内容"
            rules={[{ required: true, message: '请输入内容' }]}
          >
            <Input.TextArea rows={4} placeholder="请记录学情内容" />
          </Form.Item>
          <Form.Item name="followUpMethod" label="跟进方式">
            <Input placeholder="如：电话、微信、面谈" />
          </Form.Item>
          <Form.Item name="nextStep" label="下一步计划">
            <Input placeholder="后续跟进计划" />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

const AttachmentsTab: React.FC<TabProps & { data: AttachmentRecord[] }> = ({
  data,
  studentId,
  onRefresh,
}) => {
  const [uploading, setUploading] = useState(false);

  const handleDelete = async (attachmentId: number) => {
    try {
      await api.delete(`/archive/attachments/${attachmentId}`);
      message.success('已归档');
      onRefresh();
    } catch (e: unknown) {
      const err = e as { message?: string };
      message.error(err?.message || '归档失败');
    }
  };

  const columns: ColumnsType<AttachmentRecord> = [
    {
      title: '类别',
      dataIndex: 'category',
      render: (v: string) => ATTACHMENT_CATEGORY_OPTIONS.find((o) => o.value === v)?.label || v,
    },
    { title: '文件名', dataIndex: 'fileName' },
    { title: '大小', dataIndex: 'fileSize', render: formatFileSize },
    {
      title: '操作',
      render: (_: unknown, record: AttachmentRecord) => (
        <Space>
          <Button
            size="small"
            icon={<EyeOutlined />}
            onClick={async () => {
              try {
                const blob = await api.get<Blob>(`/archive/${studentId}/attachments/${record.id}`, {
                  responseType: 'blob',
                });
                const url = URL.createObjectURL(blob);
                window.open(url, '_blank');
                setTimeout(() => URL.revokeObjectURL(url), 60_000);
              } catch (e: unknown) {
                const err = e as { message?: string };
                message.error(err?.message || '查看失败');
              }
            }}
          >
            查看
          </Button>
          <Popconfirm title="确定归档该附件？" onConfirm={() => handleDelete(record.id)}>
            <Button size="small" danger icon={<InboxOutlined />}>
              归档
            </Button>
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <div>
      <Upload
        showUploadList={false}
        customRequest={async (options) => {
          const formData = new FormData();
          formData.append(
            'file',
            options.file instanceof File
              ? options.file
              : new File([options.file as Blob], 'attachment'),
          );
          setUploading(true);
          try {
            await api.post(`/archive/${studentId}/attachments`, formData, {
              headers: { 'Content-Type': 'multipart/form-data' },
            });
            message.success('上传成功');
            options.onSuccess?.({});
            onRefresh();
          } catch (e: unknown) {
            const msg = e instanceof Error ? e.message : '上传失败';
            message.error(msg);
            options.onError?.(e instanceof Error ? e : new Error(msg));
          } finally {
            setUploading(false);
          }
        }}
      >
        <Button icon={<UploadOutlined />} loading={uploading}>
          上传附件
        </Button>
      </Upload>
      <Table<AttachmentRecord>
        columns={columns}
        dataSource={data}
        rowKey="id"
        pagination={{
          defaultPageSize: 15,
          showSizeChanger: true,
          pageSizeOptions: [15, 30, 50],
        }}
        style={{ marginTop: 16 }}
      />
    </div>
  );
};

// ---- Main Component ----

const StudentProfileContent: React.FC<StudentProfileContentProps> = ({
  studentId,
  inDrawer,
  onClose,
}) => {
  const [aggregateData, setAggregateData] = useState<StudentProfileAggregate | null>(null);
  const [organizations, setOrganizations] = useState<Array<{ id: number; name: string }>>([]);
  const [loading, setLoading] = useState(false);

  const fetchData = useCallback(async () => {
    setLoading(true);
    try {
      const res = await api.get<StudentProfileAggregate>(`/archive/${studentId}`);
      setAggregateData(res);
    } catch (e: unknown) {
      const err = e as { message?: string };
      message.error(err?.message || '加载失败');
    } finally {
      setLoading(false);
    }
  }, [studentId]);

  useEffect(() => {
    void fetchData();
  }, [fetchData]);

  useEffect(() => {
    api
      .get('/organizations', { params: { includeArchived: 'false' } })
      .then((res: unknown) => {
        setOrganizations(res as Array<{ id: number; name: string }>);
      })
      .catch(() => {});
  }, []);

  const handlePreviewReport = useCallback(async () => {
    try {
      const { html } = await api.get<{ html: string }>(`/archive/${studentId}/report-html`);
      const w = window.open('', '_blank');
      if (w) {
        w.document.write(html);
        w.document.close();
      }
    } catch {
      message.error('加载报告失败');
    }
  }, [studentId]);

  const handleViewSensitive = useViewSensitive(studentId, '学生档案');

  const tabItems = useMemo(() => {
    if (!aggregateData) return [];
    const { enrollments, examScores, learningRecords, attachments, attendances } = aggregateData;
    return [
      {
        key: 'enrollments',
        label: `报读班型 (${enrollments.length})`,
        children: <EnrollmentsTab data={enrollments} studentId={studentId} onRefresh={fetchData} />,
      },
      {
        key: 'exams',
        label: `考试成绩 (${examScores.length})`,
        children: (
          <ExamScoresTab
            data={examScores}
            studentId={studentId}
            enrollments={enrollments}
            onRefresh={fetchData}
          />
        ),
      },
      {
        key: 'attendance',
        label: `出勤记录 (${attendances.length})`,
        children: <AttendanceTab data={attendances} />,
      },
      {
        key: 'learning',
        label: `课堂回访 (${learningRecords.length})`,
        children: (
          <LearningTab data={learningRecords} studentId={studentId} onRefresh={fetchData} />
        ),
      },
      {
        key: 'attachments',
        label: `附件 (${attachments.length})`,
        children: <AttachmentsTab data={attachments} studentId={studentId} onRefresh={fetchData} />,
      },
      {
        key: 'reports',
        label: '报告版本',
        children: <Empty description="暂无报告版本" />,
      },
    ];
  }, [aggregateData, studentId, fetchData]);

  if (!aggregateData) {
    if (loading) {
      return (
        <div style={{ textAlign: 'center', padding: 80 }}>
          <Spin size="large" />
        </div>
      );
    }
    return null;
  }

  const { student, profile, result } = aggregateData;

  return (
    <div>
      {inDrawer && (
        <Row justify="space-between" align="middle" style={{ marginBottom: 24 }}>
          <Space>
            <Button type="text" icon={<CloseOutlined />} onClick={onClose} aria-label="关闭档案" />
            <span style={{ fontSize: 16, fontWeight: 500 }}>
              学员档案 - {student.name}{student.studentNo ? ` (${student.studentNo})` : ''}
            </span>
          </Space>
          <Space>
            <Button icon={<FileTextOutlined />} onClick={handlePreviewReport}>
              预览报告
            </Button>
            <Button icon={<ReloadOutlined />} onClick={fetchData} loading={loading}>
              刷新
            </Button>
          </Space>
        </Row>
      )}

      <Row gutter={16} style={{ marginBottom: 24 }}>
        {[
          { title: '入学测试总分' },
          { title: '阶段最高分' },
          { title: '阶段提升分' },
          { title: '出勤率' },
        ].map((item) => (
          <Col span={6} key={item.title}>
            <Card size="small">
              <Statistic title={item.title} value="-" />
            </Card>
          </Col>
        ))}
      </Row>

      <InlineArchiveSummary
        studentId={studentId}
        student={student}
        profile={profile}
        result={result}
        organizations={organizations}
        onRefresh={fetchData}
        onViewSensitive={handleViewSensitive}
      />

      <Tabs defaultActiveKey="enrollments" items={tabItems} />
    </div>
  );
};

export default StudentProfileContent;
