import type { AdminActionRunResponse, AdminActionSummary } from "@xtablo/shared-types";
import { useEffect, useState } from "react";
import { adminApi } from "../lib/api";

function getErrorMessage(error: unknown, fallbackMessage: string) {
  if (typeof error === "object" && error !== null && "response" in error) {
    const response = error.response;
    if (
      typeof response === "object" &&
      response !== null &&
      "data" in response &&
      typeof response.data === "object" &&
      response.data !== null &&
      "error" in response.data &&
      typeof response.data.error === "string"
    ) {
      return response.data.error;
    }
  }

  return fallbackMessage;
}

export function useAdminActions() {
  const [actions, setActions] = useState<AdminActionSummary[]>([]);
  const [selectedActionId, setSelectedActionId] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [isRunning, setIsRunning] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [resultMessage, setResultMessage] = useState<string | null>(null);

  useEffect(() => {
    let isMounted = true;

    const loadActions = async () => {
      try {
        const response = await adminApi.get<{ actions: AdminActionSummary[] }>("/admin/actions");
        if (!isMounted) {
          return;
        }

        setActions(response.data.actions);
        setSelectedActionId((currentValue) => currentValue ?? response.data.actions[0]?.id ?? null);
      } catch (error) {
        if (isMounted) {
          setError(getErrorMessage(error, "Failed to load admin actions"));
        }
      } finally {
        if (isMounted) {
          setIsLoading(false);
        }
      }
    };

    void loadActions();

    return () => {
      isMounted = false;
    };
  }, []);

  const runAction = async (payload: Record<string, string>) => {
    if (!selectedActionId) {
      return;
    }

    setIsRunning(true);
    setError(null);
    setResultMessage(null);

    try {
      const response = await adminApi.post<AdminActionRunResponse>(
        `/admin/actions/${selectedActionId}/run`,
        payload
      );
      setResultMessage(response.data.message);
    } catch (error) {
      const message = getErrorMessage(error, "Failed to run admin action");
      setError(message);
      throw new Error(message);
    } finally {
      setIsRunning(false);
    }
  };

  return {
    actions,
    error,
    isLoading,
    isRunning,
    resultMessage,
    runAction,
    selectedActionId,
    setError,
    setResultMessage,
    setSelectedActionId,
  };
}
