"""Build the offline evidence dashboard from audited source records."""

import hashlib
import json
import os
from pathlib import Path
from business_content import apply_business
from release_config import VERSION, OUTPUT, EVIDENCE, prepare

ROOT = Path(__file__).resolve().parents[1]


def read_json(name):
    return json.loads((ROOT / "research" / name).read_text(encoding="utf-8"))


def build_sources(review):
    sources = []
    for original in read_json("local_sources.json"):
        source_id = original["id"]
        canonical = review["topicDuplicates"].get(source_id, source_id)
        audit = review["sources"].get(canonical, {})
        source = {key: original[key] for key in ("id", "file", "name", "sha256", "pages")}
        source.update({
            "kindGroup": "local",
            "publisher": audit.get("publisher", "见原报告署名"),
            "published": audit.get("published", "见原报告封面"),
            "period": audit.get("period", "见原报告统计期"),
            "scope": audit.get("scope", "厨房其他品类"),
            "status": audit.get("status", "其他品类"),
            "note": audit.get("note", "已登记并提取文本；饮水用具规划采用对应细分类证据。"),
            "pagesReviewed": audit.get("pages", []),
        })
        if canonical != source_id:
            source["status"] = "同主题副本"
            source["note"] = f"同名同日期主题归并至 {canonical}，原文件与独立哈希保留。" + source["note"]
        sources.append(source)
    downloads = {item["id"]: item for item in read_json("public_downloads.json")}
    for entry in read_json("public_sources.json"):
        source = {**downloads[entry["id"]], **entry}
        source["kindGroup"] = "public"
        source["status"] = "原文已下载" if source.get("file") else "原文待获取"
        source["note"] = source["use"]
        source["pagesReviewed"] = {"W01": [7, 16], "W02": [7, 9], "W03": [12, 13], "W04": [2, 3]}.get(source["id"], [])
        if not source.get("file"):
            source["note"] += " 原文下载遇到 TLS 握手错误；此条保留为检索线索。"
        sources.append(source)
    workbooks = [
        ("X01", "硬百-四级分类 - 栾丽萍 东福.xlsx", "类目!D31:D45", "15个饮水用具四级分类", "业务分类基线"),
        ("X02", "品牌-餐饮具-完善.xlsx", "饮水用具记录：第293—442行，A:H", "品牌排名与引进意见", "候选品牌池"),
        ("X03", "厨具-资料参考目录.xlsx", "行业报告 目录；品牌表", "58条目录记录与品牌资料", "资料目录"),
    ]
    for source_id, filename, location, scope, status in workbooks:
        sources.append({
            "id": source_id, "name": filename, "file": filename, "kindGroup": "workbook",
            "publisher": "用户提供", "published": "业务版本日期待确认",
            "period": "分类及品牌清单快照", "scope": scope, "status": status,
            "location": location,
            "note": "分类与品牌目录作为原始参考；全年经营见P02，当前在售明细见P06，品牌排名保留品类、平台和统计期。",
            "sha256": hashlib.sha256((ROOT / filename).read_bytes()).hexdigest(),
        })
    for source in sources:
        source["images"] = {
            path.stem.split("-p")[-1]: path.relative_to(ROOT).as_posix()
            for path in sorted((ROOT / "research" / "page_images").glob(f"{source['id']}-p[0-9]*.png"))
        }
    return sources


def business_content():
    return {
        "supply": [
            {
                "title": "上游 · 材料、报价与质量",
                "finding": "德力股份在2025年经营讨论中分别披露能源和原料成本变化。市场监管总局2025年抽查对玻璃杯瓶壶检查迁移量、耐水性和内应力等项目，对塑料餐饮具检查对应材料迁移项目。",
                "action": "向供货方核验报价有效期、材料和使用温度、检测对应型号/批次；将包装、运输破损和商品贡献利润纳入单品核算。",
                "boundary": "公司成本变化与监管抽查各自保留统计范围；商城采购成本使用真实报价，准入项目按商品材质和用途逐款确认。",
                "refs": [{"id": "W03", "page": 13}, {"id": "W07", "page": None}],
            },
            {
                "title": "中游 · 制造、品牌与补货",
                "finding": "哈尔斯2026年上半年境内营业收入同比增长16.03%，同时包含大规模境外业务。华瓷2025年年报摘要列明茶具、咖啡具等日用陶瓷产品，也包含其他陶瓷业务。",
                "action": "品牌池按授权、真实到货价、供货率、最小起订量、补货周期、功能验收和清退条件建立可比表；杯壶与制造商其他业务分别核算。",
                "boundary": "企业经营用于供应商研究。品牌引入优先核验合作状态及细分类TOP10依据，商品组合按兑换金额优先和分频道毛利约束评估。",
                "refs": [{"id": "W01", "page": 16}, {"id": "W04", "page": 2}],
            },
            {
                "title": "下游 · 使用场景与组合增量",
                "finding": "任拓披露2025年1—4月部分主流电商平台咖啡器具相关线上销售额同比增长35%，所述范围包含咖啡机、磨豆机和手冲壶，并提出家庭咖啡角场景。",
                "action": "将手冲、法压、冷萃等实际器具及杯碟作为待验证组合方向；核对商城搜索、成交、连带和竞品到手价，再决定进入试验的具体款式。",
                "boundary": "咖啡杯、咖啡壶的独立增速待细分类数据；本轮选品为无电器具，面向企业员工福利场景，规划期2026-09至2027-02。",
                "refs": [{"id": "W06", "page": None}],
            },
        ],
        "signals": [
            {
                "title": "哈尔斯：收入与利润走势分化",
                "period": "2026 年上半年", "type": "公司经营",
                "value": "+12.83%", "unit": "营业收入同比", "tone": "teal",
                "detail": "营业收入 17.73 亿元；归母净利润同比 −46.50%。",
                "scope": "公司合并报表，包含境外业务。适用于供给背景和经营分化观察。",
                "source": "W01", "page": 7,
            },
            {
                "title": "嘉益股份：出口制造承压",
                "period": "2026 年上半年", "type": "公司经营",
                "value": "−26.10%", "unit": "营业收入同比", "tone": "red",
                "detail": "营业收入 10.34 亿元；归母净利润同比 −44.10%。",
                "scope": "以海外品牌 OEM / ODM 为主；国内商城归因另取同渠道交易证据。",
                "source": "W02", "page": 7,
            },
            {
                "title": "网上商品零售保持增长",
                "period": "2026 年 1—8 月", "type": "宏观对照",
                "value": "+4.3%", "unit": "累计同比",
                "tone": "teal",
                "detail": "同期社会消费品零售总额同比 +1.1%，网上商品零售中的“用类”同比 +1.1%。",
                "scope": "全国宏观口径；饮水用具及本商城趋势分别验证。",
                "source": "W05", "page": None,
            },
        ],
    }


def main():
    prepare()
    review = read_json("review.json")
    data = {**review, **business_content(), "sources": build_sources(review)}
    local = read_json("local_sources.json")
    public = [source for source in data["sources"] if source["kindGroup"] == "public"]
    data["counts"] = {
        "files": len(local), "pages": sum(source["pages"] for source in local),
        "topics": len(local) - len(review["topicDuplicates"]),
        "relevant": len(local) - len(review["topicDuplicates"]) - len(review["excluded"]),
        "excluded": len(review["excluded"]),
        "downloaded": sum(bool(source.get("file")) for source in public),
        "publicPdf": sum(bool(source.get("file")) and source["kind"] == "pdf" for source in public),
        "publicHtml": sum(bool(source.get("file")) and source["kind"] == "html" for source in public),
    }
    apply_business(data)
    data["outputRelative"] = OUTPUT.relative_to(ROOT).as_posix()
    for source in data["sources"]:
        if source.get("file"):
            source["file"] = Path(os.path.relpath(ROOT / source["file"], OUTPUT)).as_posix()
        source["images"] = {
            page: Path(os.path.relpath(ROOT / file, OUTPUT)).as_posix()
            for page, file in source.get("images", {}).items()
        }
    (OUTPUT / "饮水用具全年经营与品类规划.md").write_text(data["reviewMarkdown"], encoding="utf-8", newline="\n")
    (EVIDENCE / "dashboard_data.json").write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8", newline="\n")
    html = (ROOT / "dashboard" / "template.html").read_text(encoding="utf-8")
    replacements = {
        "/*__CSS__*/": (ROOT / "dashboard" / "style.css").read_text(encoding="utf-8"),
        "/*__DATA__*/": json.dumps(data, ensure_ascii=False, separators=(",", ":")).replace("<", "\\u003c"),
        "/*__ICONS__*/": (ROOT / "dashboard" / "vendor" / "lucide.min.js").read_text(encoding="utf-8"),
        "/*__APP__*/": (ROOT / "dashboard" / "app.js").read_text(encoding="utf-8"),
        "__VERSION__": VERSION,
    }
    for marker, value in replacements.items():
        assert html.count(marker) >= 1, marker
        html = html.replace(marker, value)
    (OUTPUT / "饮水用具行业情报看板.html").write_text(html, encoding="utf-8", newline="\n")
    print(json.dumps({"output": str(OUTPUT), "version": VERSION, **data["counts"]}, ensure_ascii=False))


if __name__ == "__main__":
    main()
