#!/bin/bash
# content-planner: субботняя планёрка по инстаграму и тредсу → телеграм
#
# Один прогон в неделю: сб 10:00 Екб — план СЛЕДУЮЩЕЙ недели по инстаграму и
# тредсу плюс банк карточек рилсов на съёмку.
#
# Почему суббота, а не воскресенье вместе с телеграмом: Наташа снимает рилсы
# батчем, и единственное окно на это — выходные. План обязан приходить ДО окна.
# Плата за субботу известна и принята: телеграмная неделя ещё не собрана,
# поэтому инста опирается на ПРОШЕДШУЮ неделю телеграма — на посты, которые уже
# вышли и уже показали пересылки. Это и лучше: рилс собирается из проверенного.
#
# Телеграмом занимается planerka.sh (вс 18:00), утренней сверкой — morning.sh.
# Запуск: bash insta.sh   (аргументов нет)
set -u

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROMPT_FILE="$SCRIPT_DIR/prompt-insta.md"

set -a; source "$SCRIPT_DIR/.env"; set +a
VAULT="${VAULT_ROOT:-/Users/nataliadudina/Desktop/ObsidianVault}"
LOG_DIR="${PLANNER_DATA_DIR:-$HOME/Library/Application Support/content-planner}"
LOG="$LOG_DIR/run.log"
CLAUDE_BIN="${CLAUDE_BIN:-$(command -v claude)}"
mkdir -p "$LOG_DIR"

NOTIFY_PREFIX="инста-планёрка"
source "$SCRIPT_DIR/lib.sh"

if [ -z "${TELEGRAM_BOT_TOKEN:-}" ] || [ -z "${TELEGRAM_OWNER_USER_ID:-}" ]; then
  log "ERROR: нет токена/chat_id в .env"; exit 1
fi

ALERTED=0
alert() { ALERTED=1; tg_notify "упала: $1"; }
trap 'rc=$?; if [ "$rc" -ne 0 ] && [ "$ALERTED" = 0 ]; then alert "неожиданный сбой (rc=$rc), смотри run.log"; fi' EXIT

vault_pull

# Прирост TGStat собирает воскресный прогон — здесь он не нужен, отсюда --no-growth.
TODAY=$(date +%Y-%m-%d)
PREFLIGHT=$(python3 "$SCRIPT_DIR/preflight.py" "$VAULT" "$TODAY" --no-growth 2>>"$LOG")
if [ -n "$PREFLIGHT" ]; then
  log "preflight: $(echo "$PREFLIGHT" | tr '\n' ';')"
  tg_notify "источники не в порядке
$PREFLIGHT

План всё равно будет, но с дырами."
else
  log "preflight: источники на месте"
fi

# weekdates от субботы и от воскресенья даёт одну и ту же следующую неделю —
# проверено, поэтому арифметика общая и правок не потребовала.
read -r WEEK_START WEEK_END <<<"$(python3 "$SCRIPT_DIR/weekdates.py" "$TODAY")"
if [ -z "${WEEK_START:-}" ]; then
  log "ERROR: не посчитались даты недели"; alert "не посчитались даты недели"; exit 1
fi

WEEKLY_DIR="$VAULT/projects/channel/planner"
INSTA_FILE="$WEEKLY_DIR/{channel} {plan} инста и тредс неделя – $WEEK_START.md"
PREV_START=$(python3 -c "
import datetime, sys
print(datetime.date.fromisoformat(sys.argv[1]) - datetime.timedelta(days=7))
" "$WEEK_START" 2>>"$LOG")
PREV_INSTA_FILE="$WEEKLY_DIR/{channel} {plan} инста и тредс неделя – $PREV_START.md"
mkdir -p "$WEEKLY_DIR"

# Идеи читаем без маркеров и НЕ закрываем: закрыть идею — право воскресного
# прогона. Закрой её здесь — и телеграмная планёрка её больше не увидит,
# хотя тема общая для трёх площадок.
IDEAS=$(ticktick_ideas "")
if [ -z "$IDEAS" ]; then
  IDEAS="(идей в TickTick сейчас нет)"
fi

IDEAS_TMP=$(mktemp)
printf '%s\n' "$IDEAS" > "$IDEAS_TMP"
PROMPT=$(python3 - "$PROMPT_FILE" "$IDEAS_TMP" <<PYEOF
import sys
tpl = open(sys.argv[1]).read()
ideas = open(sys.argv[2]).read()
out = (tpl.replace('{{TODAY}}', '$TODAY')
          .replace('{{WEEK_START}}', '$WEEK_START')
          .replace('{{WEEK_END}}', '$WEEK_END')
          .replace('{{INSTA_FILE}}', '''$INSTA_FILE''')
          .replace('{{PREV_INSTA_FILE}}', '''$PREV_INSTA_FILE''')
          .replace('{{IDEAS}}', ideas))
print(out)
PYEOF
)
rm -f "$IDEAS_TMP"

log "start: инста-неделя $WEEK_START – $WEEK_END"

SUMMARY_FILE=$(mktemp)
cd "$VAULT" || { log "ERROR: волт недоступен"; alert "волт недоступен ($VAULT)"; exit 1; }
"$CLAUDE_BIN" -p "$PROMPT" \
  --model claude-opus-5 \
  --permission-mode acceptEdits \
  --output-format text \
  > "$SUMMARY_FILE" 2>>"$LOG"
RC=$?

SUMMARY=$(cat "$SUMMARY_FILE")
MARKER="---СВОДКА-2---"
SUMMARY_1=$(python3 -c "
import sys
text = open(sys.argv[1], encoding='utf-8').read()
print(text.split(sys.argv[2])[0].strip())
" "$SUMMARY_FILE" "$MARKER" 2>/dev/null)
SUMMARY_2=$(python3 -c "
import sys
text = open(sys.argv[1], encoding='utf-8').read()
parts = text.split(sys.argv[2])
print(parts[1].strip() if len(parts) > 1 else '')
" "$SUMMARY_FILE" "$MARKER" 2>/dev/null)
rm -f "$SUMMARY_FILE"

push_vault() {
  vault_push "content-planner: инста-неделя $WEEK_START" "результат" "projects/channel"
}

if [ $RC -ne 0 ] || [ -z "$SUMMARY" ]; then
  log "ERROR: claude rc=$RC, сводка пустая — ничего не шлём"
  alert "Claude rc=$RC / пустая сводка — инста-неделя $WEEK_START не собрана"
  push_vault
  exit 1
fi
if [ -z "$SUMMARY_2" ]; then
  log "WARN: маркера нет — сводка одна, шлю её и ссылку отдельно"
fi
if [ ! -f "$INSTA_FILE" ]; then
  log "WARN: инста-файл не создан — шлём только сводку"
fi

# --- сверка формата: разбирает ли дни тот же парсер, что и утро.
# Обрезанная генерация — главный риск этого прогона: блоков много, а дни
# стоят последними. Оборвётся хвост — утро всю неделю будет без Threads и IG,
# и узнается это постфактум. Гоняем здесь: в субботу днём есть время поправить.
if [ -f "$INSTA_FILE" ]; then
  CHECK_DIR=$(mktemp -d)
  BAD=""
  WEEK_DATES=$(python3 -c "
import datetime, sys
start = datetime.date.fromisoformat(sys.argv[1])
for i in range(7):
    print(start + datetime.timedelta(days=i))
" "$WEEK_START" 2>>"$LOG")
  for d in $WEEK_DATES; do
    if ! python3 "$SCRIPT_DIR/dayblock.py" "$INSTA_FILE" "$d" "$CHECK_DIR" >/dev/null 2>>"$LOG"; then
      BAD="$BAD $d"
    fi
  done
  rm -rf "$CHECK_DIR"
  if [ -z "$WEEK_DATES" ]; then
    log "WARN: не посчитались даты недели для сверки формата — проверку пропустил"
  elif [ -n "$BAD" ]; then
    log "ERROR: dayblock не разбирает дни:$BAD"
    tg_notify "инста-неделя $WEEK_START записана в формате, который не разбирает утренняя вырезка. Не разбираются дни:$BAD — по ним утром не будет Threads и IG. Поправь заголовки («## Пн — YYYY-MM-DD — Рубрика») и поля («**IG:** …») руками сегодня"
  else
    log "dayblock: все семь дней инста-недели $WEEK_START разбираются"
  fi
fi

LINK=""
if [ -f "$INSTA_FILE" ]; then
  URL=$(python3 "$SCRIPT_DIR/telegraph.py" "$INSTA_FILE" 2>>"$LOG")
  if [ -n "$URL" ]; then
    log "telegraph: $URL"
    LINK=$'\n'"📸 Инста и тредс: $URL"
  else
    log "WARN: telegraph не удался — шлю файлом"
    tg_send_document "$INSTA_FILE" "Инста и тредс $WEEK_START – $WEEK_END"
  fi
fi

TG_LIMIT=4096
send_summary() {   # $1 — текст сводки, $2 — хвост со ссылкой
  local body="$1" tail="$2" msg
  msg="$body$tail"
  if [ "${#msg}" -gt "$TG_LIMIT" ]; then
    body="${body:0:$(( TG_LIMIT - ${#tail} - 1 ))}…"
    msg="$body$tail"
    log "WARN: сводка обрезана до лимита телеграма"
  fi
  tg_send "$msg"
}

# Состояние отправки: первое ушло, второе упало — повторный прогон дошлёт
# только второе. Имя файла своё, чтобы не столкнуться с воскресным прогоном.
SENT_FILE="$LOG_DIR/.sent-insta-$WEEK_START"
touch "$SENT_FILE"

SEND_RC=200
if grep -q '^msg1$' "$SENT_FILE" 2>/dev/null; then
  log "сводка 1 уже отправлена раньше — пропускаю"
else
  SEND_RC=$(send_summary "$SUMMARY_1" "")
  log "sendMessage 1: HTTP $SEND_RC"
  case "$SEND_RC" in 2*) echo "msg1" >> "$SENT_FILE" ;; esac
fi

DELIVERED=0
SEND_RC_2=0
case "$SEND_RC" in
  2*)
    if [ -n "$SUMMARY_2" ]; then
      SEND_RC_2=$(send_summary "$SUMMARY_2" "$LINK")
      log "sendMessage 2: HTTP $SEND_RC_2"
      case "$SEND_RC_2" in 2*) echo "msg2" >> "$SENT_FILE"; DELIVERED=1 ;; esac
    else
      log "WARN: вторая сводка пустая (нет маркера) — шлю только ссылку"
      SEND_RC_2=200
      [ -n "$LINK" ] && SEND_RC_2=$(send_summary "$LINK" "")
      case "$SEND_RC_2" in 2*) echo "msg2" >> "$SENT_FILE"; DELIVERED=1 ;; esac
    fi
    ;;
esac

if [ "$DELIVERED" != "1" ]; then
  log "WARN: сводки дошли не полностью (1: HTTP $SEND_RC, 2: HTTP $SEND_RC_2)"
  alert "инста-сводка не отправилась (1: $SEND_RC, 2: $SEND_RC_2)"
else
  rm -f "$SENT_FILE"
fi

push_vault
log "done"
