import { jsx } from 'react/jsx-runtime';
import { lazy } from 'react';
import { defineClientPlugin, createApiClient, runClientHookWithShim, isConnectionError } from '@btst/stack/plugins/client';
import { createRoute } from '@btst/yar';
import { createFormBuilderQueryKeys } from '../../../../../../plugins/form-builder/query-keys.mjs';

const FormListPageComponent = lazy(
  () => import('./components/pages/form-list-page.mjs').then((m) => ({
    default: m.FormListPageComponent
  }))
);
const FormBuilderPageComponent = lazy(
  () => import('./components/pages/form-builder-page.mjs').then((m) => ({
    default: m.FormBuilderPageComponent
  }))
);
const SubmissionsPageComponent = lazy(
  () => import('./components/pages/submissions-page.mjs').then((m) => ({
    default: m.SubmissionsPageComponent
  }))
);
function createFormListLoader(config) {
  return async () => {
    if (typeof window === "undefined") {
      const { queryClient, apiBasePath, apiBaseURL, headers, hooks } = config;
      const context = {
        path: "/forms",
        isSSR: true,
        apiBaseURL,
        apiBasePath,
        headers
      };
      try {
        if (hooks?.beforeLoadFormList) {
          await runClientHookWithShim(
            () => hooks.beforeLoadFormList(context),
            "Load prevented by beforeLoadFormList hook"
          );
        }
        const client = createApiClient({
          baseURL: apiBaseURL,
          basePath: apiBasePath
        });
        const queries = createFormBuilderQueryKeys(client, headers);
        const limit = 20;
        const listQuery = queries.forms.list({ limit, offset: 0 });
        await queryClient.prefetchInfiniteQuery({
          queryKey: listQuery.queryKey,
          queryFn: async ({ pageParam = 0 }) => {
            const response = await client("/forms", {
              method: "GET",
              query: { limit, offset: pageParam },
              headers
            });
            if (typeof response === "object" && response !== null && "error" in response && response.error) {
              throw new Error(String(response.error));
            }
            return response.data;
          },
          initialPageParam: 0
        });
        if (hooks?.afterLoadFormList) {
          await hooks.afterLoadFormList(context);
        }
        const queryState = queryClient.getQueryState(listQuery.queryKey);
        if (queryState?.error && hooks?.onLoadError) {
          const error = queryState.error instanceof Error ? queryState.error : new Error(String(queryState.error));
          await hooks.onLoadError(error, context);
        }
      } catch (error) {
        if (isConnectionError(error)) {
          console.warn(
            "[btst/form-builder] route.loader() failed \u2014 no server running at build time. Use myStack.api.formBuilder.prefetchForRoute() for SSG data prefetching."
          );
        }
        if (hooks?.onLoadError) {
          await hooks.onLoadError(error, context);
        }
      }
    }
  };
}
function createFormBuilderLoader(id, config) {
  return async () => {
    if (typeof window === "undefined") {
      const { queryClient, apiBasePath, apiBaseURL, headers, hooks } = config;
      const context = {
        path: id ? `/forms/${id}/edit` : "/forms/new",
        params: id ? { id } : {},
        isSSR: true,
        apiBaseURL,
        apiBasePath,
        headers
      };
      try {
        if (hooks?.beforeLoadFormBuilder) {
          await runClientHookWithShim(
            () => hooks.beforeLoadFormBuilder(id, context),
            "Load prevented by beforeLoadFormBuilder hook"
          );
        }
        const client = createApiClient({
          baseURL: apiBaseURL,
          basePath: apiBasePath
        });
        const queries = createFormBuilderQueryKeys(client, headers);
        if (id) {
          await queryClient.prefetchQuery(queries.forms.byId(id));
        }
        if (hooks?.afterLoadFormBuilder) {
          await hooks.afterLoadFormBuilder(id, context);
        }
        if (id) {
          const queryState = queryClient.getQueryState(
            queries.forms.byId(id).queryKey
          );
          if (queryState?.error && hooks?.onLoadError) {
            const error = queryState.error instanceof Error ? queryState.error : new Error(String(queryState.error));
            await hooks.onLoadError(error, context);
          }
        }
      } catch (error) {
        if (isConnectionError(error)) {
          console.warn(
            "[btst/form-builder] route.loader() failed \u2014 no server running at build time. Use myStack.api.formBuilder.prefetchForRoute() for SSG data prefetching."
          );
        }
        if (hooks?.onLoadError) {
          await hooks.onLoadError(error, context);
        }
      }
    }
  };
}
function createSubmissionsLoader(formId, config) {
  return async () => {
    if (typeof window === "undefined") {
      const { queryClient, apiBasePath, apiBaseURL, headers, hooks } = config;
      const context = {
        path: `/forms/${formId}/submissions`,
        params: { formId },
        isSSR: true,
        apiBaseURL,
        apiBasePath,
        headers
      };
      try {
        if (hooks?.beforeLoadSubmissions) {
          await runClientHookWithShim(
            () => hooks.beforeLoadSubmissions(formId, context),
            "Load prevented by beforeLoadSubmissions hook"
          );
        }
        const client = createApiClient({
          baseURL: apiBaseURL,
          basePath: apiBasePath
        });
        const queries = createFormBuilderQueryKeys(client, headers);
        const limit = 20;
        await queryClient.prefetchQuery(queries.forms.byId(formId));
        const submissionsQuery = queries.formSubmissions.list({
          formId,
          limit,
          offset: 0
        });
        await queryClient.prefetchInfiniteQuery({
          queryKey: submissionsQuery.queryKey,
          queryFn: async ({ pageParam = 0 }) => {
            const response = await client(
              "/forms/:formId/submissions",
              {
                method: "GET",
                params: { formId },
                query: { limit, offset: pageParam },
                headers
              }
            );
            if (typeof response === "object" && response !== null && "error" in response && response.error) {
              throw new Error(String(response.error));
            }
            return response.data;
          },
          initialPageParam: 0
        });
        if (hooks?.afterLoadSubmissions) {
          await hooks.afterLoadSubmissions(formId, context);
        }
        const formState = queryClient.getQueryState(
          queries.forms.byId(formId).queryKey
        );
        const submissionsState = queryClient.getQueryState(
          submissionsQuery.queryKey
        );
        const queryError = formState?.error || submissionsState?.error;
        if (queryError && hooks?.onLoadError) {
          const error = queryError instanceof Error ? queryError : new Error(String(queryError));
          await hooks.onLoadError(error, context);
        }
      } catch (error) {
        if (isConnectionError(error)) {
          console.warn(
            "[btst/form-builder] route.loader() failed \u2014 no server running at build time. Use myStack.api.formBuilder.prefetchForRoute() for SSG data prefetching."
          );
        }
        if (hooks?.onLoadError) {
          await hooks.onLoadError(error, context);
        }
      }
    }
  };
}
function createFormListMeta() {
  return () => {
    const title = "Forms";
    return [
      { title },
      { name: "title", content: title },
      { name: "robots", content: "noindex" }
    ];
  };
}
function createFormBuilderMeta(id, config) {
  return () => {
    const { queryClient, apiBasePath, apiBaseURL } = config;
    let formName = "";
    if (id) {
      const client = createApiClient({
        baseURL: apiBaseURL,
        basePath: apiBasePath
      });
      const queries = createFormBuilderQueryKeys(client);
      const form = queryClient.getQueryData(queries.forms.byId(id).queryKey);
      formName = form?.name || "";
    }
    const title = id ? `Edit ${formName || "Form"}` : "New Form";
    return [
      { title },
      { name: "title", content: title },
      { name: "robots", content: "noindex" }
    ];
  };
}
function createSubmissionsMeta(formId, config) {
  return () => {
    const { queryClient, apiBasePath, apiBaseURL } = config;
    const client = createApiClient({
      baseURL: apiBaseURL,
      basePath: apiBasePath
    });
    const queries = createFormBuilderQueryKeys(client);
    const form = queryClient.getQueryData(
      queries.forms.byId(formId).queryKey
    );
    const title = form?.name ? `${form.name} Submissions` : "Submissions";
    return [
      { title },
      { name: "title", content: title },
      { name: "robots", content: "noindex" }
    ];
  };
}
const formBuilderClientPlugin = (config) => defineClientPlugin({
  name: "form-builder",
  routes: () => ({
    formList: createRoute("/forms", () => ({
      PageComponent: () => /* @__PURE__ */ jsx(FormListPageComponent, {}),
      loader: createFormListLoader(config),
      meta: createFormListMeta()
    })),
    newForm: createRoute("/forms/new", () => ({
      PageComponent: () => /* @__PURE__ */ jsx(FormBuilderPageComponent, {}),
      loader: createFormBuilderLoader(void 0, config),
      meta: createFormBuilderMeta(void 0, config)
    })),
    editForm: createRoute("/forms/:id/edit", ({ params }) => ({
      PageComponent: () => /* @__PURE__ */ jsx(FormBuilderPageComponent, { id: params.id }),
      loader: createFormBuilderLoader(params.id, config),
      meta: createFormBuilderMeta(params.id, config)
    })),
    submissions: createRoute("/forms/:id/submissions", ({ params }) => ({
      PageComponent: () => /* @__PURE__ */ jsx(SubmissionsPageComponent, { formId: params.id }),
      loader: createSubmissionsLoader(params.id, config),
      meta: createSubmissionsMeta(params.id, config)
    }))
  }),
  sitemap: async () => {
    return [];
  }
});

export { formBuilderClientPlugin };
