import "server-only";
import { getDbPool } from "./db";

const FALLBACK_SITE_BASE_URL = "https://thebookquill.com";
const DEFAULT_TITLE = "The Book Quill";
const DEFAULT_DESCRIPTION =
  "Professional Book Writing, Editing & Publishing Services in USA";
const DEFAULT_KEYWORDS =
  "book writing, book editing, book publishing, ghostwriting, author services, The Book Quill";
const DEFAULT_OG_IMAGE_PATH = "/assets/images/logo.webp";

function safeUrl(value, fallback) {
  try {
    return new URL(value);
  } catch {
    return new URL(fallback);
  }
}

export function getSiteBaseUrl() {
  const candidate =
    process.env.SITE_BASE_URL ||
    process.env.NEXT_PUBLIC_SITE_URL ||
    FALLBACK_SITE_BASE_URL;

  return safeUrl(candidate, FALLBACK_SITE_BASE_URL).toString().replace(/\/$/, "");
}

function getAdminBaseUrl() {
  const candidate =
    process.env.ADMIN_UPLOADS_BASE_URL ||
    process.env.NEXT_PUBLIC_ADMIN_UPLOADS_BASE_URL ||
    "http://127.0.0.1/saqib_brand/admin";

  return safeUrl(candidate, "http://127.0.0.1/saqib_brand/admin")
    .toString()
    .replace(/\/$/, "");
}

export function normalizeRoutePath(pathname) {
  if (!pathname || pathname === "/") {
    return "/";
  }

  let normalized = pathname.trim();

  if (/^https?:\/\//i.test(normalized)) {
    try {
      normalized = new URL(normalized).pathname;
    } catch {
      normalized = "/";
    }
  }

  normalized = normalized.replace(/\\/g, "/").replace(/\/+/g, "/");

  if (!normalized.startsWith("/")) {
    normalized = `/${normalized}`;
  }

  if (normalized.length > 1) {
    normalized = normalized.replace(/\/+$/, "");
  }

  return normalized || "/";
}

function normalizeSeoImageUrl(imagePath) {
  const value = (imagePath || "").trim();

  if (!value) {
    return `${getSiteBaseUrl()}${DEFAULT_OG_IMAGE_PATH}`;
  }

  if (/^https?:\/\//i.test(value)) {
    return value;
  }

  if (/^\/?uploads\//i.test(value)) {
    return `${getAdminBaseUrl()}/${value.replace(/^\/+/, "")}`;
  }

  if (value.startsWith("/")) {
    return `${getSiteBaseUrl()}${value}`;
  }

  return `${getSiteBaseUrl()}/${value.replace(/^\/+/, "")}`;
}

function normalizeCanonicalUrl(canonicalUrl, pathname) {
  const value = (canonicalUrl || "").trim();
  const routePath = normalizeRoutePath(pathname);

  if (!value) {
    return `${getSiteBaseUrl()}${routePath}`;
  }

  if (/^https?:\/\//i.test(value)) {
    return value;
  }

  if (value.startsWith("/")) {
    return `${getSiteBaseUrl()}${value}`;
  }

  return `${getSiteBaseUrl()}/${value.replace(/^\/+/, "")}`;
}

async function querySeoPages(query, params = []) {
  try {
    const [rows] = await getDbPool().query(query, params);
    return rows;
  } catch (error) {
    if (error?.code === "ER_NO_SUCH_TABLE") {
      return [];
    }

    throw error;
  }
}

function parseFaqItems(rawFaqJson) {
  if (!rawFaqJson) {
    return [];
  }

  try {
    const parsed = JSON.parse(rawFaqJson);

    if (!Array.isArray(parsed)) {
      return [];
    }

    return parsed
      .map((item) => ({
        question: String(item?.question || "").trim(),
        answer: String(item?.answer || "").trim(),
      }))
      .filter((item) => item.question && item.answer);
  } catch {
    return [];
  }
}

function parseJsonObject(rawJson) {
  if (!rawJson) {
    return null;
  }

  try {
    const parsed = JSON.parse(rawJson);

    if (!parsed || Array.isArray(parsed) || typeof parsed !== "object") {
      return null;
    }

    return parsed;
  } catch {
    return null;
  }
}

export async function getPublishedSeoPageByPath(pathname) {
  const routePath = normalizeRoutePath(pathname);
  let rows;

  try {
    rows = await querySeoPages(
      `SELECT page_name, route_path, meta_title, meta_description, meta_keywords, canonical_url,
              og_title, og_description, og_image, twitter_title, twitter_description, twitter_image,
              service_schema_json, faq_items_json, robots_index, robots_follow, status
       FROM seo_pages
       WHERE route_path = ? AND status = 'published'
       LIMIT 1`,
      [routePath]
    );
  } catch (error) {
    if (error?.code !== "ER_BAD_FIELD_ERROR") {
      throw error;
    }

    rows = await querySeoPages(
      `SELECT page_name, route_path, meta_title, meta_description, meta_keywords, canonical_url,
              og_title, og_description, og_image,
              NULL AS twitter_title, NULL AS twitter_description, NULL AS twitter_image,
              NULL AS service_schema_json, NULL AS faq_items_json, robots_index, robots_follow, status
       FROM seo_pages
       WHERE route_path = ? AND status = 'published'
       LIMIT 1`,
      [routePath]
    );
  }

  return rows[0] || null;
}

export async function getPageMetadata(pathname) {
  const routePath = normalizeRoutePath(pathname);
  const seoPage = await getPublishedSeoPageByPath(routePath);
  const siteBaseUrl = getSiteBaseUrl();
  const defaultOgImage = `${siteBaseUrl}${DEFAULT_OG_IMAGE_PATH}`;

  const title = seoPage?.meta_title || DEFAULT_TITLE;
  const description = seoPage?.meta_description || DEFAULT_DESCRIPTION;
  const keywords = seoPage?.meta_keywords || DEFAULT_KEYWORDS;
  const ogTitle = seoPage?.og_title || title;
  const ogDescription = seoPage?.og_description || description;
  const ogImage = seoPage?.og_image
    ? normalizeSeoImageUrl(seoPage.og_image)
    : defaultOgImage;
  const twitterTitle = seoPage?.twitter_title || ogTitle;
  const twitterDescription = seoPage?.twitter_description || ogDescription;
  const twitterImage = seoPage?.twitter_image
    ? normalizeSeoImageUrl(seoPage.twitter_image)
    : ogImage;
  const canonicalUrl = normalizeCanonicalUrl(seoPage?.canonical_url, routePath);
  const robotsIndex = seoPage ? Number(seoPage.robots_index) === 1 : true;
  const robotsFollow = seoPage ? Number(seoPage.robots_follow) === 1 : true;

  return {
    metadataBase: new URL(siteBaseUrl),
    title,
    description,
    keywords,
    applicationName: "The Book Quill",
    authors: [{ name: "The Book Quill" }],
    creator: "The Book Quill",
    publisher: "The Book Quill",
    robots: {
      index: robotsIndex,
      follow: robotsFollow,
      googleBot: {
        index: robotsIndex,
        follow: robotsFollow,
        "max-snippet": -1,
      },
    },
    alternates: {
      canonical: canonicalUrl,
    },
    verification: {
      google: "-vTGPGEsNe_Yb5WkC99k7SIn8vn9ijMNUdujPpCNqEo",
      other: {
        "msvalidate.01": "604E18F5DBAB2F9B0E01073055794572",
        "facebook-domain-verification": "rds2pqn8efi238t7ovx3yjh9jodwn4",
        "p:domain_verify": "070d183776f446d08c6e98a135c9c769",
      },
    },
    openGraph: {
      type: "website",
      locale: "en_US",
      siteName: "thebookquill",
      title: ogTitle,
      description: ogDescription,
      url: canonicalUrl,
      images: [
        {
          url: ogImage,
          width: 1366,
          height: 237,
          alt: title,
        },
      ],
    },
    twitter: {
      card: "summary_large_image",
      site: "@thebookquill",
      creator: "@thebookquill",
      title: twitterTitle,
      description: twitterDescription,
      images: [twitterImage],
    },
    icons: {
      icon: [
        { url: "/favicon.ico" },
        { url: "/favicon-96x96.png", sizes: "96x96", type: "image/png" },
        { url: "/favicon.svg", type: "image/svg+xml" },
      ],
      shortcut: "/favicon.ico",
      apple: [{ url: "/apple-touch-icon.png", sizes: "180x180" }],
    },
    manifest: "/site.webmanifest",
    other: {
      "content-language": "en-us",
      "theme-color": "#362312",
    },
  };
}

export async function getPageFaqSchema(pathname) {
  const seoPage = await getPublishedSeoPageByPath(pathname);
  const faqItems = parseFaqItems(seoPage?.faq_items_json);

  if (!faqItems.length) {
    return null;
  }

  return {
    "@context": "https://schema.org",
    "@type": "FAQPage",
    mainEntity: faqItems.map((item) => ({
      "@type": "Question",
      name: item.question,
      acceptedAnswer: {
        "@type": "Answer",
        text: item.answer,
      },
    })),
  };
}

export async function getPageStructuredSchemas(pathname) {
  const seoPage = await getPublishedSeoPageByPath(pathname);
  const serviceSchema = parseJsonObject(seoPage?.service_schema_json);
  const faqItems = parseFaqItems(seoPage?.faq_items_json);
  const schemas = [];

  if (serviceSchema) {
    schemas.push(serviceSchema);
  }

  if (faqItems.length) {
    schemas.push({
      "@context": "https://schema.org",
      "@type": "FAQPage",
      mainEntity: faqItems.map((item) => ({
        "@type": "Question",
        name: item.question,
        acceptedAnswer: {
          "@type": "Answer",
          text: item.answer,
        },
      })),
    });
  }

  if (!schemas.length) {
    return null;
  }

  return schemas.length === 1 ? schemas[0] : schemas;
}
