"""产物输出：图片本地化、TS 数据文件、JSON、Markdown 归档。"""

import re
from pathlib import Path

from config import CHAN_IMG_DIR, CHAN_IMG_URL_PREFIX, CHAN_DATA_FILE
from fetcher import fetch_bytes


def _guess_ext(url: str) -> str:
    m = re.search(r"\.(png|jpe?g|gif|webp|bmp|svg)", url, re.I)
    return "." + m.group(1).lower() if m else ".png"


def remote_image_resolver(src: str, alt: str) -> str:
    """不下载图片，正文保留远程链接。"""
    return f"![{alt}]({src})"


def make_image_resolver(p_num: int, refresh: bool = False):
    """返回一个闭包：把图片下载到 Vue 项目的 public 目录，返回可访问 URL。

    下载失败时回退到远程链接，保证正文不会因单张图片而中断。
    """
    CHAN_IMG_DIR.mkdir(parents=True, exist_ok=True)
    seq = 0

    def resolve(src: str, alt: str) -> str:
        nonlocal seq
        seq += 1
        ext = _guess_ext(src)
        fname = f"p{p_num:03d}_{seq:02d}{ext}"
        dest = CHAN_IMG_DIR / fname
        if refresh or not dest.exists():
            try:
                dest.write_bytes(fetch_bytes(src))
            except Exception as e:  # noqa: BLE001
                print(f"    [img] 下载失败，使用远程链接：{src}（{e}）")
                return f"![{alt}]({src})"
        url = f"{CHAN_IMG_URL_PREFIX}/{fname}"
        return f"![{alt}]({url})"

    return resolve


def _ts_escape(s: str) -> str:
    """转义模板字符串中的特殊字符：反斜杠、反引号、${。"""
    return s.replace("\\", "\\\\").replace("`", "\\`").replace("${", "\\${")


def _ts_str(s: str) -> str:
    return "`" + _ts_escape(s) + "`"


def write_ts_file(articles: list[dict], path: Path, stamp: str) -> None:
    """生成 ``chanlun.ts``，导出 ``chanlunLessons: Article[]``。"""
    lines: list[str] = []
    lines.append("import type { Article } from '@/types/article'")
    lines.append("")
    lines.append("/**")
    lines.append(" * 缠论《教你炒股票》系列原文")
    lines.append(f" * 共 {len(articles)} 课 · 抓取自 https://www.kline8.com/chanlun")
    lines.append(f" * 由 py-chan 爬虫自动生成 · {stamp}")
    lines.append(" */")
    lines.append("export const chanlunLessons: Article[] = [")

    for a in articles:
        lines.append("  {")
        lines.append(f"    id: {_ts_str(a['id'])},")
        lines.append(f"    slug: {_ts_str(a['slug'])},")
        lines.append("    category: 'chanlun',")
        lines.append(f"    title: {_ts_str(a['title'])},")
        lines.append(f"    subtitle: {_ts_str(a['subtitle'])},")
        lines.append(f"    lesson: {a['lesson']},")
        lines.append(f"    date: {_ts_str(a['date'])},")
        tags = ", ".join(_ts_str(t) for t in a["tags"])
        lines.append(f"    tags: [{tags}],")
        lines.append(f"    excerpt: {_ts_str(a['excerpt'])},")
        lines.append(f"    readingTime: {a['readingTime']},")
        lines.append(f"    content: {_ts_str(a['content'])},")
        lines.append("  },")
    lines.append("]")
    lines.append("")

    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text("\n".join(lines), encoding="utf-8")
