"use client";

import { type ReactNode, useState, useEffect, useMemo } from "react";
import {
  useInvitationCodes,
  useInvitationCodeFilter,
  useGenerateInvitationCodes,
  useDeleteInvitationCodes,
} from "@/hooks/use-invitation-codes";
import { useRoles } from "@/hooks/use-roles";
import { useClasses } from "@/hooks/use-classes";
import { useToast } from "@/providers/toast-provider";
import {
  PageHeader,
  PaperCard,
  Input,
  Select,
  Button,
  Badge,
  LoadingState,
  ErrorState,
  EmptyState,
  Table,
  TableRow,
  TableCell,
  Pagination,
} from "@/components/ui";
import { t } from "@/lib/i18n";

export default function InvitationCodesPage(): ReactNode {
  const { filter, setPage, setSearch, setStatus } = useInvitationCodeFilter();
  const { data, loading, error } = useInvitationCodes(filter);
  const { data: roles } = useRoles();
  const { data: classesData } = useClasses({ page: 1, pageSize: 100 });
  const { show } = useToast();
  const [generateCodes] = useGenerateInvitationCodes();
  const [deleteCodes] = useDeleteInvitationCodes();
  const [searchInput, setSearchInput] = useState("");
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());

  // 生成对话框
  const [generateOpen, setGenerateOpen] = useState(false);
  const [genCount, setGenCount] = useState(10);
  const [genRoleId, setGenRoleId] = useState("");
  const [genClassId, setGenClassId] = useState("");
  const [genEmail, setGenEmail] = useState("");
  const [generating, setGenerating] = useState(false);

  // 生成结果对话框
  const [resultOpen, setResultOpen] = useState(false);
  const [generatedCodes, setGeneratedCodes] = useState<string[]>([]);
  const [generatedBatchId, setGeneratedBatchId] = useState("");

  useEffect(() => {
    const timer = setTimeout(() => setSearch(searchInput), 300);
    return () => clearTimeout(timer);
  }, [searchInput, setSearch]);

  const classes = useMemo(() => classesData?.items ?? [], [classesData]);

  const allChecked = useMemo(
    () =>
      data !== null &&
      data.items.length > 0 &&
      data.items.every((ic) => selectedIds.has(ic.id)),
    [data, selectedIds],
  );

  const toggleSelect = (id: string) => {
    setSelectedIds((prev) => {
      const next = new Set(prev);
      if (next.has(id)) {
        next.delete(id);
      } else {
        next.add(id);
      }
      return next;
    });
  };

  const toggleSelectAll = () => {
    if (!data) return;
    if (allChecked) {
      setSelectedIds(new Set());
    } else {
      setSelectedIds(new Set(data.items.map((ic) => ic.id)));
    }
  };

  const openGenerateDialog = () => {
    setGenCount(10);
    setGenRoleId("");
    setGenClassId("");
    setGenEmail("");
    setGenerateOpen(true);
  };

  const handleGenerate = async () => {
    if (genCount < 1 || genCount > 1000) {
      show("warning", "数量范围 1-1000");
      return;
    }
    setGenerating(true);
    try {
      const result = await generateCodes({
        count: genCount,
        roleId: genRoleId || undefined,
        classId: genClassId || undefined,
        email: genEmail || undefined,
      });
      if (result) {
        show(
          "success",
          t("admin.invitationCodes.generateSuccess", {
            count: result.codes.length,
          }),
        );
        setGeneratedCodes(result.codes);
        setGeneratedBatchId(result.batchId);
        setGenerateOpen(false);
        setResultOpen(true);
      }
    } catch (err) {
      show(
        "error",
        "生成失败",
        err instanceof Error ? err.message : String(err),
      );
    } finally {
      setGenerating(false);
    }
  };

  const handleBatchDelete = async () => {
    if (selectedIds.size === 0) {
      show("warning", "请先选择要删除的邀请码");
      return;
    }
    if (!window.confirm(`确认删除选中的 ${selectedIds.size} 个邀请码？`)) {
      return;
    }
    try {
      const ok = await deleteCodes(Array.from(selectedIds));
      if (ok) {
        show("success", "删除成功");
        setSelectedIds(new Set());
        window.location.reload();
      }
    } catch (err) {
      show(
        "error",
        "删除失败",
        err instanceof Error ? err.message : String(err),
      );
    }
  };

  const handleCopyCodes = async () => {
    try {
      await navigator.clipboard.writeText(generatedCodes.join("\n"));
      show("success", "已复制到剪贴板");
    } catch {
      show("error", "复制失败");
    }
  };

  return (
    <div style={{ padding: 32, maxWidth: 1200, margin: "0 auto" }}>
      <PageHeader
        title={t("admin.invitationCodes.title")}
        description="批量生成、管理与清理邀请码"
        actions={
          <Button variant="primary" onClick={openGenerateDialog}>
            {t("admin.invitationCodes.generate")}
          </Button>
        }
      />

      <PaperCard className="p-4 mb-4">
        <div className="flex gap-3 items-center flex-wrap">
          <Input
            type="search"
            placeholder={t("admin.common.search")}
            value={searchInput}
            onChange={(e) => setSearchInput(e.target.value)}
            style={{ width: 240 }}
          />
          <Select
            value={filter.status ?? "all"}
            onChange={(e) => setStatus(e.target.value)}
          >
            <option value="all">{t("admin.common.all")}</option>
            <option value="unused">{t("admin.invitationCodes.unused")}</option>
            <option value="used">{t("admin.invitationCodes.used")}</option>
            <option value="expired">
              {t("admin.invitationCodes.expired")}
            </option>
          </Select>
          {selectedIds.size > 0 && (
            <Button variant="danger" onClick={handleBatchDelete}>
              {t("admin.common.delete")}（{selectedIds.size}）
            </Button>
          )}
        </div>
      </PaperCard>

      <PaperCard className="p-4">
        {loading && <LoadingState />}
        {error && <ErrorState message={error.message} />}
        {!loading && !error && data && (
          <>
            {data.items.length === 0 ? (
              <EmptyState message={t("admin.common.empty")} />
            ) : (
              <>
                <Table
                  headers={[
                    "",
                    t("admin.invitationCodes.code"),
                    t("admin.common.status"),
                    t("admin.common.role"),
                    t("admin.common.class"),
                    t("admin.common.email"),
                    t("admin.invitationCodes.batch"),
                    t("admin.invitationCodes.usedBy"),
                    t("admin.invitationCodes.usedAt"),
                    t("admin.common.createdAt"),
                    t("admin.invitationCodes.expiresAt"),
                  ]}
                >
                  {data.items.map((ic) => (
                    <TableRow key={ic.id}>
                      <TableCell style={{ width: 32 }}>
                        <input
                          type="checkbox"
                          checked={selectedIds.has(ic.id)}
                          onChange={() => toggleSelect(ic.id)}
                          aria-label={`select ${ic.code}`}
                        />
                      </TableCell>
                      <TableCell>
                        <span
                          style={{
                            fontFamily: "var(--font-mono)",
                            fontSize: 12,
                            letterSpacing: "0.05em",
                          }}
                        >
                          {ic.code}
                        </span>
                      </TableCell>
                      <TableCell>
                        <Badge status={ic.status} />
                      </TableCell>
                      <TableCell>{ic.roleName ?? "—"}</TableCell>
                      <TableCell>{ic.className ?? "—"}</TableCell>
                      <TableCell>{ic.email ?? "—"}</TableCell>
                      <TableCell>
                        <span
                          style={{
                            fontFamily: "var(--font-mono)",
                            fontSize: 11,
                            color: "var(--color-ink-muted)",
                          }}
                        >
                          {ic.batchId}
                        </span>
                      </TableCell>
                      <TableCell>{ic.usedByName ?? "—"}</TableCell>
                      <TableCell style={{ whiteSpace: "nowrap" }}>
                        {ic.usedAt
                          ? new Date(ic.usedAt).toLocaleDateString("zh-CN")
                          : "—"}
                      </TableCell>
                      <TableCell style={{ whiteSpace: "nowrap" }}>
                        {new Date(ic.createdAt).toLocaleDateString("zh-CN")}
                      </TableCell>
                      <TableCell style={{ whiteSpace: "nowrap" }}>
                        {ic.expiresAt
                          ? new Date(ic.expiresAt).toLocaleDateString("zh-CN")
                          : "—"}
                      </TableCell>
                    </TableRow>
                  ))}
                </Table>
                <div className="flex items-center justify-between mt-4">
                  <label
                    className="flex items-center gap-2"
                    style={{
                      fontSize: 12,
                      color: "var(--color-ink-muted)",
                      cursor: "pointer",
                    }}
                  >
                    <input
                      type="checkbox"
                      checked={allChecked}
                      onChange={toggleSelectAll}
                    />
                    全选当前页
                  </label>
                </div>
                <Pagination
                  page={data.page}
                  pageSize={data.pageSize}
                  total={data.total}
                  hasNext={data.hasNext}
                  onPageChange={(p) => {
                    setSelectedIds(new Set());
                    setPage(p);
                  }}
                />
              </>
            )}
          </>
        )}
      </PaperCard>

      {/* 生成对话框 */}
      {generateOpen && (
        <div
          role="dialog"
          aria-modal="true"
          style={{
            position: "fixed",
            inset: 0,
            background: "rgba(0,0,0,0.4)",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            zIndex: 1000,
          }}
        >
          <div
            style={{
              width: 440,
              padding: 24,
              background: "var(--bg-paper)",
              borderRadius: 8,
              border: "1px solid var(--color-rule)",
            }}
          >
            <h2
              style={{
                fontFamily: "var(--font-serif)",
                fontSize: 18,
                color: "var(--color-ink)",
                marginBottom: 16,
              }}
            >
              {t("admin.invitationCodes.generate")}
            </h2>
            <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
              <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
                <span style={{ fontSize: 12, color: "var(--color-ink)" }}>
                  {t("admin.invitationCodes.generateCount")}（1-1000）
                </span>
                <Input
                  type="number"
                  min={1}
                  max={1000}
                  value={genCount}
                  onChange={(e) => setGenCount(Number(e.target.value) || 0)}
                  style={{ width: 120 }}
                />
              </div>
              <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
                <span style={{ fontSize: 12, color: "var(--color-ink)" }}>
                  {t("admin.invitationCodes.bindRole")}
                </span>
                <Select
                  value={genRoleId}
                  onChange={(e) => setGenRoleId(e.target.value)}
                  style={{ width: "100%" }}
                >
                  <option value="">{t("admin.common.all")}（不绑定）</option>
                  {roles.map((role) => (
                    <option key={role.id} value={role.id}>
                      {role.name}
                    </option>
                  ))}
                </Select>
              </div>
              <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
                <span style={{ fontSize: 12, color: "var(--color-ink)" }}>
                  {t("admin.invitationCodes.bindClass")}（可选）
                </span>
                <Select
                  value={genClassId}
                  onChange={(e) => setGenClassId(e.target.value)}
                  style={{ width: "100%" }}
                >
                  <option value="">{t("admin.common.all")}（不绑定）</option>
                  {classes.map((cls) => (
                    <option key={cls.id} value={cls.id}>
                      {cls.name}
                    </option>
                  ))}
                </Select>
              </div>
              <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
                <span style={{ fontSize: 12, color: "var(--color-ink)" }}>
                  {t("admin.invitationCodes.bindEmail")}（可选）
                </span>
                <Input
                  type="email"
                  value={genEmail}
                  onChange={(e) => setGenEmail(e.target.value)}
                  placeholder="user@edu.test"
                />
              </div>
              <div
                style={{
                  display: "flex",
                  justifyContent: "flex-end",
                  gap: 8,
                  marginTop: 8,
                }}
              >
                <Button
                  variant="secondary"
                  onClick={() => setGenerateOpen(false)}
                >
                  {t("admin.common.cancel")}
                </Button>
                <Button
                  variant="primary"
                  onClick={handleGenerate}
                  disabled={generating}
                >
                  {generating
                    ? t("admin.common.loading")
                    : t("admin.invitationCodes.generate")}
                </Button>
              </div>
            </div>
          </div>
        </div>
      )}

      {/* 生成结果对话框 */}
      {resultOpen && (
        <div
          role="dialog"
          aria-modal="true"
          style={{
            position: "fixed",
            inset: 0,
            background: "rgba(0,0,0,0.4)",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            zIndex: 1000,
          }}
        >
          <div
            style={{
              width: 480,
              maxHeight: "80vh",
              padding: 24,
              background: "var(--bg-paper)",
              borderRadius: 8,
              border: "1px solid var(--color-rule)",
              display: "flex",
              flexDirection: "column",
            }}
          >
            <h2
              style={{
                fontFamily: "var(--font-serif)",
                fontSize: 18,
                color: "var(--color-ink)",
                marginBottom: 8,
              }}
            >
              {t("admin.invitationCodes.generateSuccess", {
                count: generatedCodes.length,
              })}
            </h2>
            <p
              style={{
                fontSize: 12,
                color: "var(--color-ink-muted)",
                marginBottom: 12,
              }}
            >
              {t("admin.invitationCodes.batch")}：{generatedBatchId}
            </p>
            <div
              style={{
                border: "1px solid var(--color-rule)",
                borderRadius: 4,
                padding: 12,
                background: "var(--bg-canvas, var(--bg-paper))",
                overflowY: "auto",
                flex: 1,
                marginBottom: 12,
              }}
            >
              <pre
                style={{
                  margin: 0,
                  fontFamily: "var(--font-mono)",
                  fontSize: 12,
                  color: "var(--color-ink)",
                  whiteSpace: "pre-wrap",
                  wordBreak: "break-all",
                }}
              >
                {generatedCodes.join("\n")}
              </pre>
            </div>
            <div
              style={{
                display: "flex",
                justifyContent: "flex-end",
                gap: 8,
              }}
            >
              <Button variant="secondary" onClick={handleCopyCodes}>
                复制全部
              </Button>
              <Button
                variant="primary"
                onClick={() => {
                  setResultOpen(false);
                  window.location.reload();
                }}
              >
                {t("admin.common.confirm")}
              </Button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
