import type { Metadata } from "next";
import Link from "next/link";
import { notFound } from "next/navigation";
import { MarkdownPreview } from "@/components/markdown-preview";
import { AdsenseContentAd } from "@/components/adsense-content-ad";
import { PublicBlogHeader } from "@/components/public-blog-header";
import { SiteFooter } from "@/components/site-footer";
import { ServerStaticUiLocalizer } from "@/components/server-static-ui-localizer";
import { getPublicSiteAbsoluteUrl } from "@/lib/mail-urls";
import { getAdsenseSlot } from "@/lib/adsense-server";
import { relatedBlogPosts } from "@/lib/blog-growth";
import { getBlogSocialImageUrl } from "@/lib/blog-social-image";
import {
  OFFICIAL_MAIL_SAME_AS,
  OFFICIAL_MAIL_SITE_NAME,
} from "@/lib/official-mail-brand";
import { getLocaleOption } from "@/lib/i18n-config";
import { resolveRequestLocale } from "@/lib/i18n-server";
import { getLocalizedPublicPath, getPublicLanguageAlternates } from "@/lib/i18n-urls";
import {
  getLocalizedBlogArticle,
} from "@/lib/localized-blog-content";
import { hasLocalizedBlogArticle } from "@/lib/localized-blog-slugs";
import {
  getPublishedMarketingBlogPost,
  getPublishedMarketingBlogPosts,
  type MarketingBlogPost,
} from "@/lib/marketing-blog";

type BlogArticlePageProps = {
  params: Promise<{ slug: string }>;
};

export const dynamic = "force-dynamic";

function formatDate(value: string | null, locale = "ko") {
  if (!value) return "";

  return new Intl.DateTimeFormat(getLocaleOption(locale as Parameters<typeof getLocaleOption>[0]).htmlLang, {
    year: "numeric",
    month: "long",
    day: "numeric",
  }).format(new Date(value));
}

function JsonLd({ data }: { data: Record<string, unknown> }) {
  return <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }} />;
}

function articleUrl(slug: string, locale: Parameters<typeof getLocaleOption>[0] = "ko") {
  return getPublicSiteAbsoluteUrl(getLocalizedPublicPath(`/blog/${slug}`, locale));
}

function tableOfContents(content: string) {
  return content
    .split("\n")
    .map((line) => line.trim())
    .filter((line) => /^##\s+/.test(line))
    .map((line) => line.replace(/^##\s+/, ""));
}

export async function generateMetadata({ params }: BlogArticlePageProps): Promise<Metadata> {
  const { slug } = await params;
  const post = await getPublishedMarketingBlogPost(slug);

  if (!post) return {};

  const locale = await resolveRequestLocale();
  const localizedArticle = getLocalizedBlogArticle(slug, locale);

  if (locale !== "ko" && localizedArticle) {
    const pathname = `/blog/${slug}`;
    const url = getPublicSiteAbsoluteUrl(getLocalizedPublicPath(pathname, locale));
    const imageUrl = getBlogSocialImageUrl(post.contentMarkdown);
    return {
      title: `${localizedArticle.title} | OfficialMail`,
      description: localizedArticle.description,
      alternates: {
        canonical: url,
        languages: getPublicLanguageAlternates(pathname, getPublicSiteAbsoluteUrl("/")),
      },
      openGraph: {
        title: localizedArticle.title,
        description: localizedArticle.description,
        url,
        siteName: OFFICIAL_MAIL_SITE_NAME,
        locale: getLocaleOption(locale).htmlLang.replace("-", "_"),
        type: "article",
        publishedTime: post.publishedAt ?? undefined,
        modifiedTime: post.updatedAt,
        images: [{ url: imageUrl, width: 1600, height: 900, alt: localizedArticle.title }],
      },
      twitter: {
        card: "summary_large_image",
        title: localizedArticle.title,
        description: localizedArticle.description,
        images: [imageUrl],
      },
    };
  }

  const url = articleUrl(post.slug);
  const imageUrl = getBlogSocialImageUrl(post.contentMarkdown);
  const pathname = `/blog/${post.slug}`;
  const languageAlternates = hasLocalizedBlogArticle(post.slug)
    ? getPublicLanguageAlternates(pathname, getPublicSiteAbsoluteUrl("/"))
    : {
        "ko-KR": url,
        "x-default": url,
      };

  return {
    title: `${post.title} | 오피셜메일 블로그`,
    description: post.seoDescription,
    keywords: post.keywords,
    alternates: {
      canonical: url,
      languages: languageAlternates,
    },
    openGraph: {
      title: post.title,
      description: post.seoDescription,
      url,
      siteName: OFFICIAL_MAIL_SITE_NAME,
      locale: "ko_KR",
      type: "article",
      publishedTime: post.publishedAt ?? undefined,
      modifiedTime: post.updatedAt,
      images: [{ url: imageUrl, width: 1600, height: 900, alt: post.title }],
    },
    twitter: {
      card: "summary_large_image",
      title: post.title,
      description: post.seoDescription,
      images: [imageUrl],
    },
  };
}

function buildSchemas(post: MarketingBlogPost, locale: Parameters<typeof getLocaleOption>[0]) {
  const url = articleUrl(post.slug, locale);
  const homeUrl = getPublicSiteAbsoluteUrl("/");
  const organizationId = `${homeUrl}#organization`;
  const imageUrl = getBlogSocialImageUrl(post.contentMarkdown);

  return {
    article: {
      "@context": "https://schema.org",
      "@type": "BlogPosting",
      "@id": `${url}#article`,
      articleSection: post.keywords[0] || "기업메일",
      author: {
        "@type": "Organization",
        "@id": organizationId,
        name: "오피셜메일",
        url: homeUrl,
      },
      about: post.keywords.map((keyword) => ({
        "@type": "Thing",
        name: keyword,
      })),
      dateModified: post.updatedAt,
      datePublished: post.publishedAt ?? post.createdAt,
      description: post.seoDescription,
      headline: post.title,
      image: {
        "@type": "ImageObject",
        url: imageUrl,
        width: 1600,
        height: 900,
      },
      inLanguage: getLocaleOption(locale).htmlLang,
      isPartOf: {
        "@id": `${getPublicSiteAbsoluteUrl(getLocalizedPublicPath("/blog", locale))}#blog`,
      },
      keywords: post.keywords.join(", "),
      mainEntityOfPage: {
        "@type": "WebPage",
        "@id": url,
      },
      publisher: {
        "@type": "Organization",
        "@id": organizationId,
        legalName: "카베닉스(KAVENIX)",
        name: "오피셜메일",
        sameAs: OFFICIAL_MAIL_SAME_AS,
        logo: {
          "@type": "ImageObject",
          url: getPublicSiteAbsoluteUrl("/icon-512.png"),
          width: 512,
          height: 512,
        },
      },
      url,
      wordCount: post.contentMarkdown.replace(/\s/g, "").length,
    },
    breadcrumb: {
      "@context": "https://schema.org",
      "@type": "BreadcrumbList",
      itemListElement: [
        { "@type": "ListItem", position: 1, name: locale === "ko" ? "오피셜메일" : "OfficialMail", item: getPublicSiteAbsoluteUrl(getLocalizedPublicPath("/", locale)) },
        { "@type": "ListItem", position: 2, name: locale === "ko" ? "블로그" : "Blog", item: getPublicSiteAbsoluteUrl(getLocalizedPublicPath("/blog", locale)) },
        { "@type": "ListItem", position: 3, name: post.title, item: url },
      ],
    },
    faq: post.faqs.length > 0 ? {
      "@context": "https://schema.org",
      "@type": "FAQPage",
      mainEntity: post.faqs.map((faq) => ({
        "@type": "Question",
        name: faq.question,
        acceptedAnswer: {
          "@type": "Answer",
          text: faq.answer,
        },
      })),
    } : null,
  };
}

export default async function BlogArticlePage({ params }: BlogArticlePageProps) {
  const { slug } = await params;
  const post = await getPublishedMarketingBlogPost(slug);

  if (!post) {
    notFound();
  }

  const locale = await resolveRequestLocale();
  const localizedArticle = locale === "ko" ? null : getLocalizedBlogArticle(slug, locale);
  const displayPost: MarketingBlogPost = localizedArticle
    ? {
        ...post,
        contentMarkdown: localizedArticle.sections
          .map((section) => `## ${section.title}\n\n${section.body}`)
          .join("\n\n"),
        excerpt: localizedArticle.description,
        faqs: [],
        keywords: [localizedArticle.category],
        seoDescription: localizedArticle.description,
        title: localizedArticle.title,
      }
    : post;
  const [allPosts] = await Promise.all([getPublishedMarketingBlogPosts()]);
  const localizedAllPosts = locale === "ko"
    ? allPosts
    : allPosts.flatMap((item) => {
        const translated = getLocalizedBlogArticle(item.slug, locale);
        return translated
          ? [{
              ...item,
              excerpt: translated.description,
              keywords: [translated.category],
              seoDescription: translated.description,
              title: translated.title,
            }]
          : [];
      });
  const relatedPosts = relatedBlogPosts(displayPost, localizedAllPosts, 3);
  const toc = tableOfContents(displayPost.contentMarkdown);
  const schemas = buildSchemas(displayPost, locale);

  return (
    <ServerStaticUiLocalizer locale={locale}>
    <main className="min-h-screen bg-white text-[#16233c]">
      <JsonLd data={schemas.article} />
      <JsonLd data={schemas.breadcrumb} />
      {schemas.faq ? <JsonLd data={schemas.faq} /> : null}
      <PublicBlogHeader
        pathname={hasLocalizedBlogArticle(post.slug) ? `/blog/${post.slug}` : "/blog"}
      />

      <article>
        <header className="border-b border-[#edf1f6] bg-[radial-gradient(circle_at_78%_12%,rgba(185,212,255,0.27),transparent_30%),linear-gradient(180deg,#fbfdff_0%,#ffffff_100%)]">
          <div className="mx-auto w-full max-w-[1420px] px-4 pb-14 pt-10 sm:px-8 sm:pb-20 sm:pt-14 xl:px-10">
            <nav aria-label="현재 위치" className="flex flex-wrap items-center gap-2 text-[12px] text-[#8290a6]">
              <Link href={getLocalizedPublicPath("/", locale)} className="hover:text-[#2f6df6]">오피셜메일</Link>
              <span>/</span>
              <Link href={getLocalizedPublicPath("/blog", locale)} className="hover:text-[#2f6df6]">블로그</Link>
              <span>/</span>
              <span className="truncate text-[#546783]">{displayPost.title}</span>
            </nav>
            <p className="mt-9 text-[13px] font-semibold text-[#2f6df6]">{displayPost.keywords[0] || "오피셜메일 블로그"}</p>
            <h1 className="mt-4 max-w-[960px] text-balance text-[36px] font-semibold leading-[1.15] tracking-[-0.075em] text-[#16233c] sm:text-[54px]">
              {displayPost.title}
            </h1>
            <p className="mt-6 max-w-[740px] text-[16px] leading-8 text-[#64748b] sm:text-[18px]">{displayPost.seoDescription}</p>
            <div className="mt-8 flex flex-wrap items-center gap-x-3 gap-y-2 text-[12px] text-[#7c8da8]">
              <time dateTime={displayPost.publishedAt ?? displayPost.updatedAt}>{formatDate(displayPost.publishedAt ?? displayPost.updatedAt, locale)}</time>
            </div>
          </div>
        </header>

        <div className="mx-auto grid w-full max-w-[1420px] gap-10 px-4 py-12 sm:px-8 sm:py-16 xl:grid-cols-[210px_minmax(0,820px)_minmax(0,1fr)] xl:px-10">
          <aside className="hidden xl:block">
            <div className="sticky top-28">
              <div className="border-l border-[#e5ecf7] pl-4">
                <p className="text-[12px] font-semibold text-[#526784]">이 글의 내용</p>
                <ol className="mt-4 space-y-2.5 text-[12px] leading-5 text-[#8190a6]">
                  {toc.map((item, index) => <li key={`${item}-${index}`}>{String(index + 1).padStart(2, "0")}. {item}</li>)}
                </ol>
              </div>
              <AdsenseContentAd
                className="!mb-0 !mt-8"
                format="rectangle"
                locale={locale}
                slot={getAdsenseSlot("sidebar")}
              />
            </div>
          </aside>
          <div className="min-w-0">
            <MarkdownPreview
              content={displayPost.contentMarkdown}
              inlineContent={(
                <AdsenseContentAd
                  format="in-article"
                  locale={locale}
                  slot={getAdsenseSlot("inArticle")}
                />
              )}
            />
            <AdsenseContentAd
              className="!my-10"
              format="horizontal"
              locale={locale}
              slot={getAdsenseSlot("articleFooter")}
            />
            <div className="mt-14 border-y border-[#e8eef7] py-7">
              <p className="text-[13px] font-semibold text-[#2f6df6]">오피셜메일로 시작하기</p>
              <h2 className="mt-2 text-[24px] font-semibold tracking-[-0.055em] text-[#16233c]">대표 메일 하나부터 공식 주소로 운영해보세요.</h2>
              <p className="mt-3 text-[14px] leading-7 text-[#64748b]">대표 메일 하나부터 회사의 공식 주소로 운영하고, 도메인 연결 값은 메일함에서 바로 확인하세요.</p>
              <div className="mt-5 flex flex-wrap gap-2">
                <Link href="/login" className="om-btn-primary h-10 rounded-[10px] px-4 text-[13px] shadow-none">오피셜메일 시작하기</Link>
                <Link href={getLocalizedPublicPath("/", locale)} className="om-btn-secondary h-10 rounded-[10px] px-4 text-[13px] shadow-none">기업메일 서비스 보기</Link>
              </div>
            </div>
          </div>
          <aside className="hidden xl:block" />
        </div>
      </article>

      {relatedPosts.length > 0 ? (
        <section className="border-t border-[#edf1f6] bg-[#fbfcff]">
          <div className="mx-auto w-full max-w-[1420px] px-4 py-12 sm:px-8 sm:py-16 xl:px-10">
            <div className="flex items-end justify-between gap-4">
              <div>
                <p className="text-[12px] font-semibold text-[#2f6df6]">NEXT POST</p>
                <h2 className="mt-2 text-[26px] font-semibold tracking-[-0.06em] text-[#16233c] sm:text-[34px]">함께 보면 좋은 글</h2>
              </div>
              <Link href={getLocalizedPublicPath("/blog", locale)} className="text-[13px] font-semibold text-[#526784] hover:text-[#2f6df6]">전체 글 보기 →</Link>
            </div>
            <div className="mt-8 divide-y divide-[#e5ecf7] border-y border-[#e5ecf7]">
              {relatedPosts.map((related) => (
                <Link key={related.id} href={getLocalizedPublicPath(`/blog/${related.slug}`, locale)} className="group grid gap-3 py-5 sm:grid-cols-[minmax(0,1fr)_auto] sm:items-center">
                  <div>
                    <p className="text-[12px] font-semibold text-[#2f6df6]">{related.keywords[0] || "기업메일"}</p>
                    <p className="mt-1.5 text-[17px] font-semibold tracking-[-0.04em] text-[#30425f] transition-colors group-hover:text-[#2f6df6]">{related.title}</p>
                  </div>
                  <span className="text-[13px] font-semibold text-[#70819d] group-hover:text-[#2f6df6]">읽기 →</span>
                </Link>
              ))}
            </div>
          </div>
        </section>
      ) : null}
      <SiteFooter className="bg-white pt-12" />
    </main>
    </ServerStaticUiLocalizer>
  );
}
