import argparse
import os
import re
import sys
from pathlib import Path

import instaloader
from instaloader import Post


SHORTCODE_RE = re.compile(r"^[A-Za-z0-9_-]+$")
URL_RE = re.compile(
    r"^https?://(?:www\.)?instagram\.com/(?:p|reel|tv)/(?P<code>[A-Za-z0-9_-]+)(?:/|\?|$)",
    re.IGNORECASE,
)


def extract_shortcode(value: str) -> str:
    value = value.strip()
    m = URL_RE.match(value)
    if m:
        return m.group("code")

    if SHORTCODE_RE.match(value):
        return value

    raise ValueError(
        "Input must be an Instagram post/reel URL or a valid shortcode."
    )


def build_loader(output_dir: Path) -> instaloader.Instaloader:
    return instaloader.Instaloader(
        dirname_pattern=str(output_dir / "{target}"),
        filename_pattern="{shortcode}",
        download_video_thumbnails=False,
        save_metadata=True,
        compress_json=False,
    )


def login_if_provided(loader: instaloader.Instaloader, username: str | None, password: str | None) -> None:
    if username and password:
        loader.login(username, password)


def parse_args(argv: list[str]) -> argparse.Namespace:
    p = argparse.ArgumentParser(description="Download Instagram post/reel by URL or shortcode")
    p.add_argument("input", help="Instagram post/reel URL or shortcode")
    p.add_argument(
        "-o",
        "--output",
        default="downloads",
        help="Output directory (default: downloads)",
    )
    p.add_argument("--username", default=os.getenv("INSTALOAD_USERNAME"), help="Instagram username")
    p.add_argument("--password", default=os.getenv("INSTALOAD_PASSWORD"), help="Instagram password")
    return p.parse_args(argv)


def main(argv: list[str] | None = None) -> int:
    args = parse_args(argv if argv is not None else sys.argv[1:])

    try:
        shortcode = extract_shortcode(args.input)
    except ValueError as e:
        print(f"Error: {e}", file=sys.stderr)
        return 2

    out = Path(args.output).resolve()
    out.mkdir(parents=True, exist_ok=True)

    loader = build_loader(out)

    try:
        login_if_provided(loader, args.username, args.password)
        post = Post.from_shortcode(loader.context, shortcode)
        loader.download_post(post, target=post.owner_username)
    except Exception as e:
        print(f"Download failed: {e}", file=sys.stderr)
        return 1

    print(f"Downloaded shortcode {shortcode} into {out}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())