export type BlogGrowthPost = {
  contentMarkdown: string;
  id: number;
  keywords: string[];
  slug: string;
  status: "draft" | "published";
  title: string;
};

export type BlogContentIdea = {
  cluster: string;
  description: string;
  keywords: string[];
  outline: string[];
  slug: string;
  title: string;
};

export const BLOG_CONTENT_IDEAS: BlogContentIdea[] = [
  {
    cluster: "DNS 문제 해결",
    description: "카페24에서 회사 도메인을 오피셜메일에 연결할 때 입력할 MX·SPF·DKIM·DMARC 위치와 검증 순서를 설명합니다.",
    keywords: ["카페24 도메인 메일", "카페24 MX 설정", "카페24 SPF DKIM"],
    outline: ["카페24 DNS 관리 화면 찾기", "MX와 SPF 입력", "DKIM·DMARC 입력", "연결 상태와 발송 테스트"],
    slug: "cafe24-domain-email-dns-setup",
    title: "카페24 도메인 메일 설정 방법: MX·SPF·DKIM 연결 순서",
  },
  {
    cluster: "DNS 문제 해결",
    description: "DKIM TXT 조회가 SERVFAIL로 끝날 때 DNS 제공업체의 길이 제한, 따옴표 분할, 1024-bit 호환 모드를 점검합니다.",
    keywords: ["DKIM SERVFAIL", "DKIM DNS 서버 오류", "DKIM TXT 등록 실패"],
    outline: ["SERVFAIL의 의미", "긴 TXT와 DNS 제공업체 제한", "1024-bit 호환 키 사용", "공개 DNS 재확인"],
    slug: "dkim-servfail-dns-fix",
    title: "DKIM 조회가 SERVFAIL로 실패할 때 확인할 DNS 설정",
  },
  {
    cluster: "DNS 문제 해결",
    description: "한 도메인에 SPF TXT가 여러 개 등록되어 PermError가 발생하는 원인과 하나의 정책으로 합치는 방법을 안내합니다.",
    keywords: ["SPF PermError", "SPF 레코드 여러 개", "SPF 중복 해결"],
    outline: ["SPF 중복이 문제가 되는 이유", "현재 TXT 레코드 조회", "include 정책 합치기", "Gmail 원본 보기로 PASS 확인"],
    slug: "spf-permerror-duplicate-record-fix",
    title: "SPF PermError 해결: 중복 TXT 레코드를 하나로 합치는 방법",
  },
  {
    cluster: "DNS 문제 해결",
    description: "DMARC 값에 쉼표나 잘못된 구분자가 들어가 불일치가 발생하는 사례와 올바른 정책 문법을 정리합니다.",
    keywords: ["DMARC 불일치", "DMARC 설정 오류", "DMARC rua 설정"],
    outline: ["정상 DMARC 문법", "세미콜론과 쉼표 오류", "정책 단계 선택", "외부 DNS에서 확인"],
    slug: "dmarc-record-syntax-fix",
    title: "DMARC 불일치 해결: TXT 문법과 DNS 조회 결과 확인하기",
  },
  {
    cluster: "업종별 메일 운영",
    description: "1인 사업자가 처음 만들 대표 주소와 문의·정산·제휴 주소의 우선순위를 실제 운영 기준으로 정리합니다.",
    keywords: ["1인 사업자 이메일", "대표 메일 주소 추천", "회사 이메일 이름"],
    outline: ["대표 주소 하나부터 시작하기", "contact·support·billing 역할", "개인 계정과 분리", "사업 성장에 맞춘 멤버 추가"],
    slug: "solo-business-email-address-guide",
    title: "1인 사업자 회사 이메일 주소는 무엇부터 만들면 좋을까",
  },
  {
    cluster: "업종별 메일 운영",
    description: "세금계산서, 결제, 환불 증빙을 고객 문의와 분리해 담당자가 바뀌어도 기록이 남는 메일 구조를 설명합니다.",
    keywords: ["세금계산서 이메일", "정산 메일 주소", "billing 이메일"],
    outline: ["정산 메일을 분리해야 하는 이유", "권장 주소 예시", "폴더와 담당자 규칙", "퇴사·인수인계 대비"],
    slug: "billing-tax-invoice-email-operations",
    title: "세금계산서·정산 메일을 고객 문의와 분리하는 운영 방법",
  },
  {
    cluster: "업종별 메일 운영",
    description: "제안서와 입점 문의를 개인 메일이 아닌 partnership 주소로 받아 담당자에게 빠르게 전달하는 구조를 다룹니다.",
    keywords: ["제휴 메일 주소", "입점 문의 이메일", "partnership 이메일"],
    outline: ["제휴 문의가 누락되는 이유", "권장 공식 주소", "담당자 전달 규칙", "답변 템플릿과 기록 관리"],
    slug: "partnership-email-address-operations",
    title: "제휴·입점 문의를 놓치지 않는 공식 메일 주소 운영법",
  },
  {
    cluster: "서비스 전환",
    description: "개인 Gmail로 쌓인 업무를 회사 도메인 메일로 옮길 때 주소 공개, 자동응답, 과거 기록 보관 순서를 안내합니다.",
    keywords: ["Gmail 회사 메일 전환", "개인 메일 기업메일 이전", "도메인 메일 전환"],
    outline: ["새 주소를 먼저 개설", "외부 채널 주소 교체", "이전 주소 자동응답", "과거 메일과 연락처 보관"],
    slug: "gmail-to-company-domain-email-migration",
    title: "개인 Gmail에서 회사 도메인 메일로 전환하는 순서",
  },
  {
    cluster: "서비스 전환",
    description: "메일 서비스를 바꾸기 전에 MX 전환 시점, 기존 메일 보관, 발신 인증, 복구 계획을 체크리스트로 제공합니다.",
    keywords: ["기업메일 이전", "메일 서비스 변경", "MX 전환 체크리스트"],
    outline: ["기존 메일 백업", "DNS TTL 확인", "MX·SPF·DKIM 전환", "수신·발신 테스트와 복구"],
    slug: "business-email-migration-checklist",
    title: "기업메일 서비스 이전 전 확인할 MX·데이터 보관 체크리스트",
  },
];

function keywordTokens(values: string[]) {
  return new Set(
    values
      .join(" ")
      .toLowerCase()
      .split(/[^a-z0-9가-힣]+/)
      .map((token) => token.trim())
      .filter((token) => token.length >= 2),
  );
}

export function relatedBlogPosts(
  current: Pick<BlogGrowthPost, "id" | "keywords" | "title" | "contentMarkdown">,
  posts: BlogGrowthPost[],
  limit = 3,
) {
  const currentTokens = keywordTokens([
    current.title,
    ...current.keywords,
    current.contentMarkdown.slice(0, 1200),
  ]);

  return posts
    .filter((post) => post.id !== current.id && post.status === "published")
    .map((post) => {
      const postTokens = keywordTokens([post.title, ...post.keywords]);
      const overlap = Array.from(postTokens).filter((token) => currentTokens.has(token)).length;
      const titleMentioned = current.contentMarkdown.includes(`/blog/${post.slug}`) ? -100 : 0;
      return { post, score: overlap * 3 + titleMentioned };
    })
    .sort((left, right) => right.score - left.score || right.post.id - left.post.id)
    .slice(0, limit)
    .map(({ post }) => post);
}

export function contentIdeaMarkdown(idea: BlogContentIdea) {
  return [
    `${idea.description}`,
    "",
    ...idea.outline.flatMap((heading) => [
      `## ${heading}`,
      "",
      "독자가 이 단계에서 실제로 확인해야 할 화면, 값, 오류 사례를 구체적으로 설명합니다.",
      "",
    ]),
    "## 자주 묻는 질문",
    "",
    "실제 설정 과정에서 반복해서 묻는 질문과 짧고 명확한 답변을 추가합니다.",
  ].join("\n");
}
