import json
import zipfile
from datetime import datetime
from pathlib import Path


def create_snapshot_dir(root: Path, output_path: str) -> tuple[Path, str]:
    timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
    root_name = root.name or "output"
    stem_timestamp = f"{root_name}_{timestamp}"
    snapshot_dir = root / output_path / stem_timestamp
    snapshot_dir.mkdir(parents=True, exist_ok=True)
    return snapshot_dir, stem_timestamp


def create_snapshot_dir_for_file(file_path: Path, output_path: str) -> tuple[Path, str]:
    timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
    stem_timestamp = f"{file_path.stem}_{timestamp}"
    snapshot_dir = file_path.parent / output_path / stem_timestamp
    snapshot_dir.mkdir(parents=True, exist_ok=True)
    return snapshot_dir, stem_timestamp


def get_output_file_path(
    snapshot_dir: Path,
    rel_path: Path,
    out_filename: str,
    *,
    flat: bool = False,
) -> Path:
    if flat:
        parent = rel_path.parent
        if parent == Path(".") or str(parent) == ".":
            flat_name = out_filename
        else:
            prefix = str(parent).replace("\\", "/").replace("/", "_")
            flat_name = f"{prefix}_{out_filename}"
        out_path = snapshot_dir / flat_name
    else:
        out_path = snapshot_dir / rel_path.parent / out_filename
        out_path.parent.mkdir(parents=True, exist_ok=True)
    return out_path


def write_report(snapshot_dir: Path, report: dict) -> Path:
    report_path = snapshot_dir / "report.json"
    report_path.write_text(json.dumps(report, indent=2), encoding="utf-8")
    return report_path


def create_zip_archive(snapshot_dir: Path, zip_path: Path) -> Path:
    snapshot_name = snapshot_dir.name
    with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zf:
        for file_path in snapshot_dir.rglob("*"):
            if file_path.is_file():
                arcname = f"{snapshot_name}/{file_path.relative_to(snapshot_dir)}"
                zf.write(file_path, arcname=arcname.replace("\\", "/"))
    return zip_path
