"""Seed brochure-derived collection JSON into normalization registries and collection commerce profile.

Examples:
    python -m app.jobs.seed_collection_brochure --file seeds/anna_caramel_harvest.json --apply
    python -m app.jobs.seed_collection_brochure --file seeds/anrwo.json --channel shopify --connection-id 7 --apply
"""

from __future__ import annotations

import argparse
import json
from pathlib import Path
from typing import Any, Dict, List, Optional


def run_seed_collection_brochure(
    *,
    file_path: str,
    channel_code: Optional[str] = None,
    connection_id: Optional[int] = None,
    sample_category_path_slug: str = "product-category/sample_doors",
    appointment_url: Optional[str] = None,
    apply: bool = False,
) -> Dict[str, Any]:
    from db.collection_brochure_seed import load_collection_brochure_seed, seed_collection_brochure
    from db.session import get_session

    payload = load_collection_brochure_seed(file_path)
    with get_session() as session:
        result = seed_collection_brochure(
            session,
            payload,
            channel_code=channel_code,
            connection_id=connection_id,
            sample_category_path_slug=sample_category_path_slug,
            appointment_url=appointment_url,
        )
        if not apply:
            session.rollback()
        return {
            "applied": bool(apply),
            "file_path": file_path,
            "channel_code": channel_code,
            "connection_id": connection_id,
            "result": result,
        }


def run_seed_collection_brochure_batch(
    *,
    file_paths: List[str],
    skip_tokens: Optional[List[str]] = None,
    channel_code: Optional[str] = None,
    connection_id: Optional[int] = None,
    sample_category_path_slug: str = "product-category/sample_doors",
    appointment_url: Optional[str] = None,
    apply: bool = False,
) -> Dict[str, Any]:
    from db.collection_brochure_seed import load_collection_brochure_seed, seed_collection_brochure
    from db.session import get_session

    results: List[Dict[str, Any]] = []
    skip_set = {_normalize_skip_token(token) for token in (skip_tokens or []) if _normalize_skip_token(token)}
    selected_files = [path for path in file_paths if not _should_skip_path(path, skip_set)]
    skipped_files = [path for path in file_paths if _should_skip_path(path, skip_set)]
    with get_session() as session:
        for file_path in selected_files:
            payload = load_collection_brochure_seed(file_path)
            result = seed_collection_brochure(
                session,
                payload,
                channel_code=channel_code,
                connection_id=connection_id,
                sample_category_path_slug=sample_category_path_slug,
                appointment_url=appointment_url,
            )
            results.append(
                {
                    "file_path": file_path,
                    "result": result,
                }
            )
        if not apply:
            session.rollback()
        else:
            session.commit()
    return {
        "applied": bool(apply),
        "file_count": len(selected_files),
        "skipped_file_count": len(skipped_files),
        "skipped_files": skipped_files,
        "channel_code": channel_code,
        "connection_id": connection_id,
        "results": results,
    }


def _collect_input_files(*, file_path: Optional[str], folder_path: Optional[str]) -> List[str]:
    paths: List[str] = []
    if file_path:
        path = Path(file_path)
        if not path.is_file():
            raise FileNotFoundError(f"Brochure JSON file not found: {file_path}")
        paths.append(str(path))
    if folder_path:
        folder = Path(folder_path)
        if not folder.is_dir():
            raise FileNotFoundError(f"Brochure JSON folder not found: {folder_path}")
        paths.extend(str(path) for path in sorted(folder.glob("*.json")) if path.is_file())
    unique: List[str] = []
    seen = set()
    for path in paths:
        key = str(Path(path))
        if key in seen:
            continue
        seen.add(key)
        unique.append(key)
    if not unique:
        raise ValueError("No brochure JSON files found. Provide --file or a folder containing *.json files.")
    return unique


def _normalize_skip_token(value: str) -> str:
    return Path(str(value).strip()).name.lower()


def _should_skip_path(path: str, skip_set: set[str]) -> bool:
    if not skip_set:
        return False
    name = Path(path).name.lower()
    stem = Path(path).stem.lower()
    return name in skip_set or stem in skip_set


def main() -> None:
    parser = argparse.ArgumentParser(description="Seed brochure-derived collection JSON into normalization tables.")
    parser.add_argument("--file", default=None, help="Path to brochure JSON file.")
    parser.add_argument("--folder", default=None, help="Folder containing brochure JSON files.")
    parser.add_argument("--skip", action="append", default=None, help="File name or stem to skip; repeatable.")
    parser.add_argument("--channel", default=None, help="Optional scoped channel, e.g. shopify or magento.")
    parser.add_argument("--connection-id", type=int, default=None, help="Optional scoped connection id.")
    parser.add_argument(
        "--sample-category-path-slug",
        default="product-category/sample_doors",
        help="Sample-door category path slug.",
    )
    parser.add_argument("--appointment-url", default=None, help="Optional appointment URL to store on the commerce profile.")
    parser.add_argument("--apply", action="store_true", help="Commit changes. Without this flag the import is rolled back.")
    args = parser.parse_args()

    file_paths = _collect_input_files(file_path=args.file, folder_path=args.folder)
    if len(file_paths) == 1:
        result = run_seed_collection_brochure(
            file_path=file_paths[0],
            channel_code=args.channel,
            connection_id=args.connection_id,
            sample_category_path_slug=args.sample_category_path_slug,
            appointment_url=args.appointment_url,
            apply=args.apply,
        )
    else:
        result = run_seed_collection_brochure_batch(
            file_paths=file_paths,
            skip_tokens=args.skip,
            channel_code=args.channel,
            connection_id=args.connection_id,
            sample_category_path_slug=args.sample_category_path_slug,
            appointment_url=args.appointment_url,
            apply=args.apply,
        )
    print(json.dumps(result, indent=2))


if __name__ == "__main__":
    main()
