from __future__ import annotations

import argparse
import json
import logging
import os
from pathlib import Path

from src.errors import UserError
from src.config.gbp_config import load_gbp_config
from src.gbp.generator import generate_payload, write_payload
from src.gbp.publish import publish_deal_post
from src.logging_setup import log_event

logger = logging.getLogger(__name__)

OUTPUT_ROOT_ENV_VAR = "OUTPUT_ROOT"


def register(sub: argparse._SubParsersAction) -> None:
    gbp = sub.add_parser("gbp", help="Google Business Profile tooling (generate + publish).")
    gbp_sub = gbp.add_subparsers(dest="gbp_cmd", required=True)

    gen = gbp_sub.add_parser("generate", help="Generate a GBP post payload for a deal (dry-run).")
    gen.add_argument("--deal-id", required=True, type=int, help="Pipedrive deal id.")
    gen.add_argument("--out", help=f"Output root folder path (or env {OUTPUT_ROOT_ENV_VAR}).")
    gen.add_argument("--run-id", help="Audit run id (default: latest).")
    gen.add_argument("--max-photos", type=int, default=3, help="Max photos to select (default: 3).")
    gen.add_argument(
        "--dry-run", action="store_true", help="Do not write payload file; only print JSON."
    )
    gen.set_defaults(_handler=_run_generate)

    pub = gbp_sub.add_parser("publish", help="Publish a GBP post (safe by default).")
    pub.add_argument("--deal-id", required=True, type=int, help="Pipedrive deal id.")
    pub.add_argument("--out", help=f"Output root folder path (or env {OUTPUT_ROOT_ENV_VAR}).")
    pub.add_argument("--confirm", action="store_true", help="Required for real publishing.")
    pub.add_argument(
        "--dry-run",
        choices=["true", "false"],
        help="Override dry-run (default from env GBP_PUBLISH_DRY_RUN).",
    )
    pub.set_defaults(_handler=_run_publish)


def _run_generate(args: argparse.Namespace) -> int:
    log_event(logger, "command.start", command="gbp.generate")
    out_dir = _load_out_dir(args.out)
    payload = generate_payload(
        out_dir=out_dir,
        deal_id=int(args.deal_id),
        run_id=(str(args.run_id).strip() if args.run_id else None),
        max_photos=int(args.max_photos),
    )
    write_payload(
        out_dir=out_dir, deal_id=int(args.deal_id), payload=payload, dry_run=bool(args.dry_run)
    )
    print(json.dumps(payload, indent=2, sort_keys=True, ensure_ascii=True))
    log_event(logger, "command.complete", command="gbp.generate")
    return 0


def _run_publish(args: argparse.Namespace) -> int:
    log_event(logger, "command.start", command="gbp.publish")
    out_dir = _load_out_dir(args.out)
    cfg = load_gbp_config(require_auth=False)
    dry_run = (
        cfg.publish_dry_run_default
        if args.dry_run is None
        else (str(args.dry_run).lower() == "true")
    )
    result = publish_deal_post(
        out_dir=out_dir,
        deal_id=int(args.deal_id),
        dry_run=bool(dry_run),
        confirm=bool(args.confirm),
    )
    print(result.to_json())
    log_event(logger, "command.complete", command="gbp.publish")
    return 0


def _load_out_dir(raw: str | None) -> Path:
    value = (raw or "").strip() or os.environ.get(OUTPUT_ROOT_ENV_VAR, "").strip()
    if not value:
        raise UserError(f"Missing output root. Pass --out or set {OUTPUT_ROOT_ENV_VAR}.")
    return Path(value)
