import React, { useState, useCallback } from 'react';
import { useParams, useNavigate } from 'react-router';
import {Button, Card, Form, Space, Tabs, Tag, Skeleton} from 'antd';
import { ArrowLeftOutlined } from '@ant-design/icons';
import dayjs from 'dayjs';
import api from '../../api';
import { message } from '../../ui/app-message';
import { useQuery } from '@tanstack/react-query';
import type { TeacherCandidateUser } from './teacher-candidate';
import { getErrorMessage } from '../../utils/error';
import { QueryErrorState } from '../../components/QueryState';
import {
  ClassAttendanceTab,
  ClassInfoTab,
  ClassScheduleTab,
  ClassStudentsTab,
  ClassTeachersTab,
  STATUS_MAP,
  type ClassDetail,
  type ClassTeacher,
  type StudentItem,
  type AttendanceSummary,
  type ClassScheduleItem,
} from './ClassDetailTabs';

const ClassDetailPage: React.FC = () => {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const [editForm] = Form.useForm();
  const [editingInfo, setEditingInfo] = useState(false);

  // Student modal state
  const [studentModalOpen, setStudentModalOpen] = useState(false);
  const [allStudents, setAllStudents] = useState<StudentItem[]>([]);
  const [selectedStudentIds, setSelectedStudentIds] = useState<number[]>([]);
  const [addingStudents, setAddingStudents] = useState(false);
  const [addingTeacher, setAddingTeacher] = useState(false);

  // Teacher modal state
  const [teacherModalOpen, setTeacherModalOpen] = useState(false);
  const [teacherRole, setTeacherRole] = useState('subject_teacher');
  const [teacherSubject, setTeacherSubject] = useState('');
  const [teacherUserId, setTeacherUserId] = useState<number>();

  // Schedule & attendance state
  const [scheduleDateRange, setScheduleDateRange] = useState<
    [dayjs.Dayjs | null, dayjs.Dayjs | null]
  >([null, null]);
  const [attendanceDateRange, setAttendanceDateRange] = useState<
    [dayjs.Dayjs | null, dayjs.Dayjs | null]
  >([null, null]);

  const {
    data: detailResult = { detail: null, students: [], teachers: [] },
    isLoading: detailLoading,
    isFetching: detailFetching,
    isError: detailError,
    refetch: refetchDetail,
  } = useQuery<{
    detail: ClassDetail | null;
    students: ClassDetail['students'];
    teachers: ClassDetail['teachers'];
  }>({
    queryKey: ['classes', 'detail', id],
    queryFn: async () => {
      const res = (await api.get(`/classes/${id}`)) as ClassDetail;
      return { detail: res, students: res.students || [], teachers: res.teachers || [] };
    },
  });
  const detail = detailResult.detail;
  const students = detailResult.students ?? [];
  const teachers = detailResult.teachers ?? [];
  const loading = detailLoading || detailFetching;
  const fetchDetail = useCallback(() => refetchDetail(), [refetchDetail]);

  const {
    data: allUsers = [],
    isError: allUsersError,
    refetch: refetchUsers,
  } = useQuery<TeacherCandidateUser[]>({
    queryKey: ['rbac', 'users', 'all'],
    queryFn: async () => {
      return (await api.get('/rbac/users')) as TeacherCandidateUser[];
    },
  });
  const fetchUsers = useCallback(() => refetchUsers(), [refetchUsers]);

  const {
    data: schedules = [],
    isError: schedulesError,
    refetch: refetchSchedules,
  } = useQuery<ClassScheduleItem[]>({
    queryKey: ['classes', 'schedule', id, scheduleDateRange],
    queryFn: async () => {
      if (!id) return [];
      const params: Record<string, string> = {};
      if (scheduleDateRange?.[0]) params.startDate = scheduleDateRange[0].format('YYYY-MM-DD');
      if (scheduleDateRange?.[1]) params.endDate = scheduleDateRange[1].format('YYYY-MM-DD');
      return (await api.get<ClassScheduleItem[]>(`/classes/${id}/schedule`, { params })) || [];
    },
  });

  const {
    data: attendanceSummary = null,
    isError: attendanceSummaryError,
    refetch: refetchAttendanceSummary,
  } = useQuery<AttendanceSummary | null>({
    queryKey: ['classes', 'attendance-summary', id, attendanceDateRange],
    queryFn: async () => {
      if (!id) return null;
      const params: Record<string, string> = {};
      if (attendanceDateRange?.[0])
        params.startDate = attendanceDateRange[0].format('YYYY-MM-DD');
      if (attendanceDateRange?.[1]) params.endDate = attendanceDateRange[1].format('YYYY-MM-DD');
      return (
        (await api.get<AttendanceSummary>(`/classes/${id}/attendance-summary`, {
          params,
        })) || null
      );
    },
  });

  const handleSaveInfo = async () => {
    try {
      const values = await editForm.validateFields();
      await api.put(`/classes/${id}`, {
        name: values.name,
        code: values.code,
        classType: values.classType,
        startDate: values.startDate?.format('YYYY-MM-DD'),
        endDate: values.endDate?.format('YYYY-MM-DD'),
        maxStudents: values.maxStudents,
        status: values.status,
        notes: values.notes,
      });
      setEditingInfo(false);
      fetchDetail();
      message.success('已更新');
    } catch (e: unknown) {
      message.error(getErrorMessage(e, '更新失败'));
    }
  };

  const handleRemoveStudent = async (studentId: number) => {
    try {
      await api.delete(`/classes/${id}/students/${studentId}`);
      fetchDetail();
      message.success('已移除');
    } catch (e: unknown) {
      message.error(getErrorMessage(e, '移除失败'));
    }
  };

  const handleAddStudents = async () => {
    if (!selectedStudentIds.length) return;
    setAddingStudents(true);
    try {
      await api.post(`/classes/${id}/students`, { studentIds: selectedStudentIds });
      setStudentModalOpen(false);
      setSelectedStudentIds([]);
      fetchDetail();
      message.success('已添加');
    } catch (e: unknown) {
      message.error(getErrorMessage(e, '添加失败'));
    } finally {
      setAddingStudents(false);
    }
  };

  const handleAddTeacher = async () => {
    if (!teacherUserId) return;
    setAddingTeacher(true);
    try {
      await api.post(`/classes/${id}/teachers`, {
        userId: teacherUserId,
        roleType: teacherRole,
        subject: teacherSubject || undefined,
      });
      setTeacherModalOpen(false);
      fetchDetail();
      message.success('已添加');
    } catch (e: unknown) {
      message.error(getErrorMessage(e, '添加失败'));
    } finally {
      setAddingTeacher(false);
    }
  };

  const handleRemoveTeacher = async (userId: number) => {
    try {
      await api.delete(`/classes/${id}/teachers/${userId}`);
      fetchDetail();
      message.success('已移除');
    } catch (e: unknown) {
      message.error(getErrorMessage(e, '移除失败'));
    }
  };

  const openStudentModal = async () => {
    try {
      const res = (await api.get('/students', {
        params: { includeArchived: 'false' },
      })) as StudentItem[];
      setAllStudents(res || []);
      setSelectedStudentIds([]);
      setStudentModalOpen(true);
    } catch (e: unknown) {
      message.error(getErrorMessage(e, '加载学员列表失败'));
    }
  };

  const openTeacherModal = async () => {
    try {
      await fetchUsers();
      setTeacherUserId(undefined);
      setTeacherRole('subject_teacher');
      setTeacherSubject('');
      setTeacherModalOpen(true);
    } catch (e: unknown) {
      message.error(getErrorMessage(e, '加载用户列表失败'));
    }
  };

  const getTeacherName = (teacher: ClassTeacher) =>
    allUsers.find((user) => user.id === teacher.userId)?.name?.trim() || '-';

  if (!detail) {
    if (loading) {
      return (
        <div style={{ padding: 24 }}>
          <Skeleton active paragraph={{ rows: 8 }} />
        </div>
      );
    }
    if (detailError) {
      return (
        <QueryErrorState
          title="班级详情加载失败"
          description="请检查网络后重试。"
          onRetry={() => void refetchDetail()}
        />
      );
    }
    return null;
  }

  return (
    <Card
      title={
        <Space>
          <Button icon={<ArrowLeftOutlined />} onClick={() => navigate('/classes')} />
          <span>
            {detail.name} ({detail.code})
          </span>
          <Tag color={STATUS_MAP[detail.status]?.color}>{STATUS_MAP[detail.status]?.text}</Tag>
        </Space>
      }
      loading={loading}
    >
      <Tabs
        defaultActiveKey="info"
        items={[
          {
            key: 'info',
            label: '基本信息',
            children: (
              <ClassInfoTab
                detail={detail}
                teachers={teachers}
                editingInfo={editingInfo}
                editForm={editForm}
                onSave={handleSaveInfo}
                onEdit={() => {
                  editForm.setFieldsValue({
                    name: detail.name,
                    code: detail.code,
                    classType: detail.classType,
                    startDate: detail.startDate ? dayjs(detail.startDate) : undefined,
                    endDate: detail.endDate ? dayjs(detail.endDate) : undefined,
                    maxStudents: detail.maxStudents,
                    status: detail.status,
                    notes: detail.notes,
                  });
                  setEditingInfo(true);
                }}
                onCancel={() => setEditingInfo(false)}
                getTeacherName={getTeacherName}
              />
            ),
          },
          {
            key: 'students',
            label: `花名册 (${students.filter((s) => s.status === 'active').length})`,
            children: (
              <ClassStudentsTab
                id={id}
                detail={detail}
                students={students}
                allStudents={allStudents}
                selectedStudentIds={selectedStudentIds}
                modalOpen={studentModalOpen}
                onOpen={openStudentModal}
                onAdd={handleAddStudents}
                onClose={() => setStudentModalOpen(false)}
                onRemove={handleRemoveStudent}
                onSelect={setSelectedStudentIds}
                adding={addingStudents}
              />
            ),
          },
          {
            key: 'teachers',
            label: `教师 (${teachers.length})`,
            children: allUsersError ? (
              <QueryErrorState
                title="可添加教师加载失败"
                description="请检查网络后重试。"
                onRetry={() => void fetchUsers()}
              />
            ) : (
              <ClassTeachersTab
                teachers={teachers}
                allUsers={allUsers}
                teacherRole={teacherRole}
                teacherSubject={teacherSubject}
                teacherUserId={teacherUserId}
                modalOpen={teacherModalOpen}
                onOpen={openTeacherModal}
                onAdd={handleAddTeacher}
                onClose={() => setTeacherModalOpen(false)}
                onRemove={handleRemoveTeacher}
                onRoleChange={setTeacherRole}
                onSubjectChange={setTeacherSubject}
                onUserChange={setTeacherUserId}
                getTeacherName={getTeacherName}
                adding={addingTeacher}
              />
            ),
          },
          {
            key: 'schedule',
            label: '课表',
            children: schedulesError ? (
              <QueryErrorState
                title="课表加载失败"
                description="请检查网络后重试。"
                onRetry={() => void refetchSchedules()}
              />
            ) : (
              <ClassScheduleTab
                schedules={schedules}
                scheduleDateRange={scheduleDateRange}
                onRangeChange={setScheduleDateRange}
              />
            ),
          },
          {
            key: 'attendance-summary',
            label: '出勤汇总',
            children: attendanceSummaryError ? (
              <QueryErrorState
                title="出勤汇总加载失败"
                description="请检查网络后重试。"
                onRetry={() => void refetchAttendanceSummary()}
              />
            ) : (
              <ClassAttendanceTab
                attendanceSummary={attendanceSummary}
                attendanceDateRange={attendanceDateRange}
                onRangeChange={setAttendanceDateRange}
              />
            ),
          },
        ]}
      />
    </Card>
  );
};

export default ClassDetailPage;
