"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { useAuth } from "@/hooks/use-auth";
import { useActiveClass } from "@/hooks/use-active-class";
import {
  deleteAPI,
  fetchAPI,
  getErrorMessage,
  postAPI,
  putAPI,
  uploadAPI,
} from "@/lib/api";
import { Card, CardContent } from "@/components/ui/card";
import { ErrorState } from "@/components/error-state";
import { Pagination } from "@/components/pagination";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { ConfirmDialog } from "@/components/confirm-dialog";
import { toast } from "sonner";
import type {
  ClassPermission,
  InactiveMemberEntry,
  PageResponse,
  UserListItem,
} from "@/lib/types";
import { CLASS_PERMISSIONS, ROLES } from "@/lib/constants";
import { hasClassPermission } from "@/lib/permissions";

type InviteCodeResponse = {
  invite_code: string;
};

type MessageResponse = {
  message: string;
};

type TeacherCreateRequest = {
  class_id: number;
  name: string;
  email: string;
  password: string;
};

type TeacherCreateResponse = {
  message: string;
  user: UserListItem;
};

type TeacherAssignRequest = {
  class_id: number;
  email: string;
};

type TeacherAssignResponse = {
  message: string;
  user: UserListItem;
};

const PERMISSION_GROUPS: Array<{
  title: string;
  description: string;
  permissions: ClassPermission[];
}> = [
  {
    title: "成员与组织",
    description: "管理班级成员、班委和基础可见范围",
    permissions: ["class_view", "member_view", "member_manage", "committee_manage"],
  },
  {
    title: "内容与活动",
    description: "管理公告、动态、投票、排期和资源库",
    permissions: [
      "announcement_manage",
      "timeline_manage",
      "vote_manage",
      "schedule_manage",
      "resource_manage",
    ],
  },
  {
    title: "教学与财务",
    description: "管理作业、班费和模块开关",
    permissions: ["assignment_manage", "fund_manage", "module_manage"],
  },
];

const COMMITTEE_PRESETS: Array<{
  role: string;
  description: string;
  permissions: ClassPermission[];
}> = [
  {
    role: "班长",
    description: "统筹班级日常管理与主要内容发布",
    permissions: [
      "class_view",
      "member_view",
      "member_manage",
      "committee_manage",
      "announcement_manage",
      "timeline_manage",
      "vote_manage",
      "schedule_manage",
      "resource_manage",
    ],
  },
  {
    role: "副班长",
    description: "协助班长处理班级组织和内容管理",
    permissions: [
      "class_view",
      "member_view",
      "member_manage",
      "announcement_manage",
      "timeline_manage",
      "vote_manage",
      "schedule_manage",
      "resource_manage",
    ],
  },
  {
    role: "学习委员",
    description: "负责学习通知、作业协同与课程安排",
    permissions: [
      "class_view",
      "member_view",
      "announcement_manage",
      "assignment_manage",
      "schedule_manage",
      "resource_manage",
    ],
  },
  {
    role: "组织委员",
    description: "负责活动组织、投票协同和排期推进",
    permissions: [
      "class_view",
      "member_view",
      "timeline_manage",
      "vote_manage",
      "schedule_manage",
      "resource_manage",
    ],
  },
  {
    role: "生活委员",
    description: "负责生活事务通知与班费相关管理",
    permissions: [
      "class_view",
      "member_view",
      "announcement_manage",
      "fund_manage",
      "resource_manage",
    ],
  },
  {
    role: "文体委员",
    description: "负责文体活动、动态发布与投票互动",
    permissions: [
      "class_view",
      "member_view",
      "timeline_manage",
      "vote_manage",
      "schedule_manage",
      "resource_manage",
    ],
  },
];

export default function MembersPage() {
  const { user } = useAuth();
  const { activeClassId } = useActiveClass();
  // Tab state
  const [activeTab, setActiveTab] = useState<"members" | "inactive">("inactive");

  // Members state
  const [members, setMembers] = useState<UserListItem[]>([]);
  const [membersLoading, setMembersLoading] = useState(true);
  const [membersError, setMembersError] = useState<string | null>(null);
  const [membersPage, setMembersPage] = useState(1);
  const [membersTotalPages, setMembersTotalPages] = useState(1);
  // Inactive member state
  const [inactiveMembers, setInactiveMembers] = useState<InactiveMemberEntry[]>([]);
  const [inactiveLoading, setInactiveLoading] = useState(true);
  const [inactiveError, setInactiveError] = useState<string | null>(null);
  const [inactivePage, setInactivePage] = useState(1);
  const [inactiveTotalPages, setInactiveTotalPages] = useState(1);
  const [inviteCode, setInviteCode] = useState("");
  const [importOpen, setImportOpen] = useState(false);
  const [importText, setImportText] = useState("");
  const [importing, setImporting] = useState(false);
  const [clearTarget, setClearTarget] = useState(false);
  const [teacherCreateOpen, setTeacherCreateOpen] = useState(false);
  const [teacherName, setTeacherName] = useState("");
  const [teacherEmail, setTeacherEmail] = useState("");
  const [teacherPassword, setTeacherPassword] = useState("");
  const [teacherSubmitting, setTeacherSubmitting] = useState(false);
  const [teacherAssignOpen, setTeacherAssignOpen] = useState(false);
  const [teacherAssignEmail, setTeacherAssignEmail] = useState("");
  const [teacherAssignSubmitting, setTeacherAssignSubmitting] = useState(false);
  const [memberManagerOpen, setMemberManagerOpen] = useState(false);
  const [managingMember, setManagingMember] = useState<UserListItem | null>(null);
  const [memberRoleValue, setMemberRoleValue] = useState<string>("student");
  const [memberCommitteeValue, setMemberCommitteeValue] = useState("");
  const [memberPermissionsValue, setMemberPermissionsValue] = useState<ClassPermission[]>([]);
  const [memberSubmitting, setMemberSubmitting] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  const isSuperAdmin = user?.role === "super_admin";
  const canManageCommittee = hasClassPermission(user, "committee_manage", activeClassId);
  const canOpenMemberManager = isSuperAdmin || canManageCommittee;

  // Load members
  const loadMembers = useCallback(async () => {
    if (!activeClassId) {
      setMembers([]);
      setMembersLoading(false);
      return;
    }
    setMembersLoading(true);
    setMembersError(null);
    try {
      const res = await fetchAPI<PageResponse<UserListItem>>(
        `/api/classes/${activeClassId}/members`,
        {
          status: "approved",
          page: String(membersPage),
          page_size: "20",
        }
      );
      setMembers(res.items ?? []);
      setMembersTotalPages(res.total_pages ?? 1);
    } catch (err: unknown) {
      setMembersError(getErrorMessage(err, "加载失败"));
    } finally {
      setMembersLoading(false);
    }
  }, [activeClassId, membersPage]);

  // Load inactive members
  const loadInactiveMembers = useCallback(async () => {
    if (!activeClassId) {
      setInactiveMembers([]);
      setInviteCode("");
      setInactiveLoading(false);
      return;
    }
    setInactiveLoading(true);
    setInactiveError(null);
    try {
      const [inactiveRes, codeRes] = await Promise.all([
        fetchAPI<PageResponse<InactiveMemberEntry>>(`/api/classes/${activeClassId}/inactive-members`, {
          page: String(inactivePage),
          page_size: "50",
        }),
        fetchAPI<InviteCodeResponse>(`/api/classes/${activeClassId}/invite-code`),
      ]);
      setInactiveMembers(inactiveRes.items ?? []);
      setInactiveTotalPages(inactiveRes.total_pages ?? 1);
      setInviteCode(codeRes.invite_code ?? "");
    } catch (err: unknown) {
      setInactiveError(getErrorMessage(err, "加载失败"));
    } finally {
      setInactiveLoading(false);
    }
  }, [activeClassId, inactivePage]);

  useEffect(() => {
    if (!activeClassId) return;
    if (activeTab === "members") {
      void loadMembers();
      return;
    }
    void loadInactiveMembers();
  }, [activeClassId, activeTab, loadInactiveMembers, loadMembers]);

  // Member actions
  const handleRoleChange = async (userId: number, newRole: string) => {
    try {
      await putAPI<UserListItem>(`/api/users/${userId}/role`, {
        role: newRole,
      });
      toast.success(
        `角色已更新为 ${ROLES[newRole as keyof typeof ROLES] || newRole}`
      );
      await loadMembers();
    } catch (err: unknown) {
      toast.error(getErrorMessage(err, "操作失败"));
    }
  };

  const handleCommitteeRoleChange = async (userId: number, newRole: string) => {
    try {
      await putAPI<UserListItem>(`/api/users/${userId}/committee-role`, {
        class_id: activeClassId,
        committee_role: newRole === "__none__" ? null : newRole,
      });
      toast.success(newRole === "__none__" ? "已清除班委标签" : `已设置班委标签: ${newRole}`);
      await loadMembers();
    } catch (err: unknown) {
      toast.error(getErrorMessage(err, "操作失败"));
    }
  };

  // Inactive member actions
  const handleCopyCode = () => {
    navigator.clipboard.writeText(inviteCode);
    toast.success("邀请码已复制");
  };

  const handleRegenerateCode = async () => {
    try {
      const res = await postAPI<InviteCodeResponse>(
        `/api/classes/${activeClassId}/invite-code/regenerate`
      );
      setInviteCode(res.invite_code);
      toast.success("邀请码已重新生成");
    } catch (err: unknown) {
      toast.error(getErrorMessage(err, "操作失败"));
    }
  };

  const handleTextImport = async () => {
    if (!importText.trim()) return;
    setImporting(true);
    try {
      // Parse text: each line is "学号 姓名" or "学号,姓名" or "学号\t姓名"
      const entries: { student_id: string; name: string }[] = [];
      const lines = importText.trim().split("\n");
      for (const line of lines) {
        const parts = line.trim().split(/[,\t，\s]+/);
        if (parts.length >= 2) {
          entries.push({ student_id: parts[0], name: parts.slice(1).join("") });
        }
      }
      if (entries.length === 0) {
        toast.error("未解析到有效数据，每行格式：学号 姓名");
        return;
      }
      const res = await postAPI<MessageResponse>(
        `/api/classes/${activeClassId}/inactive-members/import`,
        {
          entries,
        }
      );
      toast.success(res.message);
      setImportOpen(false);
      setImportText("");
      await loadInactiveMembers();
    } catch (err: unknown) {
      toast.error(getErrorMessage(err, "导入失败"));
    } finally {
      setImporting(false);
    }
  };

  const handleFileUpload = async () => {
    const fileInput = fileInputRef.current;
    if (!fileInput?.files?.length) return;
    setImporting(true);
    try {
      const formData = new FormData();
      formData.append("file", fileInput.files[0]);
      const res = await uploadAPI<MessageResponse>(
        `/api/classes/${activeClassId}/inactive-members/upload`,
        formData
      );
      toast.success(res.message);
      setImportOpen(false);
      if (fileInput) fileInput.value = "";
      await loadInactiveMembers();
    } catch (err: unknown) {
      toast.error(getErrorMessage(err, "上传失败"));
    } finally {
      setImporting(false);
    }
  };

  const handleDeleteInactiveMember = async (userId: number) => {
    try {
      await deleteAPI<MessageResponse>(`/api/classes/${activeClassId}/inactive-members/${userId}`);
      toast.success("已删除");
      await loadInactiveMembers();
    } catch (err: unknown) {
      toast.error(getErrorMessage(err, "删除失败"));
    }
  };

  const handleClearRoster = async () => {
    try {
      const res = await postAPI<MessageResponse>(`/api/classes/${activeClassId}/inactive-members/clear`);
      toast.success(res.message);
      setClearTarget(false);
      await loadInactiveMembers();
    } catch (err: unknown) {
      toast.error(getErrorMessage(err, "操作失败"));
    }
  };

  const togglePermission = (permission: ClassPermission) => {
    setMemberPermissionsValue((prev) =>
      prev.includes(permission)
        ? prev.filter((item) => item !== permission)
        : [...prev, permission]
    );
  };

  const applyPermissionPreset = (permissions: ClassPermission[]) => {
    setMemberPermissionsValue(Array.from(new Set(permissions)));
  };

  const applyCommitteePreset = (presetRole: string) => {
    const preset = COMMITTEE_PRESETS.find((item) => item.role === presetRole);
    if (!preset) {
      return;
    }
    setMemberCommitteeValue(preset.role);
    applyPermissionPreset(preset.permissions);
  };

  const handlePermissionsSave = async (userId: number, permissions: ClassPermission[]) => {
    try {
      await putAPI<UserListItem>(`/api/users/${userId}/class-permissions`, {
        class_id: activeClassId,
        class_permissions: permissions,
      });
    } catch (err: unknown) {
      toast.error(getErrorMessage(err, "操作失败"));
      throw err;
    }
  };

  const resetTeacherForm = () => {
    setTeacherName("");
    setTeacherEmail("");
    setTeacherPassword("");
  };

  const resetTeacherAssignForm = () => {
    setTeacherAssignEmail("");
  };

  const handleCreateTeacher = async () => {
    if (!activeClassId) return;
    if (!teacherName.trim()) {
      toast.error("请输入老师姓名");
      return;
    }
    if (!teacherEmail.trim()) {
      toast.error("请输入老师邮箱");
      return;
    }
    if (teacherPassword.length < 8) {
      toast.error("初始密码至少 8 位");
      return;
    }

    setTeacherSubmitting(true);
    try {
      const payload: TeacherCreateRequest = {
        class_id: activeClassId,
        name: teacherName.trim(),
        email: teacherEmail.trim(),
        password: teacherPassword,
      };
      const res = await postAPI<TeacherCreateResponse>("/api/users/teachers", payload);
      toast.success(res.message);
      setTeacherCreateOpen(false);
      resetTeacherForm();
      if (activeTab === "members") {
        await loadMembers();
      }
    } catch (err: unknown) {
      toast.error(getErrorMessage(err, "创建老师失败"));
    } finally {
      setTeacherSubmitting(false);
    }
  };

  const handleAssignTeacher = async () => {
    if (!activeClassId) return;
    if (!teacherAssignEmail.trim()) {
      toast.error("请输入老师邮箱");
      return;
    }

    setTeacherAssignSubmitting(true);
    try {
      const payload: TeacherAssignRequest = {
        class_id: activeClassId,
        email: teacherAssignEmail.trim(),
      };
      const res = await postAPI<TeacherAssignResponse>("/api/users/teachers/assign", payload);
      toast.success(res.message);
      setTeacherAssignOpen(false);
      resetTeacherAssignForm();
      if (activeTab === "members") {
        await loadMembers();
      }
    } catch (err: unknown) {
      toast.error(getErrorMessage(err, "分配老师失败"));
    } finally {
      setTeacherAssignSubmitting(false);
    }
  };

  const openMemberManager = (member: UserListItem) => {
    setManagingMember(member);
    setMemberRoleValue(member.role);
    setMemberCommitteeValue(member.committee_role ?? "");
    setMemberPermissionsValue(member.class_permissions ?? []);
    setMemberManagerOpen(true);
  };

  const resetMemberManager = () => {
    setManagingMember(null);
    setMemberRoleValue("student");
    setMemberCommitteeValue("");
    setMemberPermissionsValue([]);
    setMemberSubmitting(false);
  };

  const handleMemberManagerSave = async () => {
    if (!managingMember || !activeClassId) return;

    const originalRole = managingMember.role;
    const originalCommittee = managingMember.committee_role ?? "";
    const originalPermissions = managingMember.class_permissions ?? [];
    const normalizedCommittee = memberCommitteeValue.trim();
    const permissionsChanged =
      originalPermissions.length !== memberPermissionsValue.length ||
      originalPermissions.some((permission) => !memberPermissionsValue.includes(permission));

    setMemberSubmitting(true);
    try {
      if (isSuperAdmin && memberRoleValue !== originalRole) {
        await handleRoleChange(managingMember.id, memberRoleValue);
      }

      if (memberRoleValue !== "super_admin" && canManageCommittee) {
        if (normalizedCommittee !== originalCommittee) {
          await handleCommitteeRoleChange(
            managingMember.id,
            normalizedCommittee ? normalizedCommittee : "__none__"
          );
        }

        if (permissionsChanged) {
          await handlePermissionsSave(managingMember.id, memberPermissionsValue);
          toast.success("成员设置已更新");
        } else if (normalizedCommittee !== originalCommittee || memberRoleValue !== originalRole) {
          toast.success("成员设置已更新");
        }
      } else if (memberRoleValue !== originalRole) {
        toast.success("成员设置已更新");
      }

      setMemberManagerOpen(false);
      resetMemberManager();
      await loadMembers();
    } catch {
      // Errors are surfaced by the called actions.
    } finally {
      setMemberSubmitting(false);
    }
  };

  return (
    <div className="space-y-6">
      <div>
        <div className="text-[11px] uppercase tracking-[0.24em] text-[#976746]">Members</div>
        <h1 className="mt-2 text-3xl font-semibold text-[#4e1d1a]">成员管理</h1>
        <p className="mt-2 text-[#765a4d]">管理成员导入、激活码和班级成员权限</p>
      </div>

      {!activeClassId ? (
        <div className="py-12 text-center text-[#9d806f]">
          {isSuperAdmin ? "请在顶部选择一个班级" : "您尚未分配班级"}
        </div>
      ) : (
        <>
          {/* Tab switcher */}
          <div className="flex gap-2 rounded-2xl border border-[#eadbc8] bg-[#fffaf2] p-2">
            <Button
              variant={activeTab === "inactive" ? "default" : "ghost"}
              size="sm"
              onClick={() => setActiveTab("inactive")}
            >
              未激活成员
            </Button>
            <Button
              variant={activeTab === "members" ? "default" : "ghost"}
              size="sm"
              onClick={() => setActiveTab("members")}
            >
              成员管理
            </Button>
          </div>

          {activeTab === "inactive" && (
            <div className="space-y-4">
              {/* Invite code section */}
              <Card className="bg-[#fffaf2]">
                <CardContent className="p-4">
                  <div className="flex items-center justify-between">
                    <div>
                      <p className="text-sm text-[#7a5e4f]">成员激活码</p>
                      <p className="mt-1 text-2xl font-mono font-bold tracking-widest text-[#4e1d1a]">
                        {inviteCode || "—"}
                      </p>
                    </div>
                    <div className="flex gap-2">
                      <Button variant="outline" size="sm" onClick={handleCopyCode}>
                        复制
                      </Button>
                      <Button variant="outline" size="sm" onClick={handleRegenerateCode}>
                        重新生成
                      </Button>
                    </div>
                  </div>
                  <p className="mt-2 text-xs text-[#9a7b68]">
                    将此激活码分享给成员，成员输入激活码和学号后即可激活账号
                  </p>
                </CardContent>
              </Card>

              {/* Import actions */}
              <div className="flex gap-2">
                <Dialog open={importOpen} onOpenChange={(open) => { setImportOpen(open); if (!open) setImportText(""); }}>
                  <DialogTrigger>
                    <Button>导入成员</Button>
                  </DialogTrigger>
                  <DialogContent className="max-w-lg">
                    <DialogHeader>
                      <DialogTitle>导入成员</DialogTitle>
                    </DialogHeader>
                    <div className="space-y-4 pt-2">
                      <div>
                        <Label>文本输入（每行：学号 姓名，用空格或逗号分隔）</Label>
                        <Textarea
                          placeholder={"24001 张三\n24002 李四\n24003 王五"}
                          value={importText}
                          onChange={(e) => setImportText(e.target.value)}
                          rows={6}
                          className="mt-2 font-mono text-sm"
                        />
                        <Button
                          onClick={handleTextImport}
                          disabled={importing || !importText.trim()}
                          className="mt-2 w-full"
                        >
                          {importing ? "导入中..." : "从文本导入"}
                        </Button>
                      </div>
                      <div className="relative">
                        <div className="absolute inset-0 flex items-center">
                          <span className="w-full border-t" />
                        </div>
                        <div className="relative flex justify-center text-xs uppercase">
                          <span className="bg-white px-2 text-gray-400">或</span>
                        </div>
                      </div>
                      <div>
                        <Label>上传 CSV / Excel 文件</Label>
                        <p className="text-xs text-gray-400 mt-1">
                          CSV 需含 student_id(学号) 和 name(姓名) 列；Excel 需含「学号」「姓名」列
                        </p>
                        <input
                          ref={fileInputRef}
                          type="file"
                          accept=".csv,.xlsx,.xls"
                          className="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded file:border-0 file:text-sm file:font-medium file:bg-gray-100 file:text-gray-700 hover:file:bg-gray-200 mt-2"
                        />
                        <Button
                          onClick={handleFileUpload}
                          disabled={importing}
                          className="mt-2 w-full"
                          variant="outline"
                        >
                          {importing ? "上传中..." : "上传文件"}
                        </Button>
                      </div>
                    </div>
                  </DialogContent>
                </Dialog>
                <Button
                  variant="outline"
                  onClick={() => setClearTarget(true)}
                  disabled={inactiveMembers.length === 0}
                >
                  清除未激活成员
                </Button>
              </div>

              {/* Inactive member list */}
              {inactiveLoading ? (
                <div className="animate-pulse space-y-2">
                  {[1, 2, 3].map((i) => (
                    <Card key={i} className="bg-[#fffaf2]">
                      <CardContent className="p-4">
                        <div className="h-12 bg-gray-200 rounded" />
                      </CardContent>
                    </Card>
                  ))}
                </div>
              ) : inactiveError ? (
                <ErrorState message={inactiveError} onRetry={loadInactiveMembers} />
              ) : inactiveMembers.length === 0 ? (
                <div className="py-12 text-center text-[#9d806f]">
                  暂无未激活成员，点击「导入成员」添加
                </div>
              ) : (
                <div className="space-y-2">
                  {inactiveMembers.map((r) => (
                    <Card key={r.id} className="bg-[#fffdf8]">
                      <CardContent className="p-4 flex items-center justify-between">
                        <div>
                          <p className="font-medium text-[#4e1d1a]">{r.name}</p>
                          <p className="text-sm text-[#73594a]">{r.student_id}</p>
                        </div>
                        <div className="flex items-center gap-2">
                          <Badge variant="outline">未激活</Badge>
                          <Button
                            variant="ghost"
                            size="sm"
                            className="text-red-500"
                            onClick={() => handleDeleteInactiveMember(r.id)}
                          >
                            删除
                          </Button>
                        </div>
                      </CardContent>
                    </Card>
                  ))}
                </div>
              )}

              <Pagination
                page={inactivePage}
                totalPages={inactiveTotalPages}
                onPageChange={setInactivePage}
              />
            </div>
          )}

          {activeTab === "members" && (
            <div className="space-y-4">
              <div className="flex items-center justify-between">
                <h2 className="text-lg font-semibold text-[#4e1d1a]">已激活成员</h2>
                {isSuperAdmin && (
                  <div className="flex items-center gap-2">
                    <Dialog
                      open={teacherAssignOpen}
                      onOpenChange={(open) => {
                        setTeacherAssignOpen(open);
                        if (!open) {
                          resetTeacherAssignForm();
                        }
                      }}
                    >
                      <DialogTrigger>
                        <Button size="sm" variant="outline">分配已有老师</Button>
                      </DialogTrigger>
                      <DialogContent className="max-w-md">
                        <DialogHeader>
                          <DialogTitle>分配已有老师到当前班级</DialogTitle>
                        </DialogHeader>
                        <div className="space-y-4 pt-2">
                          <div className="space-y-2">
                            <Label htmlFor="teacher-assign-email">老师邮箱</Label>
                            <Input
                              id="teacher-assign-email"
                              type="email"
                              value={teacherAssignEmail}
                              onChange={(e) => setTeacherAssignEmail(e.target.value)}
                              placeholder="teacher@example.com"
                            />
                          </div>
                          <p className="text-xs text-gray-400">
                            适合把已经存在的老师账号继续加入当前班级，不会重复创建账号。
                          </p>
                          <Button
                            className="w-full"
                            onClick={handleAssignTeacher}
                            disabled={teacherAssignSubmitting}
                          >
                            {teacherAssignSubmitting ? "分配中..." : "加入当前班级"}
                          </Button>
                        </div>
                      </DialogContent>
                    </Dialog>

                    <Dialog
                      open={teacherCreateOpen}
                      onOpenChange={(open) => {
                        setTeacherCreateOpen(open);
                        if (!open) {
                          resetTeacherForm();
                        }
                      }}
                    >
                      <DialogTrigger>
                        <Button size="sm">创建老师账号</Button>
                      </DialogTrigger>
                      <DialogContent className="max-w-md">
                        <DialogHeader>
                          <DialogTitle>创建老师账号</DialogTitle>
                        </DialogHeader>
                        <div className="space-y-4 pt-2">
                          <div className="space-y-2">
                            <Label htmlFor="teacher-name">老师姓名</Label>
                            <Input
                              id="teacher-name"
                              value={teacherName}
                              onChange={(e) => setTeacherName(e.target.value)}
                              placeholder="请输入老师姓名"
                            />
                          </div>
                          <div className="space-y-2">
                            <Label htmlFor="teacher-email">邮箱</Label>
                            <Input
                              id="teacher-email"
                              type="email"
                              value={teacherEmail}
                              onChange={(e) => setTeacherEmail(e.target.value)}
                              placeholder="teacher@example.com"
                            />
                          </div>
                          <div className="space-y-2">
                            <Label htmlFor="teacher-password">初始密码</Label>
                            <Input
                              id="teacher-password"
                              type="password"
                              value={teacherPassword}
                              onChange={(e) => setTeacherPassword(e.target.value)}
                              placeholder="至少 8 位"
                            />
                          </div>
                          <p className="text-xs text-gray-400">
                            创建后该老师会直接加入当前选中的班级，可继续加入其他班级。
                          </p>
                          <Button
                            className="w-full"
                            onClick={handleCreateTeacher}
                            disabled={teacherSubmitting}
                          >
                            {teacherSubmitting ? "创建中..." : "创建老师账号"}
                          </Button>
                        </div>
                      </DialogContent>
                    </Dialog>
                  </div>
                )}
              </div>

              {membersLoading ? (
                <div className="animate-pulse space-y-2">
                  {[1, 2, 3].map((i) => (
                    <Card key={i} className="bg-[#fffaf2]">
                      <CardContent className="p-4">
                        <div className="h-12 bg-gray-200 rounded" />
                      </CardContent>
                    </Card>
                  ))}
                </div>
              ) : membersError ? (
                <ErrorState message={membersError} onRetry={loadMembers} />
              ) : members.length === 0 ? (
                <div className="py-8 text-center text-[#9d806f]">暂无已激活成员</div>
              ) : (
                <div className="space-y-2">
                  {members.map((m) => (
                    <Card key={m.id} className="bg-[#fffdf8]">
                      <CardContent className="flex items-start justify-between gap-4 p-4">
                        <div className="min-w-0 flex-1">
                          <div>
                            <p className="font-medium text-[#4e1d1a]">
                              {m.name}
                              {m.committee_role && (
                                <Badge className="ml-2 text-xs bg-[#f3ddab] text-[#74411f] hover:bg-[#f3ddab] border-[#e5c884]">
                                  {m.committee_role}
                                </Badge>
                              )}
                            </p>
                            <p className="text-sm text-[#73594a]">
                              {m.email}
                              {m.student_id ? ` · ${m.student_id}` : ""}
                              {m.company ? ` · ${m.company}` : ""}
                            </p>
                          </div>

                          <div className="mt-3 flex flex-wrap gap-2">
                            {m.class_permissions && m.class_permissions.length > 0 ? (
                              m.class_permissions.map((permission) => (
                                <Badge
                                  key={permission}
                                  variant="outline"
                                  className="border-[#dcc6ab] bg-[#fff8ef] text-xs text-[#7a5e4f]"
                                >
                                  {CLASS_PERMISSIONS[permission]}
                                </Badge>
                              ))
                            ) : (
                              <Badge
                                variant="outline"
                                className="border-[#e4d5c4] bg-white text-xs text-[#9d806f]"
                              >
                                普通成员
                              </Badge>
                            )}
                          </div>
                        </div>
                        <div className="flex shrink-0 items-center gap-2">
                          <Badge variant="outline" className="border-[#dcc6ab] bg-[#fff8ef] text-[#7a5e4f]">
                            {ROLES[m.role as keyof typeof ROLES] || m.role}
                          </Badge>
                          {canOpenMemberManager && (
                            <Button
                              variant="outline"
                              size="sm"
                              className="h-7 text-xs"
                              onClick={() => openMemberManager(m)}
                            >
                              管理
                            </Button>
                          )}
                        </div>
                      </CardContent>
                    </Card>
                  ))}
                </div>
              )}

              <Pagination
                page={membersPage}
                totalPages={membersTotalPages}
                onPageChange={setMembersPage}
              />
            </div>
          )}
        </>
      )}

      <ConfirmDialog
        open={clearTarget}
        onOpenChange={(open) => { if (!open) setClearTarget(false); }}
        title="清除未激活成员"
        description="确定清除当前班级所有未激活成员？此操作不可恢复。"
        confirmText="清除"
        variant="destructive"
        onConfirm={handleClearRoster}
      />

      <Dialog
        open={memberManagerOpen}
        onOpenChange={(open) => {
          setMemberManagerOpen(open);
          if (!open) {
            resetMemberManager();
          }
        }}
      >
        <DialogContent className="max-h-[88vh] max-w-3xl overflow-hidden border-[#eadbc8] bg-[#fffdf8] p-0">
          <DialogHeader>
            <div className="border-b border-[#eadbc8] px-6 pb-4 pt-6">
              <DialogTitle className="text-xl text-[#4e1d1a]">成员设置</DialogTitle>
            </div>
          </DialogHeader>
          {managingMember && (
            <div className="flex max-h-[calc(88vh-5.5rem)] flex-col">
              <div className="px-6 pt-5">
              <div className="rounded-[1.5rem] border border-[#eadbc8] bg-[#fffaf2] p-4">
                <div className="flex flex-wrap items-center gap-2">
                  <p className="text-base font-semibold text-[#4e1d1a]">{managingMember.name}</p>
                  <Badge variant="outline" className="border-[#dcc6ab] bg-[#fff8ef] text-[#7a5e4f]">
                    {ROLES[managingMember.role as keyof typeof ROLES] || managingMember.role}
                  </Badge>
                  {managingMember.committee_role && (
                    <Badge className="border-[#e5c884] bg-[#f3ddab] text-[#74411f] hover:bg-[#f3ddab]">
                      {managingMember.committee_role}
                    </Badge>
                  )}
                </div>
                <p className="mt-2 text-sm text-[#7a5e4f]">
                  {managingMember.email}
                  {managingMember.student_id ? ` · ${managingMember.student_id}` : ""}
                </p>
              </div>
              </div>

              <div className="min-h-0 flex-1 overflow-y-auto px-6 py-5">
                <Tabs defaultValue="identity" className="gap-4">
                  <TabsList
                    className="w-full rounded-2xl border border-[#eadbc8] bg-[#fffaf2] p-1"
                  >
                    <TabsTrigger
                      value="identity"
                      className="rounded-xl data-active:bg-[#fffdf8] data-active:text-[#4e1d1a]"
                    >
                      身份设置
                    </TabsTrigger>
                    <TabsTrigger
                      value="permissions"
                      className="rounded-xl data-active:bg-[#fffdf8] data-active:text-[#4e1d1a]"
                    >
                      权限设置
                    </TabsTrigger>
                  </TabsList>

                  <TabsContent value="identity" className="space-y-4">
                    {isSuperAdmin && managingMember.role !== "super_admin" ? (
                      <section className="space-y-3 rounded-[1.5rem] border border-[#eadbc8] bg-[#fffdf8] p-4">
                        <div>
                          <h3 className="text-sm font-semibold text-[#4e1d1a]">系统角色</h3>
                          <p className="mt-1 text-xs text-[#8d7160]">
                            角色决定是否具备跨班管理能力。老师和同学都可以在当前班级里继续配置班委身份。
                          </p>
                        </div>
                        <Select
                          value={memberRoleValue}
                          onValueChange={(value) => {
                            if (value) setMemberRoleValue(value);
                          }}
                        >
                          <SelectTrigger className="w-full">
                            <SelectValue>
                              {ROLES[memberRoleValue as keyof typeof ROLES] || memberRoleValue}
                            </SelectValue>
                          </SelectTrigger>
                          <SelectContent>
                            <SelectItem value="student">同学</SelectItem>
                            <SelectItem value="teacher">老师</SelectItem>
                          </SelectContent>
                        </Select>
                      </section>
                    ) : (
                      <section className="rounded-[1.5rem] border border-[#eadbc8] bg-[#fffdf8] p-4">
                        <p className="text-sm font-medium text-[#4e1d1a]">系统角色</p>
                        <p className="mt-2 text-sm text-[#7a5e4f]">
                          当前成员的系统角色为
                          <span className="mx-1 font-medium text-[#4e1d1a]">
                            {ROLES[memberRoleValue as keyof typeof ROLES] || memberRoleValue}
                          </span>
                          。
                        </p>
                      </section>
                    )}

                    {managingMember.role !== "super_admin" && canManageCommittee && (
                      <section className="space-y-4 rounded-[1.5rem] border border-[#eadbc8] bg-[#fffdf8] p-4">
                        <div>
                          <h3 className="text-sm font-semibold text-[#4e1d1a]">班级身份</h3>
                          <p className="mt-1 text-xs text-[#8d7160]">
                            在这里设置当前班级中的班委身份。预设会自动带出推荐权限。
                          </p>
                        </div>

                        <div className="space-y-2">
                          <Label htmlFor="committee-role">班委名称</Label>
                          <Input
                            id="committee-role"
                            value={memberCommitteeValue}
                            onChange={(e) => setMemberCommitteeValue(e.target.value)}
                            placeholder="例如：班长、学习委员，留空表示不是班委"
                          />
                          <div className="flex flex-wrap gap-2 pt-1">
                            {COMMITTEE_PRESETS.map((preset) => (
                              <Button
                                key={preset.role}
                                type="button"
                                variant={memberCommitteeValue === preset.role ? "default" : "outline"}
                                size="sm"
                                className="h-7 text-xs"
                                onClick={() => applyCommitteePreset(preset.role)}
                              >
                                {preset.role}
                              </Button>
                            ))}
                          </div>
                          <div className="rounded-xl bg-[#f7eee1] px-3 py-2 text-xs text-[#7a5e4f]">
                            {COMMITTEE_PRESETS.find((preset) => preset.role === memberCommitteeValue)?.description ??
                              "可先选择班委预设，再去权限页微调具体管理能力。"}
                          </div>
                        </div>
                      </section>
                    )}
                  </TabsContent>

                  <TabsContent value="permissions" className="space-y-4">
                    {managingMember.role !== "super_admin" && canManageCommittee ? (
                      <section className="space-y-4 rounded-[1.5rem] border border-[#eadbc8] bg-[#fffdf8] p-4">
                        <div className="space-y-2">
                          <div className="flex flex-wrap items-center justify-between gap-2">
                            <Label className="text-[#4e1d1a]">班级权限</Label>
                            <div className="flex flex-wrap gap-2">
                              <Button
                                type="button"
                                variant="outline"
                                size="sm"
                                className="h-7 text-xs"
                                onClick={() =>
                                  applyPermissionPreset([
                                    "member_view",
                                    "announcement_manage",
                                    "timeline_manage",
                                    "vote_manage",
                                    "schedule_manage",
                                    "resource_manage",
                                  ])
                                }
                              >
                                常用管理权限
                              </Button>
                              <Button
                                type="button"
                                variant="ghost"
                                size="sm"
                                className="h-7 text-xs text-[#8d7160]"
                                onClick={() => applyPermissionPreset([])}
                              >
                                清空
                              </Button>
                            </div>
                          </div>

                          {memberCommitteeValue &&
                            COMMITTEE_PRESETS.find((preset) => preset.role === memberCommitteeValue) && (
                              <div className="flex flex-wrap gap-2 rounded-xl bg-[#fff8ef] p-3">
                                {COMMITTEE_PRESETS.find((preset) => preset.role === memberCommitteeValue)!.permissions.map(
                                  (permission) => (
                                    <Badge
                                      key={permission}
                                      variant="outline"
                                      className="border-[#dcc6ab] bg-white text-xs text-[#7a5e4f]"
                                    >
                                      {CLASS_PERMISSIONS[permission]}
                                    </Badge>
                                  )
                                )}
                              </div>
                            )}
                        </div>

                        <div className="space-y-3">
                          {PERMISSION_GROUPS.map((group) => (
                            <div key={group.title} className="rounded-xl border border-[#eadbc8] bg-[#fffaf2] p-3">
                              <div className="mb-2">
                                <p className="text-sm font-medium text-[#4e1d1a]">{group.title}</p>
                                <p className="text-xs text-[#8d7160]">{group.description}</p>
                              </div>
                              <div className="grid gap-2 sm:grid-cols-2">
                                {group.permissions.map((permission) => (
                                  <label
                                    key={permission}
                                    className="flex items-center gap-2 rounded-xl border border-transparent px-2 py-2 text-sm text-[#5f4639] hover:border-[#e1cdb6] hover:bg-[#fff8ef]"
                                  >
                                    <input
                                      type="checkbox"
                                      checked={memberPermissionsValue.includes(permission)}
                                      onChange={() => togglePermission(permission)}
                                    />
                                    <span>{CLASS_PERMISSIONS[permission]}</span>
                                  </label>
                                ))}
                              </div>
                            </div>
                          ))}
                        </div>
                      </section>
                    ) : (
                      <section className="rounded-[1.5rem] border border-[#eadbc8] bg-[#fffdf8] p-4">
                        <p className="text-sm text-[#7a5e4f]">当前成员暂无可配置的班级权限项。</p>
                      </section>
                    )}
                  </TabsContent>
                </Tabs>
              </div>

              <div className="flex justify-end gap-2 border-t border-[#eadbc8] bg-[#fffdf8] px-6 py-4">
                <Button
                  variant="outline"
                  onClick={() => {
                    setMemberManagerOpen(false);
                    resetMemberManager();
                  }}
                  disabled={memberSubmitting}
                >
                  取消
                </Button>
                <Button onClick={handleMemberManagerSave} disabled={memberSubmitting}>
                  {memberSubmitting ? "保存中..." : "保存设置"}
                </Button>
              </div>
            </div>
          )}
        </DialogContent>
      </Dialog>
    </div>
  );
}
