"use client";

/**
 * MyClasses — 我的班级（ai14）
 *
 * 数据源：useMyClasses + useLeaveClass GraphQL hook
 * 视图：班级卡片网格（班级名 + 班主任 + 学生数 + 年级 + 学年）
 * 功能：加入班级（JoinClassModal）/ 退出班级（确认后调用 leaveClass）
 *
 * 设计依据：01-understanding.md §7 L1 视口（my-classes）
 *          02-architecture-design.md §14.4（CSR）
 */

import { useState, useCallback, useEffect } from "react";
import {
  useMyClasses,
  useLeaveClass,
} from "@/lib/graphql/hooks";
import type { ClassInfo } from "@/lib/graphql/types";
import { JoinClassModal } from "@/components/join-class-modal";

export default function MyClassesPage(): JSX.Element {
  const { data, fetching, error, reexecute } = useMyClasses();
  const classes = data ?? [];
  const [modalOpen, setModalOpen] = useState(false);
  const [leavingClassId, setLeavingClassId] = useState<string | null>(null);
  const [feedback, setFeedback] = useState<
    { type: "success" | "error"; message: string } | null
  >(null);

  const {
    execute: executeLeave,
    fetching: leaveFetching,
    data: leaveData,
    success: leaveSuccess,
    errors: leaveErrors,
  } = useLeaveClass();

  // 响应退出班级结果
  useEffect(() => {
    if (!leaveFetching && leaveData !== null && leavingClassId !== null) {
      if (leaveSuccess) {
        setFeedback({ type: "success", message: "已退出班级" });
        setLeavingClassId(null);
        reexecute();
      } else if (!leaveSuccess) {
        const errMsg = leaveErrors[0]?.message ?? "退出失败";
        setFeedback({ type: "error", message: errMsg });
        setLeavingClassId(null);
      }
    }
  }, [
    leaveData,
    leaveSuccess,
    leaveErrors,
    leaveFetching,
    leavingClassId,
    reexecute,
  ]);

  const handleOpenModal = useCallback((): void => {
    setModalOpen(true);
  }, []);

  const handleCloseModal = useCallback((): void => {
    setModalOpen(false);
  }, []);

  const handleJoined = useCallback(
    (_className: string): void => {
      setFeedback({ type: "success", message: "加入班级成功" });
      reexecute();
    },
    [reexecute],
  );

  const handleLeaveClass = useCallback((classId: string): void => {
    setLeavingClassId(classId);
    executeLeave({ classId });
  }, [executeLeave]);

  const handleConfirmLeave = useCallback(
    (classId: string): void => {
      if (
        window.confirm("确定要退出该班级吗？退出后将无法查看该班级的作业与通知。")
      ) {
        handleLeaveClass(classId);
      }
    },
    [handleLeaveClass],
  );

  return (
    <div className="px-6 lg:px-10 py-8 lg:py-10 max-w-7xl mx-auto">
      <header className="mb-6">
        <div className="flex items-start justify-between gap-md">
          <div className="min-w-0 flex-1">
            <p
              className="text-xs uppercase tracking-wider"
              style={{ color: "var(--color-ink-muted)" }}
            >
              学习场景
            </p>
            <h1
              className="mt-2 text-3xl lg:text-4xl font-serif"
              style={{ color: "var(--color-ink)" }}
            >
              我的班级
            </h1>
            <p
              className="mt-2 text-sm"
              style={{ color: "var(--color-ink-muted)" }}
            >
              查看你所在的班级、班主任与同学人数。
            </p>
          </div>
          <button
            type="button"
            onClick={handleOpenModal}
            className="btn-primary flex-shrink-0"
          >
            加入班级
          </button>
        </div>
      </header>

      <div className="rule-thin mb-8" />

      {feedback && (
        <div
          className="mb-md p-sm rounded text-sm"
          role="alert"
          style={{
            color:
              feedback.type === "success"
                ? "var(--color-success)"
                : "var(--color-danger)",
            background:
              feedback.type === "success"
                ? "hsl(var(--hue-success), var(--sat-success), 95%)"
                : "hsl(var(--hue-danger), var(--sat-danger), 95%)",
          }}
        >
          {feedback.message}
        </div>
      )}

      {fetching ? (
        <LoadingSkeleton />
      ) : error ? (
        <ErrorState message={error.message} />
      ) : classes.length === 0 ? (
        <EmptyState onJoin={handleOpenModal} />
      ) : (
        <section
          aria-label="班级列表"
          className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-5"
        >
          {classes.map((cls) => (
            <ClassCard
              key={cls.id}
              cls={cls}
              onLeave={handleConfirmLeave}
              leaving={leavingClassId === cls.id && leaveFetching}
            />
          ))}
        </section>
      )}

      <JoinClassModal
        open={modalOpen}
        onClose={handleCloseModal}
        onJoined={handleJoined}
      />
    </div>
  );
}

function ClassCard({
  cls,
  onLeave,
  leaving,
}: {
  cls: ClassInfo;
  onLeave: (classId: string) => void;
  leaving: boolean;
}): JSX.Element {
  return (
    <article className="card-paper p-6 flex flex-col">
      <div className="flex items-start justify-between gap-3">
        <div className="min-w-0 flex-1">
          <p
            className="text-xs uppercase tracking-wider"
            style={{ color: "var(--color-ink-muted)" }}
          >
            {cls.grade} · {cls.year} 学年
          </p>
          <h2
            className="mt-2 text-2xl font-serif text-truncate"
            style={{ color: "var(--color-ink)" }}
          >
            {cls.name}
          </h2>
        </div>
        <span
          className="badge badge-info flex-shrink-0"
          aria-label={`共 ${cls.studentCount} 名学生`}
        >
          {cls.studentCount} 人
        </span>
      </div>

      <div className="rule-thin my-4" />

      <dl className="space-y-2 text-sm">
        <div className="flex items-baseline justify-between">
          <dt
            className="text-xs uppercase tracking-wider"
            style={{ color: "var(--color-ink-muted)" }}
          >
            班主任
          </dt>
          <dd style={{ color: "var(--color-ink)" }}>{cls.homeroomTeacher}</dd>
        </div>
      </dl>

      <div className="mt-auto pt-4">
        <button
          type="button"
          onClick={() => onLeave(cls.id)}
          disabled={leaving}
          className="btn-secondary text-xs"
          aria-label={`退出班级 ${cls.name}`}
        >
          {leaving ? "退出中…" : "退出班级"}
        </button>
      </div>
    </article>
  );
}

function LoadingSkeleton(): JSX.Element {
  return (
    <div
      aria-busy="true"
      aria-live="polite"
      className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-5"
    >
      {[0, 1, 2].map((i) => (
        <div key={i} className="card-paper p-6" aria-hidden="true">
          <div
            className="h-3 w-20 rounded-sm animate-pulse"
            style={{ background: "var(--color-rule)" }}
          />
          <div
            className="mt-3 h-7 w-32 rounded-sm animate-pulse"
            style={{ background: "var(--color-rule)" }}
          />
          <div
            className="mt-6 h-px w-full"
            style={{ background: "var(--color-rule)" }}
          />
          <div
            className="mt-4 h-4 w-24 rounded-sm animate-pulse"
            style={{ background: "var(--color-rule)" }}
          />
        </div>
      ))}
      <span className="sr-only">正在加载班级列表...</span>
    </div>
  );
}

function ErrorState({ message }: { message: string }): JSX.Element {
  return (
    <div
      role="alert"
      className="card-paper p-8 text-center"
      style={{ borderColor: "var(--color-danger)" }}
    >
      <p
        className="text-base font-serif"
        style={{ color: "var(--color-danger)" }}
      >
        班级列表加载失败
      </p>
      <p className="mt-2 text-sm" style={{ color: "var(--color-ink-muted)" }}>
        {message}
      </p>
      <button
        type="button"
        onClick={() => window.location.reload()}
        className="mt-4 btn-secondary text-xs"
      >
        重新加载
      </button>
    </div>
  );
}

function EmptyState({ onJoin }: { onJoin: () => void }): JSX.Element {
  return (
    <div className="card-paper p-8 text-center">
      <p
        className="text-4xl font-serif"
        style={{ color: "var(--color-ink-subtle)" }}
        aria-hidden="true"
      >
        ⌂
      </p>
      <p
        className="mt-4 text-base font-serif"
        style={{ color: "var(--color-ink)" }}
      >
        暂未分配到班级
      </p>
      <p className="mt-2 text-sm" style={{ color: "var(--color-ink-muted)" }}>
        请联系班主任或教务老师为你分配班级，或使用邀请码加入班级。
      </p>
      <button
        type="button"
        onClick={onJoin}
        className="mt-4 btn-primary"
      >
        加入班级
      </button>
    </div>
  );
}
