import re
from dataclasses import dataclass
from urllib.parse import urlparse

import instaloader
from instaloader import Post, Profile

IG_HOST_RE = re.compile(r"(^|\.)instagram\.com$", re.IGNORECASE)
POST_PATH_RE = re.compile(r"^/(p|reel|tv)/([A-Za-z0-9_-]+)(?:/|$)", re.IGNORECASE)
PROFILE_PATH_RE = re.compile(r"^/([A-Za-z0-9._]+)(?:/|$)")
DIRECT_VIDEO_RE = re.compile(r"^https?://.*\.mp4(?:\?.*)?$", re.IGNORECASE)


@dataclass
class ParsedInput:
    input_type: str
    shortcode: str | None = None
    username: str | None = None
    subtype: str | None = None


def parse_instagram_input(value: str) -> ParsedInput:
    raw = value.strip()
    if DIRECT_VIDEO_RE.match(raw):
        return ParsedInput(input_type="video_url")

    parsed = urlparse(raw)
    host = (parsed.hostname or "").lower()
    if not IG_HOST_RE.search(host):
        return ParsedInput(input_type="unknown")

    path = parsed.path or "/"
    post_match = POST_PATH_RE.match(path)
    if post_match:
        subtype = post_match.group(1).lower()
        shortcode = post_match.group(2)
        return ParsedInput(input_type=subtype, shortcode=shortcode, subtype=subtype)

    profile_match = PROFILE_PATH_RE.match(path)
    if profile_match:
        username = profile_match.group(1).strip(".")
        if username and username not in {"explore", "accounts", "reels", "p"}:
            return ParsedInput(input_type="profile", username=username)

    return ParsedInput(input_type="unknown")


def build_loader() -> instaloader.Instaloader:
    return instaloader.Instaloader(
        download_pictures=False,
        download_videos=False,
        download_video_thumbnails=False,
        download_comments=False,
        save_metadata=False,
        compress_json=False,
    )


def resolve_media(loader: instaloader.Instaloader, shortcode: str) -> dict:
    post = Post.from_shortcode(loader.context, shortcode)
    node = post._node  # Uses instaloader's resolved GraphQL payload.
    video_url = node.get("video_url")
    image_url = node.get("display_url")
    media_url = video_url or image_url
    media_type = "video" if post.is_video else "image"
    if post.typename == "GraphSidecar":
        media_type = "carousel"

    return {
        "shortcode": post.shortcode,
        "owner_username": post.owner_username,
        "caption": post.caption or "",
        "is_video": post.is_video,
        "typename": post.typename,
        "media_type": media_type,
        "media_url": media_url,
        "video_url": video_url,
        "image_url": image_url,
    }


def resolve_profile(loader: instaloader.Instaloader, username: str) -> dict:
    profile = Profile.from_username(loader.context, username)
    return {
        "username": profile.username,
        "full_name": profile.full_name,
        "biography": profile.biography,
        "followers": profile.followers,
        "followees": profile.followees,
        "profile_pic_url": profile.profile_pic_url,
        "is_private": profile.is_private,
        "is_verified": profile.is_verified,
    }
