import { buildPostPath } from "@/lib/postSlug";
import {
  SITE_URL,
  SITEMAP_PAGE_SIZE,
  absoluteUrl,
  clampPages,
  pagesFromTotal,
  sitemapFetchJson,
  type SitemapEntry,
} from "./config";

type ExpertiseRow = { name?: string; title?: string; _id?: string };
type ProvinceRow = { id: number; name: string; slug: string };
type CategoryRow = {
  name?: string;
  title?: string;
  slug?: string;
  _id?: string;
};

function slugPart(value: string): string {
  return value.trim().replace(/\s+/g, "-");
}

function entry(
  path: string,
  opts?: Partial<SitemapEntry>
): SitemapEntry {
  return {
    url: absoluteUrl(path),
    lastModified: opts?.lastModified || new Date(),
    changeFrequency: opts?.changeFrequency || "daily",
    priority: opts?.priority ?? 0.7,
  };
}

export function buildStaticEntries(): SitemapEntry[] {
  const today = new Date();
  return [
    entry("/", { changeFrequency: "daily", priority: 1, lastModified: today }),
    entry("/explore", {
      changeFrequency: "hourly",
      priority: 0.9,
      lastModified: today,
    }),
    entry("/projects", {
      changeFrequency: "daily",
      priority: 0.9,
      lastModified: today,
    }),
    entry("/billboards", {
      changeFrequency: "daily",
      priority: 0.9,
      lastModified: today,
    }),
    entry("/academy", {
      changeFrequency: "daily",
      priority: 0.85,
      lastModified: today,
    }),
    entry("/videos", {
      changeFrequency: "daily",
      priority: 0.8,
      lastModified: today,
    }),
  ];
}

function extractHashtags(...texts: Array<string | undefined | null>): string[] {
  const found = new Set<string>();
  const re = /#([\p{L}\p{N}_]+)/gu;
  for (const text of texts) {
    if (!text) continue;
    let match: RegExpExecArray | null;
    while ((match = re.exec(text)) !== null) {
      const tag = match[1]?.trim();
      if (tag && tag.length >= 2 && tag.length <= 40) found.add(tag);
    }
  }
  return [...found];
}

async function fetchExpertiseNames(): Promise<string[]> {
  const data = await sitemapFetchJson<
    ExpertiseRow[] | { expertises?: ExpertiseRow[]; data?: ExpertiseRow[] }
  >("/expertise");
  const rows = Array.isArray(data)
    ? data
    : data?.expertises || data?.data || [];
  return rows
    .map((e) => e.name || e.title || "")
    .filter(Boolean)
    .slice(0, 40);
}

async function fetchAcademyCategories(): Promise<string[]> {
  const data = await sitemapFetchJson<{
    categories?: CategoryRow[];
    data?: CategoryRow[] | { categories?: CategoryRow[] };
  }>("/academy/categories?status=active&limit=100");
  const rows = Array.isArray(data?.categories)
    ? data.categories
    : Array.isArray(data?.data)
      ? data.data
      : Array.isArray((data?.data as { categories?: CategoryRow[] })?.categories)
        ? (data?.data as { categories: CategoryRow[] }).categories
        : [];
  return rows
    .map((c) => c.name || c.title || c.slug || "")
    .filter(Boolean)
    .slice(0, 80);
}

async function sampleHashtags(): Promise<string[]> {
  const data = await sitemapFetchJson<{
    posts?: Array<{ caption?: string }>;
  }>(`/users/web?page=1&limit=200&sort=latest`);
  const tags = extractHashtags(
    ...(data?.posts || []).map((p) => p.caption || "")
  );
  return tags.slice(0, 120);
}

export async function buildFilterEntries(): Promise<SitemapEntry[]> {
  const provincesModule = await import("@/data/provinces.json");
  const provinces = (
    Array.isArray(provincesModule)
      ? provincesModule
      : (provincesModule as { default: ProvinceRow[] }).default
  ) as ProvinceRow[];

  const [expertises, categories, hashtags] = await Promise.all([
    fetchExpertiseNames(),
    fetchAcademyCategories(),
    sampleHashtags(),
  ]);

  const urls = new Map<string, SitemapEntry>();
  const add = (path: string, priority = 0.65) => {
    urls.set(path, entry(path, { changeFrequency: "daily", priority }));
  };

  // صفحه پست‌ها — فیلتر تخصص / استان
  for (const exp of expertises) {
    add(`/${slugPart(`استخدام-${exp}`)}`, 0.75);
    add(`/videos/${slugPart(`ویدئو-ها-و-نمونه-کارهای-${exp}`)}`, 0.7);
    add(`/projects?expertise=${encodeURIComponent(exp)}`, 0.7);
  }
  add(`/${slugPart("استخدام-متخصصین-مد-و-زیبایی")}`, 0.7);
  add(`/videos/${slugPart("ویدئو-ها-متخصصین-مد-و-زیبایی")}`, 0.65);

  for (const province of provinces) {
    const pName = province.name;
    add(
      `/${slugPart(`استخدام-متخصصین-مد-و-زیبایی-در-استان-${pName}`)}`,
      0.7
    );
    add(
      `/billboards/${slugPart(`تبلیغات-خدمات-مد-و-زیبایی-در-استان-${pName}`)}`,
      0.7
    );
    for (const exp of expertises.slice(0, 12)) {
      add(`/${slugPart(`استخدام-${exp}-در-استان-${pName}`)}`, 0.68);
    }
  }

  // آموزشگاه — دسته‌بندی و رایگان
  add(`/academy?isFree=true`, 0.7);
  for (const cat of categories) {
    add(`/academy?category=${encodeURIComponent(cat)}`, 0.7);
  }

  // هشتگ‌های داینامیک (از محتوای واقعی)
  for (const tag of hashtags) {
    const q = encodeURIComponent(tag);
    add(`/?hashtag=${q}`, 0.72);
    add(`/explore?hashtag=${q}`, 0.72);
    add(`/academy?search=${encodeURIComponent(`#${tag}`)}`, 0.6);
  }

  return [...urls.values()];
}

/* ─── page counters ─── */

export async function countPostsPages(): Promise<number> {
  const data = await sitemapFetchJson<{
    totalPages?: number;
    totalItems?: number;
  }>(`/users/web?page=1&limit=${SITEMAP_PAGE_SIZE}`);
  if (data?.totalPages) return clampPages(data.totalPages);
  if (data?.totalItems) return pagesFromTotal(data.totalItems);
  return 1;
}

export async function countUsersPages(): Promise<number> {
  const data = await sitemapFetchJson<{
    total?: number;
    hasMore?: boolean;
    users?: unknown[];
  }>(`/users/seo/public-profiles?page=1&limit=${SITEMAP_PAGE_SIZE}`);
  if (typeof data?.total === "number") return pagesFromTotal(data.total);
  return data?.users?.length ? 1 : 1;
}

export async function countProjectsPages(): Promise<number> {
  const data = await sitemapFetchJson<{
    totalPages?: number;
    totalItems?: number;
    projects?: unknown[];
  }>(`/projects?page=1&limit=${SITEMAP_PAGE_SIZE}`);
  if (data?.totalPages) return clampPages(data.totalPages);
  if (data?.totalItems) return pagesFromTotal(data.totalItems);
  return data?.projects?.length ? 1 : 1;
}

export async function countBillboardsPages(): Promise<number> {
  const data = await sitemapFetchJson<{
    totalPages?: number;
    totalItems?: number;
    advertisings?: unknown[];
  }>(`/advertising/web?page=1&limit=${SITEMAP_PAGE_SIZE}`);
  if (data?.totalPages) return clampPages(data.totalPages);
  if (data?.totalItems) return pagesFromTotal(data.totalItems);
  return data?.advertisings?.length ? 1 : 1;
}

export async function countCoursesPages(): Promise<number> {
  const data = await sitemapFetchJson<{
    data?: {
      pagination?: { totalPages?: number; totalItems?: number };
      courses?: unknown[];
    };
  }>(
    `/academy/academy/get/curses?page=1&limit=${SITEMAP_PAGE_SIZE}&status=accept`
  );
  const pagination = data?.data?.pagination;
  if (pagination?.totalPages) return clampPages(pagination.totalPages);
  if (pagination?.totalItems) return pagesFromTotal(pagination.totalItems);
  return data?.data?.courses?.length ? 1 : 1;
}

export async function countAcademiesPages(): Promise<number> {
  const data = await sitemapFetchJson<{
    data?: {
      pagination?: { totalPages?: number; totalItems?: number };
      academies?: unknown[];
    };
    success?: boolean;
  }>(`/academy/academies?page=1&limit=${SITEMAP_PAGE_SIZE}`);
  const pagination = data?.data?.pagination;
  if (pagination?.totalPages) return clampPages(pagination.totalPages);
  if (pagination?.totalItems) return pagesFromTotal(pagination.totalItems);
  return data?.data?.academies?.length ? 1 : 1;
}

/* ─── page builders ─── */

export async function buildPostsPage(page: number): Promise<SitemapEntry[]> {
  const data = await sitemapFetchJson<{
    posts?: Array<{
      _id: string;
      caption?: string;
      user_name?: string;
      first_name?: string;
      last_name?: string;
      updatedAt?: string;
      createdAt?: string;
      type?: string;
    }>;
  }>(`/users/web?page=${page}&limit=${SITEMAP_PAGE_SIZE}&sort=latest`);

  return (data?.posts || [])
    .filter((p) => p?._id)
    .map((p) =>
      entry(buildPostPath(p._id, p), {
        changeFrequency: "hourly",
        priority: p.type === "video" ? 0.8 : 0.78,
        lastModified: p.updatedAt || p.createdAt || new Date(),
      })
    );
}

export async function buildUsersPage(page: number): Promise<SitemapEntry[]> {
  const data = await sitemapFetchJson<{
    users?: Array<{ user_name?: string; updatedAt?: string }>;
  }>(
    `/users/seo/public-profiles?page=${page}&limit=${SITEMAP_PAGE_SIZE}`
  );

  return (data?.users || [])
    .filter((u) => u.user_name)
    .map((u) =>
      entry(`/users/${encodeURIComponent(String(u.user_name))}`, {
        changeFrequency: "weekly",
        priority: 0.75,
        lastModified: u.updatedAt || new Date(),
      })
    );
}

export async function buildProjectsPage(page: number): Promise<SitemapEntry[]> {
  const data = await sitemapFetchJson<{
    projects?: Array<{
      _id: string;
      title?: string;
      updatedAt?: string;
      createdAt?: string;
    }>;
  }>(`/projects?page=${page}&limit=${SITEMAP_PAGE_SIZE}`);

  return (data?.projects || [])
    .filter((p) => p?._id)
    .map((p) => {
      const title = encodeURIComponent(p.title || "project");
      return entry(`/projects/${p._id}/${title}`, {
        changeFrequency: "daily",
        priority: 0.85,
        lastModified: p.updatedAt || p.createdAt || new Date(),
      });
    });
}

export async function buildBillboardsPage(
  page: number
): Promise<SitemapEntry[]> {
  const data = await sitemapFetchJson<{
    advertisings?: Array<{
      _id: string;
      title?: string;
      updatedAt?: string;
      createdAt?: string;
    }>;
    billboards?: Array<{
      _id: string;
      title?: string;
      updatedAt?: string;
      createdAt?: string;
    }>;
  }>(`/advertising/web?page=${page}&limit=${SITEMAP_PAGE_SIZE}`);

  const rows = data?.advertisings || data?.billboards || [];
  return rows
    .filter((b) => b?._id)
    .map((b) => {
      const title = encodeURIComponent(b.title || "billboard");
      return entry(`/billboards/${b._id}/${title}`, {
        changeFrequency: "daily",
        priority: 0.85,
        lastModified: b.updatedAt || b.createdAt || new Date(),
      });
    });
}

export async function buildCoursesPage(page: number): Promise<SitemapEntry[]> {
  const data = await sitemapFetchJson<{
    data?: {
      courses?: Array<{
        _id: string;
        cuorse_name?: string;
        academyId?: string;
        updatedAt?: string;
        createdAt?: string;
      }>;
    };
  }>(
    `/academy/academy/get/curses?page=${page}&limit=${SITEMAP_PAGE_SIZE}&status=accept`
  );

  const courses = data?.data?.courses || [];
  return courses
    .filter((c) => c?._id)
    .map((c) => {
      const name = encodeURIComponent(c.cuorse_name || "course");
      return entry(`/academy/${c._id}/${name}`, {
        changeFrequency: "weekly",
        priority: 0.8,
        lastModified: c.updatedAt || c.createdAt || new Date(),
      });
    });
}

export async function buildAcademiesPage(
  page: number
): Promise<SitemapEntry[]> {
  const data = await sitemapFetchJson<{
    data?: {
      academies?: Array<{
        _id: string;
        updatedAt?: string;
        createdAt?: string;
      }>;
    };
  }>(`/academy/academies?page=${page}&limit=${SITEMAP_PAGE_SIZE}`);

  const academies = data?.data?.academies || [];
  if (academies.length) {
    return academies
      .filter((a) => a?._id)
      .map((a) =>
        entry(`/academy/profile/${a._id}`, {
          changeFrequency: "weekly",
          priority: 0.75,
          lastModified: a.updatedAt || a.createdAt || new Date(),
        })
      );
  }

  // fallback: استخراج academyId از پکیج‌ها
  const coursesData = await sitemapFetchJson<{
    data?: {
      courses?: Array<{ academyId?: string; updatedAt?: string }>;
    };
  }>(
    `/academy/academy/get/curses?page=${page}&limit=${SITEMAP_PAGE_SIZE}&status=accept`
  );
  const ids = new Set<string>();
  for (const c of coursesData?.data?.courses || []) {
    if (c.academyId) ids.add(String(c.academyId));
  }
  return [...ids].map((id) =>
    entry(`/academy/profile/${id}`, {
      changeFrequency: "weekly",
      priority: 0.75,
    })
  );
}

export { SITE_URL };
