"""The brand commands (Stream K9): `brands spellings` and `brands split`.

Sources of truth: this module, `services/brands.py`, `decisions/appliers.py`
(the `(brand, split)` applier), `docs/RUNBOOK.md`. The undo is the ledger's own
(`decisions undo-batch <uid>`), so there is no `brands unsplit`.
"""

from __future__ import annotations

import argparse

from sqlalchemy import select

from app.db import SessionLocal
from app.models import Account, Brand
from app.services import brands as brands_service
from app.services.decisions.writer import Refused


def _brand(db, slug: str) -> Brand | None:
    return db.scalar(select(Brand).where(Brand.slug == slug))


def cmd_spellings(args: argparse.Namespace) -> int:
    with SessionLocal() as db:
        row = _brand(db, args.brand)
        if row is None:
            print(f"no brand {args.brand}")
            return 2
        counts = brands_service.spellings_on(db, row)
        print(f"{row.slug} ({row.name}): {len(counts)} listed spelling(s) on {sum(counts.values())} live product variant(s)")
        for spelling, n in sorted(counts.items(), key=lambda kv: (-kv[1], kv[0])):
            print(f"  {n:5d}  {spelling!r}")
    return 0


def cmd_split(args: argparse.Namespace) -> int:
    with SessionLocal() as db:
        row = _brand(db, args.brand)
        if row is None:
            print(f"no brand {args.brand}")
            return 2
        account = db.scalar(select(Account).where(Account.username == args.by))
        if account is None:
            print(f"no account {args.by}")
            return 2
        try:
            report = brands_service.split_brand(db, row, args.spelling, new_name=args.name, decided_by=account)
        except Refused as exc:
            print(f"split: {exc.code}: {exc.summary}")
            return 2
    print(f"split: {report['product_variants_moved']} product variant(s) moved from {args.brand} to "
          f"{report['brand_slug']} ({'minted' if report['minted'] else 'adopted'}), "
          f"{report['lines_created']} product line(s) created, {report['lines_pruned']} pruned, "
          f"{report['line_decisions_carried']} line decision(s) carried; "
          f"{report['groups_merged']} group(s) folded at the tail")
    print(f"  decision {report['decision_uid']}; undo with: python -m app.cli decisions undo-batch <batch uid> --reason \"<why>\" --by {args.by}")
    return 0


def register(sub: argparse._SubParsersAction) -> None:
    brands = sub.add_parser("brands", help="the brand rows: their listed spellings, and splitting one the fold joined wrongly")
    bsub = brands.add_subparsers(dest="brands_command", required=True)

    sp = bsub.add_parser("spellings", help="every listed spelling a brand row holds, with how many product variants carry it")
    sp.add_argument("--brand", required=True, help="the brand slug")
    sp.set_defaults(func=cmd_spellings)

    split = bsub.add_parser("split", help="move listed spellings off a brand row onto one of their own, as one recorded decision")
    split.add_argument("--brand", required=True, help="the brand slug to split FROM")
    split.add_argument("--spelling", action="append", required=True, help="a listed spelling to move; repeatable")
    split.add_argument("--name", required=True, help="the name of the brand the spellings move to")
    split.add_argument("--by", required=True, help="the account username the decision is recorded against")
    split.set_defaults(func=cmd_split)
