"use client";

/**
 * Elective — 选课中心（批次 A）
 *
 * 数据源：useAvailableElectiveCourses + useMyElectiveSelections
 *         + useSelectElectiveCourse + useDropElectiveCourse
 * 视图：我的选课 + 可选课程列表（容量进度 + 选课/退选操作）
 */

import Link from "next/link";
import {
  useAvailableElectiveCourses,
  useMyElectiveSelections,
  useSelectElectiveCourse,
  useDropElectiveCourse,
} from "@/lib/graphql/hooks";
import type { CourseSelectionStatus, ElectiveCourse, ElectiveCourseStatus } from "@/lib/graphql/types";

const COURSE_STATUS_LABELS: Record<ElectiveCourseStatus, string> = {
  draft: "草稿",
  open: "开放选课",
  closed: "已截止",
  cancelled: "已取消",
};

const SELECTION_STATUS_LABELS: Record<CourseSelectionStatus, string> = {
  selected: "已选",
  enrolled: "已录取",
  waitlist: "候补",
  dropped: "已退选",
  rejected: "未录取",
};

export default function ElectivePage(): JSX.Element {
  const { data: courses, fetching, error, reexecute } = useAvailableElectiveCourses();
  const { data: selections, reexecute: reexecuteSelections } = useMyElectiveSelections();
  const { execute: selectExecute } = useSelectElectiveCourse();
  const { execute: dropExecute } = useDropElectiveCourse();

  const availableCourses = courses ?? [];
  const mySelections = selections ?? [];

  const handleSelect = (courseId: string): void => {
    selectExecute({ courseId });
    reexecute();
    reexecuteSelections();
  };

  const handleDrop = (courseId: string): void => {
    dropExecute({ courseId });
    reexecute();
    reexecuteSelections();
  };

  return (
    <div className="px-6 lg:px-10 py-8 lg:py-10 max-w-7xl mx-auto">
      <header className="mb-6">
        <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>
      </header>

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

      {mySelections.length > 0 && (
        <section className="mb-8">
          <h2 className="text-base font-serif mb-4" style={{ color: "var(--color-ink)" }}>
            我的选课
          </h2>
          <ul className="space-y-3">
            {mySelections.map((sel) => (
              <li key={sel.id}>
                <article className="card-paper p-4 flex items-center justify-between gap-4">
                  <div className="min-w-0 flex-1">
                    <div className="flex items-center gap-2 mb-1">
                      <span className="badge badge-success">
                        {SELECTION_STATUS_LABELS[sel.status]}
                      </span>
                      <span className="text-xs" style={{ color: "var(--color-ink-muted)" }}>
                        学分 {sel.course.credit}
                      </span>
                    </div>
                    <Link
                      href={`/elective/${sel.courseId}`}
                      className="text-sm font-medium hover:underline"
                      style={{ color: "var(--color-ink)" }}
                    >
                      {sel.courseName}
                    </Link>
                    <p className="mt-1 text-xs" style={{ color: "var(--color-ink-muted)" }}>
                      {sel.course.teacherName ?? "—"} · {sel.course.schedule ?? "—"}
                    </p>
                  </div>
                  {sel.status === "enrolled" && (
                    <button
                      type="button"
                      onClick={() => handleDrop(sel.courseId)}
                      className="btn-secondary text-xs flex-shrink-0"
                    >
                      退选
                    </button>
                  )}
                </article>
              </li>
            ))}
          </ul>
        </section>
      )}

      <section>
        <h2 className="text-base font-serif mb-4" style={{ color: "var(--color-ink)" }}>
          可选课程
        </h2>
        {fetching ? (
          <LoadingSkeleton />
        ) : error ? (
          <ErrorState message={error.message} onRetry={() => reexecute()} />
        ) : availableCourses.length === 0 ? (
          <EmptyState />
        ) : (
          <ul className="space-y-4">
            {availableCourses.map((course) => (
              <CourseCard
                key={course.id}
                course={course}
                enrolled={mySelections.some(
                  (s) => s.courseId === course.id && (s.status === "enrolled" || s.status === "selected"),
                )}
                onSelect={() => handleSelect(course.id)}
              />
            ))}
          </ul>
        )}
      </section>
    </div>
  );
}

function CourseCard({
  course,
  enrolled,
  onSelect,
}: {
  course: ElectiveCourse;
  enrolled: boolean;
  onSelect: () => void;
}): JSX.Element {
  const fillRate = course.capacity > 0 ? course.enrolledCount / course.capacity : 0;
  const isFull = course.enrolledCount >= course.capacity;

  return (
    <li>
      <article className="card-paper p-5">
        <div className="flex items-start justify-between gap-4 mb-2">
          <div className="flex items-center gap-2">
            <span className="badge badge-info">{course.subjectName ?? "—"}</span>
            <span className={`badge ${course.status === "open" ? "badge-success" : "badge-warning"}`}>
              {COURSE_STATUS_LABELS[course.status]}
            </span>
          </div>
          <span className="text-xs" style={{ color: "var(--color-ink-muted)" }}>
            {course.selectionMode === "fcfs" ? "先到先得" : "抽签"}
          </span>
        </div>
        <Link
          href={`/elective/${course.id}`}
          className="text-base font-serif hover:underline"
          style={{ color: "var(--color-ink)" }}
        >
          {course.name}
        </Link>
        {course.description && (
          <p className="mt-1 text-sm" style={{ color: "var(--color-ink-muted)" }}>
            {course.description}
          </p>
        )}
        <div className="mt-3 grid grid-cols-2 md:grid-cols-4 gap-3 text-xs" style={{ color: "var(--color-ink-muted)" }}>
          <span>教师：{course.teacherName ?? "—"}</span>
          <span>教室：{course.classroom ?? "—"}</span>
          <span>时间：{course.schedule ?? "—"}</span>
          <span>学分：{course.credit}</span>
        </div>
        <div className="mt-3 flex items-center gap-3">
          <div className="flex-1 h-2 rounded-sm overflow-hidden" style={{ background: "var(--color-rule)" }}>
            <div
              className="h-full"
              style={{
                width: `${Math.min(fillRate * 100, 100)}%`,
                background: isFull ? "var(--color-danger)" : "var(--color-accent)",
              }}
            />
          </div>
          <span className="text-xs flex-shrink-0" style={{ color: "var(--color-ink-muted)" }}>
            {course.enrolledCount}/{course.capacity}
          </span>
          {course.status === "open" && !enrolled && (
            <button
              type="button"
              onClick={onSelect}
              disabled={isFull}
              className="btn-primary text-xs flex-shrink-0 disabled:opacity-50"
            >
              {isFull ? "已满" : "选课"}
            </button>
          )}
          {enrolled && (
            <span className="text-xs flex-shrink-0" style={{ color: "var(--color-success)" }}>
              已选
            </span>
          )}
        </div>
      </article>
    </li>
  );
}

function LoadingSkeleton(): JSX.Element {
  return (
    <div className="space-y-4" aria-busy="true" aria-live="polite">
      {[0, 1, 2].map((i) => (
        <div
          key={i}
          className="h-36 animate-pulse rounded-sm"
          style={{ background: "var(--color-rule)", opacity: 0.3 }}
        />
      ))}
      <span className="sr-only">正在加载可选课程...</span>
    </div>
  );
}

function ErrorState({ message, onRetry }: { message: string; onRetry: () => void }): 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={onRetry} className="mt-4 btn-secondary text-xs">
        重新加载
      </button>
    </div>
  );
}

function EmptyState(): 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>
    </div>
  );
}
