"use client";

/**
 * 作业提交页（ai14，P3）
 *
 * - useParams 获取作业 id
 * - useHomeworkDetail 加载作业详情
 * - react-hook-form + zod 校验：每题按类型渲染（简答 textarea / 选择 radio）
 * - 提交按钮调用 useSubmitHomework mutation（execute + useEffect 监听结果）
 * - 成功：toast + 跳转 /my-homework；失败：错误提示
 * - 自动保存草稿到 localStorage（key: homework-draft:${id}），挂载时恢复
 * - 附件上传占位（待 ISSUE-014-05 仲裁）
 */

import { useEffect, useMemo, useRef, useState } from "react";
import { useParams, useRouter } from "next/navigation";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { useHomeworkDetail, useSubmitHomework } from "@/lib/graphql/hooks";
import type { AnswerInput, HomeworkQuestion } from "@/lib/graphql/types";

interface FormValues {
  answers: Record<string, string>;
  note: string;
}

const schema = z.object({
  answers: z.record(z.string(), z.string().min(1, "请填写答案")),
  note: z.string().max(500).optional().or(z.literal("")),
});

const DRAFT_PREFIX = "homework-draft:";
const SAVE_DEBOUNCE_MS = 800;

function draftKey(id: string): string {
  return `${DRAFT_PREFIX}${id}`;
}

function loadDraft(id: string): Partial<FormValues> | null {
  if (typeof window === "undefined") return null;
  try {
    const raw = window.localStorage.getItem(draftKey(id));
    return raw ? (JSON.parse(raw) as Partial<FormValues>) : null;
  } catch {
    return null;
  }
}

function saveDraft(id: string, values: FormValues): void {
  try {
    window.localStorage.setItem(draftKey(id), JSON.stringify(values));
  } catch {
    // 存储失败静默忽略
  }
}

function clearDraft(id: string): void {
  try {
    window.localStorage.removeItem(draftKey(id));
  } catch {
    // 忽略
  }
}

function formatDueAt(iso: string): string {
  try {
    return new Date(iso).toLocaleString("zh-CN", { hour12: false });
  } catch {
    return iso;
  }
}

function isChoice(q: HomeworkQuestion): boolean {
  return q.type === "single-choice" || q.type === "multiple-choice";
}

/** 将表单字符串值转换为 AnswerInput 联合类型 */
function toAnswerInput(question: HomeworkQuestion, value: string): AnswerInput {
  switch (question.type) {
    case "single-choice":
      return { type: "single-choice", optionId: value };
    case "multiple-choice":
      return { type: "multiple-choice", optionIds: [value] };
    case "fill-blank":
      return { type: "fill-blank", values: [value] };
    case "short-answer":
      return { type: "short-answer", text: value };
    case "essay":
      return { type: "essay", text: value };
  }
}

export default function HomeworkSubmitPage(): React.ReactNode {
  const params = useParams();
  const router = useRouter();
  const homeworkId =
    typeof params.id === "string"
      ? params.id
      : Array.isArray(params.id)
        ? (params.id[0] ?? "")
        : "";

  const { data: homework, fetching, error } = useHomeworkDetail(homeworkId);
  const submitMutation = useSubmitHomework();

  const form = useForm<FormValues>({
    defaultValues: { answers: {}, note: "" },
  });
  const { register, handleSubmit, formState, reset, watch, getValues } = form;

  const [toast, setToast] = useState<{
    message: string;
    tone: "success" | "error";
  } | null>(null);
  const [draftRestored, setDraftRestored] = useState(false);
  const restoredRef = useRef(false);
  const submittingRef = useRef(false);

  // 作业详情加载后初始化表单 + 恢复草稿
  useEffect(() => {
    if (!homework || restoredRef.current) return;
    restoredRef.current = true;
    const draft = loadDraft(homeworkId);
    const defaults: FormValues = { answers: {}, note: "" };
    if (draft?.answers) defaults.answers = draft.answers;
    if (draft?.note) defaults.note = draft.note;
    reset(defaults);
    setDraftRestored(
      Boolean(draft?.answers && Object.keys(draft.answers).length > 0),
    );
  }, [homework, homeworkId, reset]);

  // 自动保存草稿（防抖）：每次表单变更后延迟写入 localStorage
  useEffect(() => {
    if (!homework) return;
    let timer: ReturnType<typeof setTimeout> | undefined;
    const subscription = watch(() => {
      if (timer) clearTimeout(timer);
      timer = setTimeout(() => {
        saveDraft(homeworkId, getValues());
      }, SAVE_DEBOUNCE_MS);
    });
    return () => {
      subscription.unsubscribe();
      if (timer) clearTimeout(timer);
    };
  }, [homework, homeworkId, watch, getValues]);

  const showToast = (message: string, tone: "success" | "error"): void => {
    setToast({ message, tone });
    window.setTimeout(() => setToast(null), 2500);
  };

  // 监听 mutation 结果：urql 无 onSuccess/onError 回调，用 useEffect 监听状态变化
  useEffect(() => {
    if (!submittingRef.current) return;
    if (submitMutation.fetching) return; // 仍在请求中

    submittingRef.current = false;

    if (submitMutation.success && submitMutation.data) {
      clearDraft(homeworkId);
      showToast("作业已提交", "success");
      window.setTimeout(() => router.push("/my-homework"), 600);
    } else {
      const message =
        submitMutation.errors[0]?.message ??
        submitMutation.error?.message ??
        "提交失败，请重试";
      showToast(message, "error");
    }
  }, [
    submitMutation.fetching,
    submitMutation.success,
    submitMutation.error,
    submitMutation.errors,
    submitMutation.data,
    homeworkId,
    router,
  ]);

  const questions = useMemo(() => homework?.questions ?? [], [homework]);

  const onSubmit = handleSubmit((values) => {
    // zod 二次校验（与字段 required 双保险）
    const parsed = schema.safeParse(values);
    if (!parsed.success) {
      const first = parsed.error.issues[0];
      showToast(first?.message ?? "请检查答案", "error");
      return;
    }

    const answers = questions.map((q) => {
      const value = values.answers[q.id] ?? "";
      return { questionId: q.id, answer: toAnswerInput(q, value) };
    });

    const payload = {
      homeworkId,
      answers,
      note: values.note || undefined,
    };

    submittingRef.current = true;
    submitMutation.execute(payload);
  });

  if (fetching) {
    return (
      <main className="px-md py-lg max-w-3xl mx-auto">
        <p className="text-sm text-ink-muted" aria-live="polite">
          加载中…
        </p>
      </main>
    );
  }

  if (error) {
    return (
      <main className="px-md py-lg max-w-3xl mx-auto">
        <div className="mark-left py-md px-md mb-md" aria-live="assertive">
          <p className="text-sm text-ink">{error.message || "加载失败"}</p>
          <button
            type="button"
            className="btn-secondary mt-sm"
            onClick={() => router.push("/my-homework")}
          >
            返回作业列表
          </button>
        </div>
      </main>
    );
  }

  if (!homework) {
    return (
      <main className="px-md py-lg max-w-3xl mx-auto">
        <p className="text-sm text-ink-muted">作业不存在或已删除</p>
      </main>
    );
  }

  return (
    <main
      className="px-md py-lg max-w-3xl mx-auto"
      aria-labelledby="homework-submit-title"
    >
      <header className="mb-lg">
        <h1 id="homework-submit-title" className="font-serif text-2xl text-ink">
          {homework.title}
        </h1>
        <p className="mt-xs text-sm text-ink-muted">
          {homework.subject.name}
          {homework.dueAt ? ` · 截止时间：${formatDueAt(homework.dueAt)}` : ""}
        </p>
        {draftRestored ? (
          <p className="mt-xs text-xs text-ink-subtle" role="status">
            已恢复上次的作答草稿
          </p>
        ) : null}
      </header>

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

      <form onSubmit={onSubmit} className="space-y-lg" noValidate>
        {questions.map((q, index) => {
          const fieldName = `answers.${q.id}` as const;
          const fieldError = formState.errors.answers?.[q.id];
          return (
            <fieldset key={q.id} className="card-paper p-md">
              <legend className="font-serif text-base text-ink mb-sm">
                第 {index + 1} 题
                <span
                  className="ml-xs text-xs text-ink-subtle"
                  aria-hidden="true"
                >
                  （{isChoice(q) ? "选择题" : "简答题"}）
                </span>
              </legend>
              <p className="text-sm text-ink mb-md whitespace-pre-wrap">
                {q.content}
              </p>

              {isChoice(q) && q.options && q.options.length > 0 ? (
                <div
                  role="radiogroup"
                  aria-label={`第 ${index + 1} 题选项`}
                  className="space-y-sm"
                >
                  {q.options.map((opt) => (
                    <label
                      key={opt.id}
                      className="flex items-center gap-sm cursor-pointer"
                    >
                      <input
                        type="radio"
                        value={opt.id}
                        {...register(fieldName, { required: "请填写答案" })}
                        aria-label={opt.text}
                      />
                      <span className="text-sm text-ink">{opt.text}</span>
                    </label>
                  ))}
                </div>
              ) : (
                <textarea
                  className="input-paper w-full min-h-24"
                  placeholder="请输入你的答案"
                  aria-label={`第 ${index + 1} 题答案`}
                  {...register(fieldName, { required: "请填写答案" })}
                />
              )}

              {fieldError ? (
                <p className="mt-xs text-xs text-danger" role="alert">
                  {fieldError.message ?? "请填写答案"}
                </p>
              ) : null}
            </fieldset>
          );
        })}

        {/* 备注 */}
        <fieldset className="card-paper p-md">
          <legend className="font-serif text-base text-ink mb-sm">
            备注（选填）
          </legend>
          <textarea
            className="input-paper w-full min-h-16"
            placeholder="对老师说的话…"
            maxLength={500}
            aria-label="备注"
            {...register("note")}
          />
        </fieldset>

        {/* 附件上传占位（待 ISSUE-014-05 仲裁） */}
        <section className="card-paper p-md" aria-label="附件上传">
          <p className="font-serif text-base text-ink mb-sm">附件</p>
          <div
            className="border border-dashed p-lg text-center"
            style={{ borderColor: "var(--color-rule)" }}
            role="note"
          >
            <p className="text-sm text-ink-muted">
              附件上传功能待 ISSUE-014-05 仲裁
            </p>
            <p className="mt-xs text-xs text-ink-subtle">
              支持图片 / PDF，最多 5 个，单个不超过 10MB
            </p>
          </div>
        </section>

        <div
          className="sticky bottom-0 -mx-md px-md py-md"
          style={{ background: "var(--color-paper)" }}
        >
          <button
            type="submit"
            className="btn-primary w-full"
            disabled={submitMutation.fetching}
            aria-busy={submitMutation.fetching}
          >
            {submitMutation.fetching ? "提交中…" : "提交作业"}
          </button>
        </div>
      </form>

      {toast ? (
        <div
          className="fixed bottom-md left-1/2 -translate-x-1/2 card-paper px-lg py-md text-sm"
          role="alert"
          aria-live="assertive"
          style={{
            color:
              toast.tone === "success"
                ? "var(--color-success)"
                : "var(--color-danger)",
          }}
        >
          {toast.message}
        </div>
      ) : null}
    </main>
  );
}
