import payloadConfig from "@/payload.config";
import { BlogData } from "@/schema/blog";
import { FetchBlogParams } from "@/schema/services/blog";
import { formatDate } from "@/utils/datetime";
import { getRandomNumber } from "@/utils/general";
import { sanitizeBlogContentIntoStringPreview } from "@/utils/sanitize";
import { getPayload, Where } from "payload";

export async function fetchBlog({ page, search = "", categoryId, tagId }: FetchBlogParams = {}) {
  const payload = await getPayload({ config: payloadConfig });

  const queryCondition: Where = {
    _status: { equals: "published" },
  };

  if (!!search) {
    queryCondition["title"] = {
      contains: search,
    };
  }
  if (!!categoryId) {
    queryCondition["categories"] = {
      equals: categoryId,
    };
  }
  if (!!tagId) {
    queryCondition["tags"] = {
      equals: tagId,
    };
  }

  const blogDataQuery = await payload.find({
    collection: "blogs",
    page,
    pagination: true,
    limit: 9,
    where: queryCondition,
  });

  const formattedData: BlogData[] = blogDataQuery.docs.map((item) => {
    return {
      slug: item.slug,
      title: item.title,
      description: sanitizeBlogContentIntoStringPreview(item.content),
      img: typeof item.img !== "number" ? { url: item?.img?.url ?? "", alt: item.img.alt } : undefined,
      posted_at: formatDate(item.createdAt),
    };
  });

  return {
    ...blogDataQuery,
    formattedData,
  };
}

export async function fetchBlogSuggestion() {
  const payload = await getPayload({ config: payloadConfig });
  const limitPerPage = 2;
  const blogCountQuery = await payload.count({
    collection: "blogs",
    where: { _status: { equals: "published" } },
  });

  // randomize page
  let page = 1;
  const totalDocs = blogCountQuery.totalDocs;
  if (totalDocs > limitPerPage) {
    const totalPage = Math.ceil(totalDocs / limitPerPage);
    page = getRandomNumber(totalPage);
  }

  const blogDataQuery = await payload.find({
    collection: "blogs",
    page,
    limit: limitPerPage,
  });

  const formattedData: BlogData[] = blogDataQuery.docs.map((item) => {
    return {
      slug: item.slug,
      title: item.title,
      description: sanitizeBlogContentIntoStringPreview(item.content),
      img: typeof item.img !== "number" ? { url: item?.img?.url ?? "", alt: item.img.alt } : undefined,
      posted_at: formatDate(item.createdAt),
    };
  });

  return {
    ...blogDataQuery,
    formattedData,
  };
}

export async function fetchBlogDetail(slug: string | undefined) {
  const payload = await getPayload({ config: payloadConfig });
  const blogDataQuery = await payload.find({
    collection: "blogs",
    where: {
      _status: { equals: "published" },
      slug: { equals: slug },
    },
    limit: 1,
    pagination: false,
  });

  if (!blogDataQuery?.docs?.[0]) return null;

  const data = blogDataQuery?.docs?.[0];
  const createdAt = formatDate(data.createdAt);
  const updatedAt = formatDate(data.updatedAt);
  const img = {
    url: typeof data.img !== "number" ? (data?.img?.url ?? "") : "",
    alt: typeof data.img !== "number" ? (data?.img?.alt ?? "") : "",
  };

  return {
    data,
    createdAt,
    updatedAt,
    img,
  };
}

export async function fetchBlogCategoryBySlug(slug: string) {
  const payload = await getPayload({ config: payloadConfig });
  const category = await payload.find({
    collection: "blogCategories",
    where: {
      _status: { equals: "published" },
      slug: { equals: slug },
    },
  });

  if (!category?.docs?.[0]) return null;

  return {
    data: category.docs[0],
  };
}

export async function fetchBlogTagBySlug(slug: string) {
  const payload = await getPayload({ config: payloadConfig });
  const tag = await payload.find({
    collection: "blogTags",
    where: {
      _status: { equals: "published" },
      slug: { equals: slug },
    },
  });

  if (!tag?.docs?.[0]) return null;

  return {
    data: tag.docs[0],
  };
}
