#!/usr/bin/env python3
"""Подтянуть в таблицу «Статьи» панели то, что реально написано.

Панель показывает очередь контент-плана, а состояние текстов живёт в их
frontmatter. Разойтись эти две вещи могут за день: статья написана, а в панели
у неё по-прежнему «Запланирована». Скрипт закрывает разрыв в одну сторону -
из файлов в панель, и только по трём полям: статус, ссылка, файл.

Строки, которых в таблице нет (материалы для внешних площадок, статьи вне
волны), добавляются с номерами от 22. Демо-строки (номера от 101) не трогаются:
они нарисованные, их задача показывать, как таблица выглядит с данными.

Запуск: python3 панель/данные/обновить-статьи.py
Перед запуском пересобрать реестр: python3 завод/реестр-текстов.py
"""

import json
from pathlib import Path

КОРЕНЬ = Path(__file__).resolve().parent.parent.parent
РЕЕСТР = КОРЕНЬ / "завод" / "реестр-текстов.json"
ТАБЛИЦА = КОРЕНЬ / "панель" / "данные" / "articles.json"
ВИТРИНА = "https://smm.prfabrika.ru/"

# frontmatter пишется по-человечески, панель живёт на своей легенде статусов
СТАТУСЫ = (("отложен", "Ждёт решения"), ("опубликован", "Опубликовано"),
           ("не публиковать", "Черновик готов"), ("ждёт ответа", "Готова"),
           ("к публикации", "Готова"))

# площадка у материала берётся из его шапки, а кластер там не указывают:
# тему площадочного текста привязываем к кластеру портала вручную, по смыслу
КЛАСТЕР_ПЛОЩАДКИ = {
    "cossa-01-kak-prodayut-franshizy.md": ("А25", "исследование"),
    "дзен-01-proverka-franchaizera.md": ("А13", "прогрев"),
    "tzh-01-chto-vidno-do-pokupki.md": ("А14", "прогрев"),
    "vc-01-poryadok-oshibok.md": ("Б9", "разбор"),
    "pikabu-01-proverka-prishla.md": ("Б29", "прогрев"),
}


def образец(строки):
    """Пустая строка таблицы: берём поля существующей, чтобы колонки совпали."""
    пустая = {к: None for к in строки[0]}
    пустая.update({"рубрика": "Франшизы", "контур": "спутник · разбор", "приоритет": "P1",
                   "неделя": "-", "волна": "П1", "просмотры": None, "демо": False,
                   "ключи": [], "ключи_кластер": None, "ключи_замер": None,
                   "ключи_нота": "частотность не мерена"})
    return пустая


def главная():
    реестр = json.loads(РЕЕСТР.read_text(encoding="utf-8"))
    данные = json.loads(ТАБЛИЦА.read_text(encoding="utf-8"))
    строки = данные["строки"]
    живые = [с for с in строки if not с.get("демо")]
    изменено, добавлено = [], []

    for текст in реестр["тексты"]:
        имя = Path(текст["файл"]).name
        низ = текст["статус"].lower()
        статус = next((з for сл, з in СТАТУСЫ if сл in низ), "Черновик готов")
        ссылка = (ВИТРИНА + текст["на_витрине"][0]) if текст["на_витрине"] else None
        площадочный = текст["вид"] == "внешняя площадка"
        кластер, тип = КЛАСТЕР_ПЛОЩАДКИ.get(имя, ("", "разбор"))

        if площадочный:
            строка = next((с for с in живые if с.get("файл") == текст["файл"]), None)
        else:
            строка = next((с for с in живые if с.get("кластер") == текст["кластер"]
                           and с["площадка"].startswith("портал")), None)

        if строка is None:
            строка = образец(строки)
            строка.update({
                "№": max(с["№"] for с in строки if с["№"] < 100) + 1,
                "заголовок": текст["заголовок"],
                "кластер": кластер if площадочный else текст["кластер"],
                "площадка": текст["площадка"] or "портал frantlas.ru",
                "тип": тип if площадочный else "разбор",
                "создана": текст["написано"] or реестр["собрано"],
            })
            строки.append(строка)
            живые.append(строка)
            добавлено.append(f'{строка["№"]} {строка["заголовок"][:40]} ({строка["площадка"]})')

        было = (строка.get("статус"), строка.get("ссылка"), строка.get("файл"))
        строка["статус"] = статус
        строка["ссылка"] = ссылка
        строка["файл"] = текст["файл"]
        if было != (статус, ссылка, текст["файл"]) and строка["№"] not in [int(д.split()[0]) for д in добавлено]:
            изменено.append(f'{строка["№"]} {строка["заголовок"][:40]}: {было[0]} → {статус}')

    строки.sort(key=lambda с: с["№"])
    данные["мета"]["источник"] = ("семантика/контент-план-волна-1.md · состояние текстов из "
                                 "завод/реестр-текстов.json (собирается из frontmatter файлов)")
    данные["мета"]["состояние_завода"] = (
        f'написано текстов: {реестр["итоги"]["всего"]} '
        f'({реестр["итоги"]["для_портала"]} для портала, '
        f'{реестр["итоги"]["для_внешних_площадок"]} для внешних площадок), опубликовано: '
        f'{реестр["итоги"]["опубликовано"]}')
    for п in ("Cossa", "Т-Ж Сообщество"):
        if п not in данные["мета"]["площадки"]:
            данные["мета"]["площадки"].append(п)

    ТАБЛИЦА.write_text(json.dumps(данные, ensure_ascii=False, indent=1), encoding="utf-8")
    print("обновлено строк:", len(изменено))
    for с in изменено:
        print("  ", с)
    print("добавлено строк:", len(добавлено))
    for с in добавлено:
        print("  ", с)


if __name__ == "__main__":
    главная()
