import { useCallback, useEffect, useRef, useState } from "react";
import { HttpError } from "../../shared/api/errors";
import type { PageResult } from "../../shared/api/types";
import {
  recycleBinApi,
  type RecycleBinApi,
} from "./recycleBinApi";
import type {
  RecycleBinDocumentSummary,
  RecycleBinQuery,
} from "./recycleBinTypes";

export interface RecycleBinListState {
  data: PageResult<RecycleBinDocumentSummary> | null;
  loading: boolean;
  error: HttpError | null;
}

function asHttpError(value: unknown): HttpError {
  return value instanceof HttpError
    ? value
    : new HttpError({
        httpStatus: 0,
        code: "INTERNAL_ERROR",
        message: "回收站请求失败",
        details: null,
        requestId: "client",
        cause: value,
      });
}

export function useRecycleBinList(
  query: RecycleBinQuery,
  api: RecycleBinApi = recycleBinApi,
  debounceMs = 300,
) {
  const [state, setState] = useState<RecycleBinListState>({
    data: null,
    loading: true,
    error: null,
  });
  const [revision, setRevision] = useState(0);
  const requestVersion = useRef(0);
  const refresh = useCallback(() => setRevision((value) => value + 1), []);

  useEffect(() => {
    const version = ++requestVersion.current;
    const controller = new AbortController();
    const timer = window.setTimeout(() => {
      setState((current) => ({ ...current, loading: true, error: null }));
      void api
        .list(query, controller.signal)
        .then((data) => {
          if (
            !controller.signal.aborted &&
            version === requestVersion.current
          ) {
            setState({ data, loading: false, error: null });
          }
        })
        .catch((value: unknown) => {
          if (
            controller.signal.aborted ||
            version !== requestVersion.current
          ) {
            return;
          }
          setState({
            data: null,
            loading: false,
            error: asHttpError(value),
          });
        });
    }, query.keyword ? debounceMs : 0);

    return () => {
      window.clearTimeout(timer);
      controller.abort();
    };
  }, [
    api,
    debounceMs,
    query.categoryId,
    query.deletedFrom,
    query.deletedTo,
    query.documentType,
    query.keyword,
    query.page,
    query.pageSize,
    query.sortDirection,
    query.sortField,
    revision,
  ]);

  return { ...state, refresh };
}

