"""Build the shared-hosting upload zip for BD Market.

Creates woobd-shared-hosting.zip with a single top-level `woobd/` folder so it
can be extracted straight into /home/foryouc1 on the cPanel host.
"""

import os
import sys
import zipfile

SRC = r"G:\VS Workspace\Kimi Project\WooBD"
OUT = os.path.join(SRC, "woobd-shared-hosting.zip")
PREFIX = "woobd"

# Directory names skipped anywhere in the tree.
SKIP_DIRS = {
    "node_modules",
    ".git",
    ".workbuddy-ai",
    ".upload-staging",
    ".vercel",
    ".vscode",
    ".idea",
}

# Paths (relative to SRC, forward slashes) skipped exactly.
SKIP_PATHS = {
    ".next/cache",
    ".next/export",
    ".next/trace",
    ".next/types",
    ".dev-router.php",
    ".s1.html",
    ".s2.html",
    ".s3.html",
    ".step1.html",
    "backup.json",
    "tsconfig.tsbuildinfo",
    "next-env.d.ts",
    "prisma/dev.db",
    "prisma/prod.db",
    "prisma/dev.db-journal",
}

SKIP_SUFFIXES = (".zip", ".db", ".db-journal", ".db-wal", ".db-shm", ".log", ".tsbuildinfo")

# Inside public/uploads, ship only the placeholder so we do not upload local media.
UPLOADS_KEEP = {".gitkeep"}


def should_skip(rel: str, name: str) -> bool:
    if rel in SKIP_PATHS:
        return True
    if name.endswith(SKIP_SUFFIXES):
        return True
    if rel.startswith("public/uploads/") and name not in UPLOADS_KEEP:
        return True
    return False


def main() -> int:
    if os.path.exists(OUT):
        os.remove(OUT)

    files = []
    for root, dirs, names in os.walk(SRC):
        dirs[:] = [d for d in dirs if d not in SKIP_DIRS]

        rel_root = os.path.relpath(root, SRC).replace("\\", "/")
        if rel_root == ".":
            rel_root = ""

        # Prune whole subtrees we never want.
        pruned = []
        for d in dirs:
            rel_dir = f"{rel_root}/{d}" if rel_root else d
            if rel_dir in SKIP_PATHS:
                continue
            pruned.append(d)
        dirs[:] = pruned

        for n in names:
            rel = f"{rel_root}/{n}" if rel_root else n
            if should_skip(rel, n):
                continue
            files.append((os.path.join(root, n), rel))

    files.sort(key=lambda t: t[1])

    with zipfile.ZipFile(OUT, "w", zipfile.ZIP_DEFLATED, compresslevel=9) as zf:
        for abs_path, rel in files:
            zf.write(abs_path, f"{PREFIX}/{rel}")

    size = os.path.getsize(OUT)
    print(f"Created: {OUT}")
    print(f"Files:   {len(files)}")
    print(f"Size:    {size / 1024 / 1024:.1f} MB")

    # Sanity checks
    required = {
        "woobd/package.json",
        "woobd/package-lock.json",
        "woobd/app.js",
        "woobd/.env",
        "woobd/next.config.js",
        "woobd/middleware.ts",
        "woobd/DEPLOY-SHARED-HOSTING.md",
        "woobd/.next/BUILD_ID",
        "woobd/public/uploads/.gitkeep",
        "woobd/prisma/schema.prisma",
        "woobd/prisma/schema.sql",
        "woobd/prisma/schema-with-demo.sql",
    }
    with zipfile.ZipFile(OUT) as zf:
        names = set(zf.namelist())

    missing = sorted(required - names)
    if missing:
        print("\n!! MISSING REQUIRED ENTRIES:")
        for m in missing:
            print("   -", m)
        return 1

    bad = [n for n in names if n.startswith("woobd/node_modules/") or n.startswith("woobd/.next/cache/")]
    if bad:
        print(f"\n!! {len(bad)} unwanted entries (node_modules / .next/cache)")
        return 1

    next_files = sum(1 for n in names if n.startswith("woobd/.next/"))
    print(f"Checks:  all required entries present, {next_files} files under .next/, no node_modules")
    return 0


if __name__ == "__main__":
    sys.exit(main())
