/**
 * 邀请码管理 Hooks
 *
 * contract §2.4：adminInvitationCodes / generateInvitationCodes / deleteInvitationCodes
 */
import { useCallback, useState } from "react";
import { useGraphMutation, useGraphQuery } from "./use-graphql";
import {
  ADMIN_INVITATION_CODES_QUERY,
  GENERATE_INVITATION_CODES_MUTATION,
  DELETE_INVITATION_CODES_MUTATION,
} from "@/lib/graphql-client";
import type {
  InvitationCodeViewModel,
  PaginatedResult,
  ListFilter,
} from "@/types/view-models";

interface AdminInvitationCodesResponse {
  adminInvitationCodes: PaginatedResult<InvitationCodeViewModel>;
}

interface GenerateInvitationCodesResponse {
  generateInvitationCodes: { codes: string[]; batchId: string };
}

interface DeleteInvitationCodesResponse {
  deleteInvitationCodes: boolean;
}

interface GenerateInvitationCodesInput {
  count: number;
  roleId?: string;
  classId?: string;
  email?: string;
  expiresAt?: number;
}

export function useInvitationCodes(filter: Partial<ListFilter>) {
  const result = useGraphQuery<AdminInvitationCodesResponse>(
    ADMIN_INVITATION_CODES_QUERY,
    { filter },
  );
  return {
    ...result,
    data: result.data?.adminInvitationCodes ?? null,
  };
}

export function useInvitationCodeFilter(initial?: Partial<ListFilter>) {
  const [filter, setFilter] = useState<Partial<ListFilter>>({
    page: 1,
    pageSize: 20,
    ...initial,
  });
  const setPage = useCallback(
    (page: number) => setFilter((f) => ({ ...f, page })),
    [],
  );
  const setSearch = useCallback(
    (search: string) => setFilter((f) => ({ ...f, search, page: 1 })),
    [],
  );
  const setStatus = useCallback(
    (status: string) => setFilter((f) => ({ ...f, status, page: 1 })),
    [],
  );
  return { filter, setFilter, setPage, setSearch, setStatus };
}

export function useGenerateInvitationCodes() {
  const [run, state] = useGraphMutation<
    GenerateInvitationCodesResponse,
    { input: GenerateInvitationCodesInput }
  >(GENERATE_INVITATION_CODES_MUTATION);
  const generate = useCallback(
    async (input: GenerateInvitationCodesInput) => {
      const res = await run({ input });
      return res.data?.generateInvitationCodes ?? null;
    },
    [run],
  );
  return [generate, state] as const;
}

export function useDeleteInvitationCodes() {
  const [run, state] = useGraphMutation<
    DeleteInvitationCodesResponse,
    { ids: string[] }
  >(DELETE_INVITATION_CODES_MUTATION);
  const remove = useCallback(
    async (ids: string[]) => {
      const res = await run({ ids });
      return res.data?.deleteInvitationCodes ?? false;
    },
    [run],
  );
  return [remove, state] as const;
}
