import { ref } from "vue";
import { apiErrorContextFromUnknown } from "@/api/client";
import { useAppStore } from "@/stores/app";
import type { ApiError, ErrorDiagnostic } from "@/types";

export interface UseFormOptions {
  successMessage?: string;
  errorMessage?: string;
  toast?: boolean;
}

export function messageFromError(err: unknown): string {
  const context = apiErrorContextFromUnknown(err, "操作失败");
  if (context.error) return context.error;
  if (err instanceof Error && err.message.trim()) return err.message;
  if (err && typeof err === "object") {
    const record = err as Record<string, unknown>;
    const nested = record.error && typeof record.error === "object" ? record.error as Record<string, unknown> : null;
    const candidate = nested?.message ?? nested?.code ?? record.message ?? record.reason ?? record.error;
    if (typeof candidate === "string" && candidate.trim()) return candidate;
  }
  return String(err || "操作失败");
}

export function useForm(options: UseFormOptions = {}) {
  const loading = ref(false);
  const error = ref<string | null>(null);
  const apiError = ref<ApiError | null>(null);
  const diagnostic = ref<ErrorDiagnostic | null>(null);
  const notice = ref<string | null>(null);
  const app = useAppStore();

  async function submit(action: () => Promise<void>, successMessage?: string): Promise<boolean> {
    if (loading.value) return false;
    loading.value = true;
    error.value = null;
    apiError.value = null;
    diagnostic.value = null;
    notice.value = null;
    try {
      await action();
      const message = successMessage ?? options.successMessage ?? null;
      notice.value = message;
      if (options.toast !== false && message) app.showSuccess(message);
      return true;
    } catch (err) {
      const context = apiErrorContextFromUnknown(err, "操作失败");
      const message = options.errorMessage ?? context.error ?? messageFromError(err);
      error.value = message;
      apiError.value = context.apiError;
      diagnostic.value = context.diagnostic;
      if (options.toast !== false) app.showError(message);
      return false;
    } finally {
      loading.value = false;
    }
  }

  return { loading, error, apiError, diagnostic, notice, submit };
}
