"use client";

/**
 * MyHomework — 我的作业列表（ai14）
 *
 * 数据源：useMyHomework + useRequestExtension GraphQL hook
 * 视图：按状态分组（pending / overdue / submitted / graded）
 *      每张卡片：标题 + 学科 + 截止时间 + 状态徽标
 * 功能：学科筛选 / 申请延期（pending & overdue）/ 查看分析（graded）
 * 链接：pending → /my-homework/[id]/submit
 *      graded → /my-homework/[id]/analysis
 *
 * 设计依据：01-understanding.md §8（L2 路由表）
 *          02-architecture-design.md §15（详细组件设计）
 */

import { useState, useMemo, useCallback, useEffect } from "react";
import Link from "next/link";
import {
  useMyHomework,
  useRequestExtension,
} from "@/lib/graphql/hooks";
import type { HomeworkListItem, HomeworkStatus } from "@/lib/graphql/types";

const dateFormatter = new Intl.DateTimeFormat("zh-CN", {
  month: "2-digit",
  day: "2-digit",
  hour: "2-digit",
  minute: "2-digit",
});

// 状态分组配置（顺序即展示顺序）
const STATUS_GROUPS: Array<{
  key: HomeworkStatus;
  label: string;
  description: string;
}> = [
  {
    key: "pending",
    label: "待提交",
    description: "点击进入提交",
  },
  {
    key: "overdue",
    label: "已逾期",
    description: "请尽快提交",
  },
  {
    key: "submitted",
    label: "已提交",
    description: "等待批改",
  },
  {
    key: "graded",
    label: "已批改",
    description: "查看得分",
  },
];

type SubjectFilter = "all" | string;

export default function MyHomeworkPage(): JSX.Element {
  const { data, fetching, error, reexecute } = useMyHomework();
  const homework = data ?? [];
  const [subjectFilter, setSubjectFilter] = useState<SubjectFilter>("all");
  const [extensionTarget, setExtensionTarget] = useState<HomeworkListItem | null>(null);
  const [extensionReason, setExtensionReason] = useState("");
  const [feedback, setFeedback] = useState<
    { type: "success" | "error"; message: string } | null
  >(null);

  const {
    execute: executeExtension,
    fetching: extFetching,
    data: extData,
    success: extSuccess,
    errors: extErrors,
  } = useRequestExtension();

  // 提取所有学科选项（去重）
  const subjectOptions = useMemo(() => {
    const map = new Map<string, string>();
    homework.forEach((h) => {
      map.set(h.subject.id, h.subject.name);
    });
    return Array.from(map.entries()).map(([id, name]) => ({ id, name }));
  }, [homework]);

  // 按学科筛选
  const filteredHomework = useMemo(() => {
    if (subjectFilter === "all") return homework;
    return homework.filter((h) => h.subject.id === subjectFilter);
  }, [homework, subjectFilter]);

  // 按状态分组
  const grouped = STATUS_GROUPS.map((g) => ({
    ...g,
    items: filteredHomework.filter((h) => h.status === g.key),
  }));

  // 响应延期申请结果
  useEffect(() => {
    if (!extFetching && extData !== null && extensionTarget) {
      if (extSuccess && extData) {
        setFeedback({
          type: "success",
          message: `延期申请已通过，新截止时间：${dateFormatter.format(
            new Date(extData.newDueDate),
          )}`,
        });
        setExtensionTarget(null);
        setExtensionReason("");
        reexecute();
      } else if (!extSuccess) {
        const errMsg = extErrors[0]?.message ?? "延期申请失败";
        setFeedback({ type: "error", message: errMsg });
        setExtensionTarget(null);
      }
    }
  }, [extData, extSuccess, extErrors, extFetching, extensionTarget, reexecute]);

  const handleRequestExtension = useCallback(
    (hw: HomeworkListItem): void => {
      setExtensionTarget(hw);
      setExtensionReason("");
    },
    [],
  );

  const handleSubmitExtension = useCallback((): void => {
    if (!extensionTarget) return;
    if (!extensionReason.trim()) {
      setFeedback({ type: "error", message: "请填写延期原因" });
      return;
    }
    executeExtension({
      homeworkId: extensionTarget.id,
      reason: extensionReason.trim(),
    });
  }, [extensionTarget, extensionReason, executeExtension]);

  const handleCloseExtension = useCallback((): void => {
    setExtensionTarget(null);
    setExtensionReason("");
  }, []);

  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>

      {/* 学科筛选 */}
      {homework.length > 0 && (
        <div
          className="mb-md flex items-center gap-sm flex-wrap"
          role="group"
          aria-label="学科筛选"
        >
          <span
            className="text-xs uppercase tracking-wider"
            style={{ color: "var(--color-ink-muted)" }}
          >
            学科：
          </span>
          <button
            type="button"
            onClick={() => setSubjectFilter("all")}
            className="px-sm py-xs text-xs rounded-sm"
            style={{
              background:
                subjectFilter === "all"
                  ? "var(--color-accent)"
                  : "transparent",
              color:
                subjectFilter === "all"
                  ? "var(--color-paper)"
                  : "var(--color-ink)",
              border: "1px solid var(--color-rule)",
            }}
            aria-pressed={subjectFilter === "all"}
          >
            全部
          </button>
          {subjectOptions.map((subj) => (
            <button
              key={subj.id}
              type="button"
              onClick={() => setSubjectFilter(subj.id)}
              className="px-sm py-xs text-xs rounded-sm"
              style={{
                background:
                  subjectFilter === subj.id
                    ? "var(--color-accent)"
                    : "transparent",
                color:
                  subjectFilter === subj.id
                    ? "var(--color-paper)"
                    : "var(--color-ink)",
                border: "1px solid var(--color-rule)",
              }}
              aria-pressed={subjectFilter === subj.id}
            >
              {subj.name}
            </button>
          ))}
        </div>
      )}

      <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} />
      ) : filteredHomework.length === 0 ? (
        <EmptyState />
      ) : (
        <div className="space-y-10">
          {grouped.map(
            (group) =>
              group.items.length > 0 && (
                <section key={group.key} aria-label={group.label}>
                  <div className="flex items-baseline gap-3 mb-4">
                    <h2
                      className="text-lg font-serif"
                      style={{ color: "var(--color-ink)" }}
                    >
                      {group.label}
                    </h2>
                    <span
                      className="text-xs"
                      style={{ color: "var(--color-ink-muted)" }}
                    >
                      {group.items.length} 份 · {group.description}
                    </span>
                  </div>
                  <div className="rule-thin mb-4" />
                  <ul className="grid grid-cols-1 lg:grid-cols-2 gap-4">
                    {group.items.map((hw) => (
                      <li key={hw.id}>
                        <HomeworkCard
                          homework={hw}
                          onRequestExtension={handleRequestExtension}
                        />
                      </li>
                    ))}
                  </ul>
                </section>
              ),
          )}
        </div>
      )}

      {/* 延期申请对话框 */}
      {extensionTarget && (
        <div
          className="fixed inset-0 z-50 flex items-center justify-center p-md"
          style={{ background: "rgba(0,0,0,0.5)" }}
          role="dialog"
          aria-modal="true"
          aria-labelledby="extension-title"
          onClick={(e) => {
            if (e.target === e.currentTarget && !extFetching) {
              handleCloseExtension();
            }
          }}
        >
          <div
            className="w-full max-w-md card-paper p-lg"
            style={{ background: "var(--color-paper)" }}
            onClick={(e) => e.stopPropagation()}
          >
            <h3
              id="extension-title"
              className="font-serif text-xl mb-md"
              style={{ color: "var(--color-ink)" }}
            >
              申请作业延期
            </h3>
            <p
              className="text-sm mb-md"
              style={{ color: "var(--color-ink-muted)" }}
            >
              作业：{extensionTarget.title}
            </p>
            <label
              htmlFor="ext-reason"
              className="block text-xs mb-xs"
              style={{ color: "var(--color-ink-muted)" }}
            >
              延期原因
            </label>
            <textarea
              id="ext-reason"
              value={extensionReason}
              onChange={(e) => setExtensionReason(e.target.value)}
              rows={3}
              placeholder="请说明延期原因…"
              className="w-full input-paper"
              aria-label="延期原因"
            />
            <div className="mt-md flex justify-end gap-sm">
              <button
                type="button"
                onClick={handleCloseExtension}
                disabled={extFetching}
                className="btn-secondary"
              >
                取消
              </button>
              <button
                type="button"
                onClick={handleSubmitExtension}
                disabled={extFetching || !extensionReason.trim()}
                className="btn-primary"
              >
                {extFetching ? "申请中…" : "提交申请"}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

function HomeworkCard({
  homework,
  onRequestExtension,
}: {
  homework: HomeworkListItem;
  onRequestExtension: (hw: HomeworkListItem) => void;
}): JSX.Element {
  const dueAt = new Date(homework.dueAt);
  const isPending = homework.status === "pending";
  const isOverdue = homework.status === "overdue";
  const isGraded = homework.status === "graded";
  const canRequestExtension = isPending || isOverdue;
  const submitHref = isPending || isOverdue ? `/my-homework/${homework.id}/submit` : null;
  const analysisHref = isGraded ? `/my-homework/${homework.id}/analysis` : null;

  const badgeClass = getBadgeClassForStatus(homework.status);

  // 截止时间紧迫度（仅 pending 显示）
  const now = new Date();
  const isUrgent =
    isPending &&
    dueAt.getTime() - now.getTime() > 0 &&
    dueAt.getTime() - now.getTime() < 24 * 60 * 60 * 1000;

  const inner = (
    <article
      className="card-paper p-5 h-full"
      aria-label={`${homework.title} - ${homework.status}`}
    >
      <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)" }}
          >
            {homework.subject.name}
          </p>
          <h3
            className="mt-1 text-lg font-serif text-truncate"
            style={{ color: "var(--color-ink)" }}
          >
            {homework.title}
          </h3>
        </div>
        <span className={`badge ${badgeClass} flex-shrink-0`}>
          {getStatusLabel(homework.status)}
        </span>
      </div>

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

      <dl className="space-y-2 text-xs">
        <div className="flex items-baseline justify-between gap-2">
          <dt
            className="uppercase tracking-wider"
            style={{ color: "var(--color-ink-muted)" }}
          >
            截止时间
          </dt>
          <dd
            style={{
              color: isOverdue
                ? "var(--color-danger)"
                : isUrgent
                  ? "var(--color-warning)"
                  : "var(--color-ink)",
            }}
          >
            {dateFormatter.format(dueAt)}
            {isOverdue && " · 已逾期"}
            {isUrgent && " · 24h 内"}
          </dd>
        </div>
        <div className="flex items-baseline justify-between gap-2">
          <dt
            className="uppercase tracking-wider"
            style={{ color: "var(--color-ink-muted)" }}
          >
            题量
          </dt>
          <dd style={{ color: "var(--color-ink)" }}>
            {homework.questionCount} 题
          </dd>
        </div>
        {isGraded && homework.score !== undefined && (
          <div className="flex items-baseline justify-between gap-2">
            <dt
              className="uppercase tracking-wider"
              style={{ color: "var(--color-ink-muted)" }}
            >
              得分
            </dt>
            <dd
              className="text-base font-serif"
              style={{ color: "var(--color-accent)" }}
            >
              {homework.score}
              <span
                className="text-xs font-sans"
                style={{ color: "var(--color-ink-muted)" }}
              >
                {" "}
                / {homework.totalScore}
              </span>
            </dd>
          </div>
        )}
      </dl>

      {/* 操作按钮区 */}
      <div className="mt-4 flex items-center gap-sm">
        {submitHref && (
          <Link
            href={submitHref}
            className="btn-primary text-xs"
            aria-label={`${homework.title} - 进入提交`}
          >
            进入提交 →
          </Link>
        )}
        {canRequestExtension && (
          <button
            type="button"
            onClick={(e) => {
              e.preventDefault();
              e.stopPropagation();
              onRequestExtension(homework);
            }}
            className="btn-secondary text-xs"
            aria-label={`申请延期 ${homework.title}`}
          >
            申请延期
          </button>
        )}
        {analysisHref && (
          <Link
            href={analysisHref}
            className="btn-secondary text-xs"
            aria-label={`查看分析 ${homework.title}`}
          >
            查看分析
          </Link>
        )}
      </div>
    </article>
  );

  return inner;
}

function getBadgeClassForStatus(status: HomeworkStatus): string {
  switch (status) {
    case "pending":
      return "badge-warning";
    case "submitted":
      return "badge-info";
    case "graded":
      return "badge-success";
    case "overdue":
      return "badge-danger";
    default:
      return "badge-info";
  }
}

function getStatusLabel(status: HomeworkStatus): string {
  const map: Record<HomeworkStatus, string> = {
    pending: "待提交",
    submitted: "已提交",
    graded: "已批改",
    overdue: "已逾期",
  };
  return map[status] ?? status;
}

function LoadingSkeleton(): JSX.Element {
  return (
    <div aria-busy="true" aria-live="polite" className="space-y-10">
      {[0, 1].map((i) => (
        <div key={i} aria-hidden="true">
          <div
            className="h-4 w-24 rounded-sm animate-pulse mb-4"
            style={{ background: "var(--color-rule)" }}
          />
          <div className="rule-thin mb-4" />
          <ul className="grid grid-cols-1 lg:grid-cols-2 gap-4">
            {[0, 1].map((j) => (
              <li key={j} className="card-paper p-5">
                <div
                  className="h-3 w-16 rounded-sm animate-pulse"
                  style={{ background: "var(--color-rule)" }}
                />
                <div
                  className="mt-2 h-5 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 space-y-2">
                  {[0, 1].map((k) => (
                    <div
                      key={k}
                      className="h-3 w-32 rounded-sm animate-pulse"
                      style={{ background: "var(--color-rule)" }}
                    />
                  ))}
                </div>
              </li>
            ))}
          </ul>
        </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(): 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>
  );
}
