'use strict';

const jsxRuntime = require('react/jsx-runtime');
const client = require('@btst/stack/plugins/client');
const yar = require('@btst/yar');
const plugins_blog_queryKeys = require('../../../../../../plugins/blog/query-keys.cjs');
const homePage = require('./components/pages/home-page.cjs');
const newPostPage = require('./components/pages/new-post-page.cjs');
const editPostPage = require('./components/pages/edit-post-page.cjs');
const tagPage = require('./components/pages/tag-page.cjs');
const postPage = require('./components/pages/post-page.cjs');

function createPostsLoader(published, config) {
  return async () => {
    if (typeof window === "undefined") {
      const { queryClient, apiBasePath, apiBaseURL, hooks, headers } = config;
      const context = {
        path: published ? "/blog" : "/blog/drafts",
        isSSR: true,
        apiBaseURL,
        apiBasePath,
        headers
      };
      try {
        if (hooks?.beforeLoadPosts) {
          const canLoad = await hooks.beforeLoadPosts({ published }, context);
          if (!canLoad) {
            throw new Error("Load prevented by beforeLoadPosts hook");
          }
        }
        const limit = 10;
        const client$1 = client.createApiClient({
          baseURL: apiBaseURL,
          basePath: apiBasePath
        });
        const queries = plugins_blog_queryKeys.createBlogQueryKeys(client$1, headers);
        const listQuery = queries.posts.list({
          query: void 0,
          limit,
          published
        });
        await queryClient.prefetchInfiniteQuery({
          ...listQuery,
          initialPageParam: 0
        });
        const tagsQuery = queries.tags.list();
        await queryClient.prefetchQuery(tagsQuery);
        if (hooks?.afterLoadPosts) {
          const posts = queryClient.getQueryData(listQuery.queryKey) || null;
          const canContinue = await hooks.afterLoadPosts(
            posts,
            { published },
            context
          );
          if (canContinue === false) {
            throw new Error("Load prevented by afterLoadPosts hook");
          }
        }
        const queryState = queryClient.getQueryState(listQuery.queryKey);
        if (queryState?.error) {
          if (hooks?.onLoadError) {
            const error = queryState.error instanceof Error ? queryState.error : new Error(String(queryState.error));
            await hooks.onLoadError(error, context);
          }
        }
      } catch (error) {
        if (hooks?.onLoadError) {
          await hooks.onLoadError(error, context);
        }
      }
    }
  };
}
function createPostLoader(slug, config, path) {
  return async () => {
    if (typeof window === "undefined") {
      const { queryClient, apiBasePath, apiBaseURL, hooks, headers } = config;
      const context = {
        path: path ?? `/blog/${slug}`,
        params: { slug },
        isSSR: true,
        apiBaseURL,
        apiBasePath,
        headers
      };
      try {
        if (hooks?.beforeLoadPost) {
          const canLoad = await hooks.beforeLoadPost(slug, context);
          if (!canLoad) {
            throw new Error("Load prevented by beforeLoadPost hook");
          }
        }
        const client$1 = client.createApiClient({
          baseURL: apiBaseURL,
          basePath: apiBasePath
        });
        const queries = plugins_blog_queryKeys.createBlogQueryKeys(client$1, headers);
        const postQuery = queries.posts.detail(slug);
        await queryClient.prefetchQuery(postQuery);
        if (hooks?.afterLoadPost) {
          const post = queryClient.getQueryData(postQuery.queryKey) || null;
          const canContinue = await hooks.afterLoadPost(post, slug, context);
          if (canContinue === false) {
            throw new Error("Load prevented by afterLoadPost hook");
          }
        }
        const queryState = queryClient.getQueryState(postQuery.queryKey);
        if (queryState?.error) {
          if (hooks?.onLoadError) {
            const error = queryState.error instanceof Error ? queryState.error : new Error(String(queryState.error));
            await hooks.onLoadError(error, context);
          }
        }
      } catch (error) {
        if (hooks?.onLoadError) {
          await hooks.onLoadError(error, context);
        }
      }
    }
  };
}
function createNewPostLoader(config) {
  return async () => {
    if (typeof window === "undefined") {
      const { apiBasePath, apiBaseURL, hooks, headers } = config;
      const context = {
        path: "/blog/new",
        isSSR: true,
        apiBaseURL,
        apiBasePath,
        headers
      };
      try {
        if (hooks?.beforeLoadNewPost) {
          const canLoad = await hooks.beforeLoadNewPost(context);
          if (!canLoad) {
            throw new Error("Load prevented by beforeLoadNewPost hook");
          }
        }
        if (hooks?.afterLoadNewPost) {
          const canContinue = await hooks.afterLoadNewPost(context);
          if (canContinue === false) {
            throw new Error("Load prevented by afterLoadNewPost hook");
          }
        }
      } catch (error) {
        if (hooks?.onLoadError) {
          await hooks.onLoadError(error, context);
        }
      }
    }
  };
}
function createTagLoader(tagSlug, config) {
  return async () => {
    if (typeof window === "undefined") {
      const { queryClient, apiBasePath, apiBaseURL, hooks, headers } = config;
      const context = {
        path: `/blog/tag/${tagSlug}`,
        params: { tagSlug },
        isSSR: true,
        apiBaseURL,
        apiBasePath,
        headers
      };
      try {
        const limit = 10;
        const client$1 = client.createApiClient({
          baseURL: apiBaseURL,
          basePath: apiBasePath
        });
        const queries = plugins_blog_queryKeys.createBlogQueryKeys(client$1, headers);
        const listQuery = queries.posts.list({
          query: void 0,
          limit,
          published: true,
          tagSlug
        });
        await queryClient.prefetchInfiniteQuery({
          ...listQuery,
          initialPageParam: 0
        });
        const tagsQuery = queries.tags.list();
        await queryClient.prefetchQuery(tagsQuery);
        const listState = queryClient.getQueryState(listQuery.queryKey);
        const tagsState = queryClient.getQueryState(tagsQuery.queryKey);
        const queryError = listState?.error || tagsState?.error;
        if (queryError && hooks?.onLoadError) {
          const error = queryError instanceof Error ? queryError : new Error(String(queryError));
          await hooks.onLoadError(error, context);
        }
      } catch (error) {
        if (hooks?.onLoadError) {
          await hooks.onLoadError(error, context);
        }
      }
    }
  };
}
function createPostsListMeta(published, config) {
  return () => {
    const { siteBaseURL, siteBasePath, seo } = config;
    const path = published ? "/blog" : "/blog/drafts";
    const fullUrl = `${siteBaseURL}${siteBasePath}${path}`;
    const title = published ? "Blog" : "Draft Posts";
    const description = published ? "Read our latest articles, insights, and updates on web development, technology, and more." : "View and manage your draft blog posts.";
    return [
      // Primary meta tags
      { title },
      { name: "title", content: title },
      { name: "description", content: description },
      {
        name: "keywords",
        content: "blog, articles, technology, web development, insights"
      },
      ...seo?.author ? [{ name: "author", content: seo.author }] : [],
      {
        name: "robots",
        content: published ? "index, follow" : "noindex, nofollow"
      },
      // Open Graph / Facebook
      { property: "og:type", content: "website" },
      { property: "og:title", content: title },
      { property: "og:description", content: description },
      { property: "og:url", content: fullUrl },
      ...seo?.siteName ? [{ property: "og:site_name", content: seo.siteName }] : [],
      ...seo?.locale ? [{ property: "og:locale", content: seo.locale }] : [],
      ...seo?.defaultImage ? [{ property: "og:image", content: seo.defaultImage }] : [],
      // Twitter Card
      { name: "twitter:card", content: "summary_large_image" },
      { name: "twitter:title", content: title },
      { name: "twitter:description", content: description },
      ...seo?.twitterHandle ? [{ name: "twitter:site", content: seo.twitterHandle }] : []
    ];
  };
}
function createPostMeta(slug, config) {
  return () => {
    const { queryClient } = config;
    const { apiBaseURL, apiBasePath, siteBaseURL, siteBasePath, seo } = config;
    const queries = plugins_blog_queryKeys.createBlogQueryKeys(
      client.createApiClient({
        baseURL: apiBaseURL,
        basePath: apiBasePath
      })
    );
    const post = queryClient.getQueryData(
      queries.posts.detail(slug).queryKey
    );
    if (!post) {
      return [
        { title: "Unknown route" },
        { name: "title", content: "Unknown route" },
        { name: "robots", content: "noindex" }
      ];
    }
    const fullUrl = `${siteBaseURL}${siteBasePath}/blog/${post.slug}`;
    const title = post.title;
    const description = post.excerpt || post.content.substring(0, 160);
    const publishedTime = post.publishedAt ? new Date(post.publishedAt).toISOString() : new Date(post.createdAt).toISOString();
    const modifiedTime = new Date(post.updatedAt).toISOString();
    const image = post.image || seo?.defaultImage;
    return [
      // Primary meta tags
      { title },
      { name: "title", content: title },
      { name: "description", content: description },
      ...post.authorId || seo?.author ? [{ name: "author", content: post.authorId || seo?.author }] : [],
      {
        name: "robots",
        content: post.published ? "index, follow" : "noindex, nofollow"
      },
      {
        name: "keywords",
        content: `blog, article, ${post.slug.replace(/-/g, ", ")}`
      },
      // Open Graph / Facebook
      { property: "og:type", content: "article" },
      { property: "og:title", content: title },
      { property: "og:description", content: description },
      { property: "og:url", content: fullUrl },
      ...seo?.siteName ? [{ property: "og:site_name", content: seo.siteName }] : [],
      ...seo?.locale ? [{ property: "og:locale", content: seo.locale }] : [],
      ...image ? [{ property: "og:image", content: image }] : [],
      ...image ? [
        { property: "og:image:width", content: "1200" },
        { property: "og:image:height", content: "630" },
        { property: "og:image:alt", content: title }
      ] : [],
      // Article-specific Open Graph tags
      { property: "article:published_time", content: publishedTime },
      { property: "article:modified_time", content: modifiedTime },
      ...post.authorId ? [{ property: "article:author", content: post.authorId }] : [],
      // Twitter Card
      {
        name: "twitter:card",
        content: image ? "summary_large_image" : "summary"
      },
      { name: "twitter:title", content: title },
      { name: "twitter:description", content: description },
      ...seo?.twitterHandle ? [{ name: "twitter:site", content: seo.twitterHandle }] : [],
      ...post.authorId || seo?.twitterHandle ? [
        {
          name: "twitter:creator",
          content: post.authorId || seo?.twitterHandle
        }
      ] : [],
      ...image ? [{ name: "twitter:image", content: image }] : [],
      ...image ? [{ name: "twitter:image:alt", content: title }] : [],
      // Additional SEO tags
      { name: "publish_date", content: publishedTime }
    ];
  };
}
function createTagMeta(tagSlug, config) {
  return () => {
    const { queryClient } = config;
    const { apiBaseURL, apiBasePath, siteBaseURL, siteBasePath, seo } = config;
    const queries = plugins_blog_queryKeys.createBlogQueryKeys(
      client.createApiClient({
        baseURL: apiBaseURL,
        basePath: apiBasePath
      })
    );
    const tags = queryClient.getQueryData(
      queries.tags.list().queryKey
    );
    const tag = tags?.find((t) => t.slug === tagSlug);
    if (!tag) {
      return [
        { title: "Unknown route" },
        { name: "title", content: "Unknown route" },
        { name: "robots", content: "noindex" }
      ];
    }
    const fullUrl = `${siteBaseURL}${siteBasePath}/blog/tag/${tag.slug}`;
    const title = `${tag.name} Posts`;
    const description = `Browse all ${tag.name} posts`;
    return [
      { title },
      { name: "title", content: title },
      { name: "description", content: description },
      { name: "robots", content: "index, follow" },
      { name: "keywords", content: `blog, ${tag.name}, articles` },
      { property: "og:type", content: "website" },
      { property: "og:title", content: title },
      { property: "og:description", content: description },
      { property: "og:url", content: fullUrl },
      ...seo?.siteName ? [{ property: "og:site_name", content: seo.siteName }] : [],
      ...seo?.defaultImage ? [{ property: "og:image", content: seo.defaultImage }] : [],
      { name: "twitter:card", content: "summary" },
      { name: "twitter:title", content: title }
    ];
  };
}
function createNewPostMeta(config) {
  return () => {
    const { siteBaseURL, siteBasePath } = config;
    const fullUrl = `${siteBaseURL}${siteBasePath}/blog/new`;
    const title = "Create New Post";
    return [
      { title },
      { name: "title", content: title },
      { name: "description", content: "Write and publish a new blog post." },
      { name: "robots", content: "noindex, nofollow" },
      // Open Graph
      { property: "og:type", content: "website" },
      { property: "og:title", content: title },
      {
        property: "og:description",
        content: "Write and publish a new blog post."
      },
      { property: "og:url", content: fullUrl },
      // Twitter
      { name: "twitter:card", content: "summary" },
      { name: "twitter:title", content: title }
    ];
  };
}
function createEditPostMeta(slug, config) {
  return () => {
    const { queryClient } = config;
    const { apiBaseURL, apiBasePath, siteBaseURL, siteBasePath } = config;
    const queries = plugins_blog_queryKeys.createBlogQueryKeys(
      client.createApiClient({
        baseURL: apiBaseURL,
        basePath: apiBasePath
      })
    );
    const post = queryClient.getQueryData(
      queries.posts.detail(slug).queryKey
    );
    const fullUrl = `${siteBaseURL}${siteBasePath}/blog/${slug}/edit`;
    const title = post ? `Edit: ${post.title}` : "Unknown route";
    return [
      { title },
      { name: "title", content: title },
      { name: "description", content: "Edit your blog post." },
      { name: "robots", content: "noindex, nofollow" },
      // Open Graph
      { property: "og:type", content: "website" },
      { property: "og:title", content: title },
      { property: "og:url", content: fullUrl },
      // Twitter
      { name: "twitter:card", content: "summary" },
      { name: "twitter:title", content: title }
    ];
  };
}
const blogClientPlugin = (config) => client.defineClientPlugin({
  name: "blog",
  routes: () => ({
    posts: yar.createRoute("/blog", () => {
      return {
        PageComponent: () => /* @__PURE__ */ jsxRuntime.jsx(homePage.HomePageComponent, { published: true }),
        loader: createPostsLoader(true, config),
        meta: createPostsListMeta(true, config)
      };
    }),
    drafts: yar.createRoute("/blog/drafts", () => {
      return {
        PageComponent: () => /* @__PURE__ */ jsxRuntime.jsx(homePage.HomePageComponent, { published: false }),
        loader: createPostsLoader(false, config),
        meta: createPostsListMeta(false, config)
      };
    }),
    newPost: yar.createRoute("/blog/new", () => {
      return {
        PageComponent: newPostPage.NewPostPageComponent,
        loader: createNewPostLoader(config),
        meta: createNewPostMeta(config)
      };
    }),
    editPost: yar.createRoute("/blog/:slug/edit", ({ params: { slug } }) => {
      return {
        PageComponent: () => /* @__PURE__ */ jsxRuntime.jsx(editPostPage.EditPostPageComponent, { slug }),
        loader: createPostLoader(slug, config, `/blog/${slug}/edit`),
        meta: createEditPostMeta(slug, config)
      };
    }),
    tag: yar.createRoute("/blog/tag/:tagSlug", ({ params: { tagSlug } }) => {
      return {
        PageComponent: () => /* @__PURE__ */ jsxRuntime.jsx(tagPage.TagPageComponent, { tagSlug }),
        loader: createTagLoader(tagSlug, config),
        meta: createTagMeta(tagSlug, config)
      };
    }),
    post: yar.createRoute("/blog/:slug", ({ params: { slug } }) => {
      return {
        PageComponent: () => /* @__PURE__ */ jsxRuntime.jsx(postPage.PostPageComponent, { slug }),
        loader: createPostLoader(slug, config),
        meta: createPostMeta(slug, config)
      };
    })
  }),
  sitemap: async () => {
    const origin = `${config.siteBaseURL}${config.siteBasePath}`;
    const indexUrl = `${origin}/blog`;
    const client$1 = client.createApiClient({
      baseURL: config.apiBaseURL,
      basePath: config.apiBasePath
    });
    const limit = 100;
    let offset = 0;
    const posts = [];
    while (true) {
      const res = await client$1("/posts", {
        method: "GET",
        query: {
          offset,
          limit,
          published: "true"
        }
      });
      const page = res.data ?? [];
      posts.push(...page);
      if (page.length < limit) break;
      offset += limit;
    }
    const tagsRes = await client$1("/tags", {
      method: "GET"
    });
    const tags = tagsRes.data ?? [];
    const getLastModified = (p) => {
      const dates = [p.updatedAt, p.publishedAt, p.createdAt].filter(
        Boolean
      );
      if (dates.length === 0) return void 0;
      const times = dates.map((d) => new Date(d).getTime()).filter((t) => !Number.isNaN(t));
      if (times.length === 0) return void 0;
      return new Date(Math.max(...times));
    };
    const latestTime = posts.map((p) => getLastModified(p)?.getTime() ?? 0).reduce((a, b) => Math.max(a, b), 0);
    const entries = [
      {
        url: indexUrl,
        lastModified: latestTime ? new Date(latestTime) : void 0,
        changeFrequency: "daily",
        priority: 0.7
      },
      ...posts.map((p) => ({
        url: `${origin}/blog/${p.slug}`,
        lastModified: getLastModified(p),
        changeFrequency: "monthly",
        priority: 0.6
      })),
      ...tags.map((t) => ({
        url: `${origin}/blog/tag/${t.slug}`,
        lastModified: t.updatedAt ? new Date(t.updatedAt) : void 0,
        changeFrequency: "weekly",
        priority: 0.5
      }))
    ];
    return entries;
  }
});

exports.blogClientPlugin = blogClientPlugin;
