"""Graph sync project scaffolding via Copier."""

from __future__ import annotations

import subprocess
from dataclasses import dataclass
from pathlib import Path
import sys

from worai.errors import UsageError

DEFAULT_TEMPLATE = "gh:wordlift/graph-sync-template"


@dataclass
class GraphSyncCreateOptions:
    destination: Path
    template: str = DEFAULT_TEMPLATE
    defaults: bool = False
    data_file: Path | None = None
    vcs_ref: str | None = None
    non_interactive: bool = False
    force: bool = False


def _ensure_destination(options: GraphSyncCreateOptions) -> Path:
    destination = options.destination.expanduser()
    try:
        if destination.exists():
            if not destination.is_dir():
                raise UsageError(
                    f"Destination exists and is not a directory: {destination}. "
                    "Use a different path."
                )
            if any(destination.iterdir()) and not options.force:
                raise UsageError(
                    f"Destination is not empty: {destination}. "
                    "Use --force to allow writing into it."
                )
        else:
            destination.mkdir(parents=True, exist_ok=True)
    except PermissionError as exc:
        raise UsageError(
            f"Permission denied while preparing destination: {destination}. "
            "Choose a writable path or adjust directory permissions."
        ) from exc
    except OSError as exc:
        raise UsageError(
            f"Unable to prepare destination: {destination}. "
            f"Details: {exc}"
        ) from exc
    return destination


def _build_copier_cmd(options: GraphSyncCreateOptions, destination: Path) -> list[str]:
    cmd = [sys.executable, "-m", "copier", "copy", "--UNSAFE"]
    if options.defaults or options.non_interactive:
        cmd.append("--defaults")
    if options.data_file is not None:
        cmd.extend(["--data-file", str(options.data_file.expanduser())])
    if options.vcs_ref:
        cmd.extend(["--vcs-ref", options.vcs_ref])
    if options.force:
        cmd.append("--force")
    cmd.extend([options.template, str(destination)])
    return cmd


def run_graph_sync_create(options: GraphSyncCreateOptions) -> None:
    destination = _ensure_destination(options)
    cmd = _build_copier_cmd(options, destination)

    try:
        subprocess.run(cmd, check=True)
    except FileNotFoundError as exc:
        raise UsageError(
            "Copier is not installed or not available on PATH. "
            "Install project dependencies with `uv sync --extra dev` "
            "or reinstall worai so runtime dependencies are included."
        ) from exc
    except PermissionError as exc:
        raise UsageError(
            "Permission denied while running Copier. "
            "Check destination/template access permissions and try again."
        ) from exc
    except subprocess.CalledProcessError as exc:
        hint = (
            "Copier failed. Check the output above for details."
            " Verify the template reference, destination, and required answers."
        )
        if options.non_interactive:
            hint += " In --non-interactive mode, provide missing answers via --data-file or template defaults."
        hint += (
            " If the output includes `Secret question requires a default value`, "
            "the template questions are invalid for this Copier version "
            "(secret questions must define a default). "
            "Use `--vcs-ref`/`--template` to target a fixed template revision."
        )
        raise UsageError(f"{hint} (exit code: {exc.returncode})") from exc
