"""Manual platform copy packs for phase-1 human uploads."""

from __future__ import annotations

from dataclasses import dataclass

from autoshorts.ideas.candidate import ValidationResult
from autoshorts.social.draft import SocialMediaDraft, validate_social_media_draft


@dataclass(frozen=True)
class ManualPlatformPost:
    platform: str
    title: str
    description: str
    hashtags: tuple[str, ...]
    tags: tuple[str, ...]
    instructions: str


@dataclass(frozen=True)
class ManualPostingPack:
    candidate_id: str
    phase: str
    video_path: str
    platform_posts: tuple[ManualPlatformPost, ...]
    requires_human_manual_upload: bool = True
    side_effects: tuple[str, ...] = ()
    external_calls: tuple[str, ...] = ()


def _is_blank(value: str) -> bool:
    return not (value or "").strip()


def _normalize_hashtag_to_tag(hashtag: str) -> str:
    return hashtag.lstrip("#").strip()


def _hashtag_block(hashtags: tuple[str, ...]) -> str:
    return " ".join(hashtags)


def _youtube_description(draft: SocialMediaDraft) -> str:
    return "\n\n".join(
        part
        for part in (
            draft.caption.strip(),
            draft.cta.strip(),
            _hashtag_block(draft.hashtags),
        )
        if part
    )


def _tiktok_caption(draft: SocialMediaDraft) -> str:
    caption = f"{draft.caption.strip()} {_hashtag_block(draft.hashtags)}".strip()
    return caption[:2200]


def _post_for_platform(draft: SocialMediaDraft, platform: str) -> ManualPlatformPost:
    title = draft.title_variants[0]
    if platform == "youtube":
        return ManualPlatformPost(
            platform="youtube",
            title=title,
            description=_youtube_description(draft),
            hashtags=draft.hashtags,
            tags=tuple(_normalize_hashtag_to_tag(hashtag) for hashtag in draft.hashtags),
            instructions="Manual upload: copy this description into YouTube Shorts.",
        )
    if platform == "tiktok":
        return ManualPlatformPost(
            platform="tiktok",
            title=title,
            description=_tiktok_caption(draft),
            hashtags=draft.hashtags,
            tags=(),
            instructions="Manual upload: copy this caption into TikTok.",
        )
    if platform == "instagram":
        return ManualPlatformPost(
            platform="instagram",
            title=title,
            description=_tiktok_caption(draft),
            hashtags=draft.hashtags,
            tags=(),
            instructions="Manual upload: copy this caption into Instagram Reels.",
        )
    raise ValueError(f"unsupported platform: {platform}")


def build_manual_posting_pack(draft: SocialMediaDraft, *, video_path: str) -> ManualPostingPack:
    draft_validation = validate_social_media_draft(draft)
    if not draft_validation.is_valid:
        raise ValueError("; ".join(draft_validation.errors))
    pack = ManualPostingPack(
        candidate_id=draft.candidate_id,
        phase="manual_posting",
        video_path=video_path,
        platform_posts=tuple(_post_for_platform(draft, platform) for platform in draft.platforms),
        requires_human_manual_upload=True,
        side_effects=(),
        external_calls=(),
    )
    validation = validate_manual_posting_pack(pack)
    if not validation.is_valid:
        raise ValueError("; ".join(validation.errors))
    return pack


def validate_manual_posting_pack(pack: ManualPostingPack) -> ValidationResult:
    errors: list[str] = []
    if _is_blank(pack.candidate_id):
        errors.append("candidate_id is required")
    if pack.phase != "manual_posting":
        errors.append("phase must be manual_posting")
    if _is_blank(pack.video_path):
        errors.append("video_path is required")
    if not pack.platform_posts:
        errors.append("at least one platform post is required")
    for post in pack.platform_posts:
        if _is_blank(post.platform):
            errors.append("platform is required")
        if _is_blank(post.title):
            errors.append(f"{post.platform} title is required")
        if _is_blank(post.description):
            errors.append(f"{post.platform} description is required")
        if not post.hashtags:
            errors.append(f"{post.platform} hashtags are required")
        if _is_blank(post.instructions):
            errors.append(f"{post.platform} instructions are required")
    if not pack.requires_human_manual_upload:
        errors.append("human manual upload is required in phase 1")
    if pack.side_effects:
        errors.append("manual posting packs must not have side effects")
    if pack.external_calls:
        errors.append("manual posting packs must not call external services")
    return ValidationResult(is_valid=not errors, errors=tuple(errors))


def render_manual_posting_instructions(pack: ManualPostingPack) -> str:
    validation = validate_manual_posting_pack(pack)
    if not validation.is_valid:
        raise ValueError("; ".join(validation.errors))

    lines = [
        "## Manual Posting Pack",
        f"Candidate: {pack.candidate_id}",
        f"Video file: {pack.video_path}",
        "No platform upload was performed.",
        "",
    ]
    labels = {
        "youtube": "YouTube Shorts",
        "tiktok": "TikTok",
        "instagram": "Instagram Reels",
    }
    for post in pack.platform_posts:
        lines.extend(
            [
                f"## {labels.get(post.platform, post.platform)}",
                post.instructions,
                f"Title: {post.title}",
                "Description:",
                post.description,
                f"Hashtags: {' '.join(post.hashtags)}",
                f"Tags: {', '.join(post.tags) if post.tags else 'n/a'}",
                "",
            ]
        )
    return "\n".join(lines).strip()
