#!/home/agent/venv/bin/python3
"""Plappi Social-Marketing engine — CLI (used by humans and by Lena via WhatsApp).

Targets:
  targets [--channel press|social] [--platform X] [--wave A] [--status active]
  target <id>

Drafting:
  draft-press (--target-id N | --wave A) [--auto-send] [--model haiku]
  draft-social --target-id N [--kind post|comment] [--topic "..."] [--auto-send]

Review / approval (what Lena calls when Nemanja replies on WhatsApp):
  list [--status pending] [--channel press|social]
  show <id>
  approve <id> [--dry]      # press: SENDS mail · community: returns paste-card · own: marks to post
  reject <id> [--reason ...]
  fix <id> --hint "..."     # regenerate with feedback (supersedes old)
  mark-posted <id>          # community manual post done
  send-pending [--channel]  # WA-push all pending items

Ops:
  reply-watch [--dry]       # scan Lena's inbox for press replies → follow-up drafts
  report                    # status summary
"""
from __future__ import annotations

import argparse
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent))
from marketing_lib import (
    list_targets, get_target, set_target_status, list_items, get_item, set_status,
    log_event, log, format_for_wa, manual_post_card, wa_send, send_email, db, insert_item,
)
import press_outreach
import social_draft


def cmd_targets(a):
    rows = list_targets(a.channel, a.platform, a.wave, a.status)
    if not rows:
        print("(keine Targets)"); return
    for r in rows:
        print(f"#{r['id']:<3} {r['channel']:<6} {r['platform']:<15} {r['wave'] or '-':<6} "
              f"{r['posting_mode']:<16} {r['status']:<9} {r['name']}")


def cmd_target(a):
    t = get_target(a.id)
    if not t:
        print("nicht gefunden", file=sys.stderr); sys.exit(1)
    for k in t.keys():
        print(f"{k:14}: {t[k]}")


def cmd_draft_press(a):
    if a.target_id:
        iid = press_outreach.draft_for_target(a.target_id, auto_send=a.auto_send,
                                              model=a.model, extra_notes=a.notes or "")
        print(f"item={iid}")
    elif a.wave:
        ids = press_outreach.draft_wave(a.wave, auto_send=a.auto_send, model=a.model)
        print(f"items={ids}")
    else:
        print("--target-id ODER --wave nötig", file=sys.stderr); sys.exit(2)


def cmd_draft_social(a):
    iid = social_draft.draft_for_target(a.target_id, kind=a.kind, topic=a.topic or "",
                                        auto_send=a.auto_send, model=a.model)
    print(f"item={iid}")


def cmd_list(a):
    rows = list_items(a.status, a.channel)
    if not rows:
        print("(keine Items)"); return
    for r in rows:
        head = (r["subject"] or r["body"].splitlines()[0])[:55]
        print(f"#{r['id']:<3} {r['status']:<11} {r['channel']:<6} {r['platform']:<14} {head}")


def cmd_show(a):
    it = get_item(a.id)
    if not it:
        print("nicht gefunden", file=sys.stderr); sys.exit(1)
    print(format_for_wa(it, get_target(it["target_id"])))


def cmd_approve(a):
    it = get_item(a.id)
    if not it:
        print("nicht gefunden", file=sys.stderr); sys.exit(1)
    if it["status"] in ("sent", "posted"):
        print(f"#{a.id} ist schon {it['status']}"); return
    t = get_target(it["target_id"])
    mode = t["posting_mode"] if t else "email"
    conn = db(); conn.execute(
        "UPDATE items SET status='approved', approved_at=datetime('now'), updated_at=datetime('now') WHERE id=?",
        (a.id,)); conn.commit(); conn.close()
    log_event(a.id, "approved", mode)

    if it["channel"] == "press" and mode == "email":
        to = t["contact"] if t else ""
        if not to or "@" not in to:
            wa_send(f"⚠️ #{a.id} {t['name'] if t else ''}: keine Mail-Adresse hinterlegt — "
                    f"bitte via Formular ({t['url'] if t else ''}) manuell senden.")
            print("kein contact-mail → manueller Versand nötig"); return
        ok = send_email(to, it["subject"], it["body"], dry=a.dry)
        if ok and not a.dry:
            conn = db(); conn.execute(
                "UPDATE items SET status='sent', sent_at=datetime('now'), updated_at=datetime('now') WHERE id=?",
                (a.id,)); conn.commit(); conn.close()
            if t:
                set_target_status(t["id"], "contacted")
            log_event(a.id, "sent", to)
            wa_send(f"✅ Mail an {t['name']} raus ({to}).")
            print(f"sent → {to}")
        else:
            print("DRY (nicht gesendet)" if a.dry else "FEHLER beim Senden")
        return

    # Reddit: auto-post via logged-in VM Chrome (the WhatsApp approve→post loop)
    if it["channel"] == "social" and it["platform"] == "reddit":
        import reddit_post
        rc = reddit_post.main(a.id)
        wa_send(f"✅ Auf Reddit gepostet (#{a.id})." if rc == 0
                else f"⚠️ Reddit-Post #{a.id} unsicher — bitte kurz prüfen.")
        print("reddit post rc=", rc)
        return

    if mode == "manual_community":
        card = manual_post_card(it, t)
        wa_send(card)
        print("community → paste-card an WhatsApp")
        return

    # auto_own / paid — own-channel poster not wired yet (LinkedIn has its own pipeline)
    wa_send(f"✅ #{a.id} freigegeben für {t['name']}.\n"
            f"(Auto-Poster für {it['platform']} steht noch aus — bitte posten und dann: posted #{a.id})")
    print("auto_own freigegeben (poster pending)")


def cmd_reject(a):
    set_status(a.id, "rejected")
    log_event(a.id, "rejected", a.reason or "")
    print(f"rejected #{a.id}")


def cmd_fix(a):
    it = get_item(a.id)
    if not it:
        print("nicht gefunden", file=sys.stderr); sys.exit(1)
    t = get_target(it["target_id"])
    from marketing_lib import run_claude, insert_item
    if it["channel"] == "press":
        sysp = press_outreach.SYSTEM_PROMPT
        prompt = (f"KORREKTUR einer Pitch-Mail.\n\nBISHER:\nBETREFF: {it['subject']}\n---\n{it['body']}\n\n"
                  f"KORREKTUR-WUNSCH: {a.hint}\n\nGib das überarbeitete Ergebnis im Format 'BETREFF: ...\\n---\\n<text>'.")
        raw = run_claude(prompt, sysp, model=it["model_used"] or "haiku", label="press_fix")
        subject, body = press_outreach._split(raw, t)
        new = insert_item(target_id=it["target_id"], channel="press", type_=it["type"],
                          platform=it["platform"], subject=subject, body=body, disclosure=it["disclosure"],
                          scheduled_for=it["scheduled_for"], thread_ref=subject,
                          prompt_used=prompt, model_used=it["model_used"] or "haiku")
    else:
        sysp = social_draft.SYSTEM_PROMPT
        prompt = (f"KORREKTUR eines Social-Beitrags ({it['platform']}).\n\nBISHER:\n{it['body']}\n\n"
                  f"KORREKTUR-WUNSCH: {a.hint}\n\nGib nur den überarbeiteten Beitragstext.")
        body = run_claude(prompt, sysp, model=it["model_used"] or "haiku", label="social_fix").strip()
        new = insert_item(target_id=it["target_id"], channel="social", type_=it["type"],
                          platform=it["platform"], subject=None, body=body, disclosure=it["disclosure"],
                          scheduled_for=it["scheduled_for"], thread_ref=it["thread_ref"],
                          prompt_used=prompt, model_used=it["model_used"] or "haiku")
    conn = db()
    conn.execute("UPDATE items SET fix_iterations=? WHERE id=?", ((it["fix_iterations"] or 0) + 1, new))
    conn.execute("UPDATE items SET status='superseded' WHERE id=?", (a.id,))
    conn.commit(); conn.close()
    log_event(a.id, "fix", f"→#{new}")
    wa_send(format_for_wa(get_item(new), t))
    print(f"new item #{new} (supersedes #{a.id})")


def cmd_mark_posted(a):
    it = get_item(a.id)
    if not it:
        print("nicht gefunden", file=sys.stderr); sys.exit(1)
    conn = db(); conn.execute("UPDATE items SET status='posted', sent_at=datetime('now') WHERE id=?", (a.id,))
    conn.commit(); conn.close()
    log_event(a.id, "posted", "manual")
    if it["target_id"]:
        set_target_status(it["target_id"], "done")
    print(f"posted #{a.id}")


def cmd_send_pending(a):
    rows = list_items("pending", a.channel)
    n = 0
    for r in rows:
        wa_send(format_for_wa(r, get_target(r["target_id"]))); n += 1
    print(f"{n} pending items an WhatsApp")


def cmd_report(a):
    conn = db()
    print("TARGETS:")
    for row in conn.execute("SELECT channel,status,COUNT(*) c FROM targets GROUP BY channel,status ORDER BY channel,status"):
        print(f"  {row['channel']:<6} {row['status']:<10} {row['c']}")
    print("ITEMS:")
    for row in conn.execute("SELECT channel,status,COUNT(*) c FROM items GROUP BY channel,status ORDER BY channel,status"):
        print(f"  {row['channel']:<6} {row['status']:<11} {row['c']}")
    conn.close()


def cmd_blast(a):
    """Bulk-send the approved templated press email to whole waves (Nemanja pre-approved)."""
    import time
    waves = [w.strip() for w in a.waves.split(",") if w.strip()]
    seen, targets = set(), []
    for w in waves:
        for t in list_targets(channel="press", wave=w, status="active"):
            if t["id"] in seen:
                continue
            seen.add(t["id"]); targets.append(t)
    sent = forms = err = 0
    form_lines = []
    sample = None
    for t in targets:
        subj, body = press_outreach.build_templated_email(t)
        if sample is None:
            sample = (t["name"], subj, body)
        contact = t["contact"] or ""
        if "@" not in contact:                      # form-only outlet → manual
            forms += 1
            form_lines.append(f"• {t['name']}: {t['url'] or contact}")
            if not a.dry:
                iid = insert_item(t["id"], "press", "press_email", t["platform"], body,
                                  subject=subj, thread_ref=subj)
                set_status(iid, "needs_manual")
            continue
        if a.dry:
            sent += 1
            continue
        ok = send_email(contact, subj, body, dry=False, no_bcc=True)
        iid = insert_item(t["id"], "press", "press_email", t["platform"], body,
                          subject=subj, thread_ref=subj)
        if ok:
            conn = db()
            conn.execute("UPDATE items SET status='sent', sent_at=datetime('now') WHERE id=?", (iid,))
            conn.commit(); conn.close()
            set_target_status(t["id"], "contacted"); log_event(iid, "sent", contact); sent += 1
        else:
            set_status(iid, "rejected"); err += 1
        time.sleep(a.sleep)
    if a.dry:
        n, s, b = sample if sample else ("—", "—", "—")
        print(f"DRY blast: {len(targets)} Targets · würde {sent} mailen, {forms} Formulare (manuell)")
        print(f"\n--- BEISPIEL: {n} ---\nBetreff: {s}\n\n{b}")
    else:
        msg = f"✅ Plappi Presse-Blast raus: {sent} Mails gesendet · {forms} Formulare (manuell) · {err} Fehler."
        if form_lines:
            msg += "\n\n📝 Diese bitte via Formular einreichen:\n" + "\n".join(form_lines[:30])
        wa_send(msg)
        print(msg)


def cmd_reply_watch(a):
    import press_reply_watch
    press_reply_watch.run(dry=a.dry)


def main():
    ap = argparse.ArgumentParser()
    sub = ap.add_subparsers(dest="cmd", required=True)

    p = sub.add_parser("targets"); p.add_argument("--channel"); p.add_argument("--platform")
    p.add_argument("--wave"); p.add_argument("--status"); p.set_defaults(fn=cmd_targets)
    p = sub.add_parser("target"); p.add_argument("id", type=int); p.set_defaults(fn=cmd_target)

    p = sub.add_parser("draft-press"); p.add_argument("--target-id", type=int); p.add_argument("--wave")
    p.add_argument("--notes"); p.add_argument("--model", default="haiku")
    p.add_argument("--auto-send", action="store_true"); p.set_defaults(fn=cmd_draft_press)

    p = sub.add_parser("draft-social"); p.add_argument("--target-id", type=int, required=True)
    p.add_argument("--kind", default="post", choices=["post", "comment"]); p.add_argument("--topic")
    p.add_argument("--model", default="haiku"); p.add_argument("--auto-send", action="store_true")
    p.set_defaults(fn=cmd_draft_social)

    p = sub.add_parser("list"); p.add_argument("--status"); p.add_argument("--channel"); p.set_defaults(fn=cmd_list)
    p = sub.add_parser("show"); p.add_argument("id", type=int); p.set_defaults(fn=cmd_show)
    p = sub.add_parser("approve"); p.add_argument("id", type=int); p.add_argument("--dry", action="store_true")
    p.set_defaults(fn=cmd_approve)
    p = sub.add_parser("reject"); p.add_argument("id", type=int); p.add_argument("--reason"); p.set_defaults(fn=cmd_reject)
    p = sub.add_parser("fix"); p.add_argument("id", type=int); p.add_argument("--hint", required=True); p.set_defaults(fn=cmd_fix)
    p = sub.add_parser("mark-posted"); p.add_argument("id", type=int); p.set_defaults(fn=cmd_mark_posted)
    p = sub.add_parser("send-pending"); p.add_argument("--channel"); p.set_defaults(fn=cmd_send_pending)
    p = sub.add_parser("blast")
    p.add_argument("--waves", default="A,A3,A4")
    p.add_argument("--dry", action="store_true")
    p.add_argument("--sleep", type=float, default=3.0)
    p.set_defaults(fn=cmd_blast)

    p = sub.add_parser("reply-watch"); p.add_argument("--dry", action="store_true"); p.set_defaults(fn=cmd_reply_watch)
    p = sub.add_parser("report"); p.set_defaults(fn=cmd_report)

    a = ap.parse_args(); a.fn(a)


if __name__ == "__main__":
    main()
