/**
 * Content Domain Adapter (Blog Posts)
 *
 * Routes blog_posts CRUD through Convex.
 *
 * Maintains method signatures compatible with the service layer so
 * blog-management.service.ts changes are minimal.
 */

import { convexQuery, convexMutation } from "@/lib/convex-client";
import {
  convexToPrismaShape,
  convexToPrismaShapeMany,
  applyPagination,
  type ConvexDoc,
} from "./base";
import type {
  BlogPostDB,
  BlogPostListItem,
  BlogPostFilters,
  PaginatedBlogPosts,
  BlogStats,
} from "@/lib/types/blog-management.types";

const TIMESTAMP_FIELDS = ["createdAt", "updatedAt", "publishedAt"];

// ─── getBlogPosts ──────────────────────────────────────────────────────────

export async function getBlogPosts(
  filters: BlogPostFilters = {},
  page: number = 1,
  pageSize: number = 20,
): Promise<PaginatedBlogPosts> {
  const docs =
    (await convexQuery<ConvexDoc[]>("content/queries:getBlogPosts", {
      ...(filters.status ? { status: filters.status } : {}),
      ...(filters.lang ? { lang: filters.lang } : {}),
      ...(filters.featured !== undefined ? { featured: filters.featured } : {}),
      ...(filters.author ? { author: filters.author } : {}),
      ...(filters.search ? { search: filters.search } : {}),
      limit: page * pageSize + pageSize,
    })) || [];

  // Apply tag filters client-side (Convex may not support array contains)
  let filtered = docs;
  if (filters.tags && filters.tags.length > 0) {
    filtered = filtered.filter((d) => {
      const docTags = d.tags as string[] | undefined;
      if (!docTags) return false;
      return filters.tags!.every((t) => docTags.includes(t));
    });
  }
  if (filters.dateFrom) {
    filtered = filtered.filter((d) => (d.date as string) >= filters.dateFrom!);
  }
  if (filters.dateTo) {
    filtered = filtered.filter((d) => (d.date as string) <= filters.dateTo!);
  }

  const total = filtered.length;
  const paginated = applyPagination(filtered, (page - 1) * pageSize, pageSize);
  const posts = convexToPrismaShapeMany<Record<string, unknown>>(
    paginated,
    TIMESTAMP_FIELDS,
  ) as unknown as BlogPostListItem[];

  return {
    posts,
    total,
    page,
    pageSize,
    totalPages: Math.ceil(total / pageSize),
  };
}

// ─── getBlogPostById ───────────────────────────────────────────────────────

export async function getBlogPostById(id: string): Promise<BlogPostDB | null> {
  const doc = await convexQuery<ConvexDoc | null>(
    "content/queries:getBlogPostById",
    { id },
  );
  if (!doc) return null;
  return convexToPrismaShape(doc, TIMESTAMP_FIELDS) as unknown as BlogPostDB;
}

// ─── checkSlugExists ───────────────────────────────────────────────────────

export async function checkSlugExists(
  slug: string,
  lang: "ar" | "en",
  excludeId?: string,
): Promise<boolean> {
  const existing = await convexQuery<ConvexDoc | null>(
    "content/queries:getBlogPostBySlug",
    { slug, lang },
  );
  if (!existing) return false;
  // If excluding an id, check it
  if (excludeId) {
    const existingId = (existing.prismaId as string) || existing._id;
    return existingId !== excludeId;
  }
  return true;
}

// ─── createBlogPost (raw DB insert — no AI image logic) ────────────────────

export async function createBlogPost(
  postData: Record<string, unknown>,
): Promise<BlogPostDB> {
  const convexId = await convexMutation<string>(
    "content/mutations:createBlogPost",
    postData,
  );

  // Return Prisma-compatible shape
  return {
    ...(postData as Record<string, unknown>),
    id: (postData.id as string) || convexId || "",
    created_at: (postData.created_at as string) || new Date().toISOString(),
    updated_at: (postData.updated_at as string) || new Date().toISOString(),
  } as unknown as BlogPostDB;
}

// ─── updateBlogPost (raw DB update) ────────────────────────────────────────

export async function updateBlogPost(
  id: string,
  updateData: Record<string, unknown>,
): Promise<BlogPostDB> {
  await convexMutation("content/mutations:updateBlogPost", {
    id,
    ...updateData,
  });

  // Return best-effort shape by re-fetching
  const updated = await getBlogPostById(id);
  if (!updated) {
    throw new Error("Blog post not found after update");
  }
  return updated;
}

// ─── deleteBlogPost (raw DB delete) ────────────────────────────────────────

export async function deleteBlogPost(id: string): Promise<void> {
  await convexMutation("content/mutations:deleteBlogPost", { id });
}

// ─── getBlogStats ──────────────────────────────────────────────────────────

export async function getBlogStats(): Promise<BlogStats> {
  const stats = await convexQuery<BlogStats>(
    "content/queries:getBlogStats",
    {},
  );
  if (!stats) {
    return {
      total: 0,
      byStatus: { draft: 0, published: 0, archived: 0 },
      byLanguage: { ar: 0, en: 0 },
      featured: 0,
      recentlyPublished: 0,
    };
  }
  return stats;
}

// ─── getAllAuthors ──────────────────────────────────────────────────────────

export async function getAllAuthors(): Promise<string[]> {
  const authors = await convexQuery<string[]>(
    "content/queries:getBlogAuthors",
    {},
  );
  return authors || [];
}

// ─── getAllBlogTags ─────────────────────────────────────────────────────────

export async function getAllBlogTags(): Promise<string[]> {
  const tags = await convexQuery<string[]>("content/queries:getBlogTags", {});
  return tags || [];
}

// ─── bulkUpdateStatus ──────────────────────────────────────────────────────

export async function bulkUpdateStatus(
  ids: string[],
  status: "DRAFT" | "PUBLISHED" | "ARCHIVED",
): Promise<number> {
  const result = await convexMutation<{ count: number }>(
    "content/mutations:bulkUpdateBlogStatus",
    { ids, status },
  );
  return result?.count ?? 0;
}

// ─── toggleFeatured ────────────────────────────────────────────────────────

export async function toggleFeatured(
  id: string,
  featured: boolean,
): Promise<void> {
  await convexMutation("content/mutations:updateBlogPost", {
    id,
    featured,
    updatedAt: Date.now(),
  });
}

// ─── Namespace export ──────────────────────────────────────────────────────

export const contentAdapter = {
  getBlogPosts,
  getBlogPostById,
  checkSlugExists,
  createBlogPost,
  updateBlogPost,
  deleteBlogPost,
  getBlogStats,
  getAllAuthors,
  getAllBlogTags,
  bulkUpdateStatus,
  toggleFeatured,
};
