"""Content preview approval package combining MP4 preview and social draft review."""

from __future__ import annotations

from dataclasses import dataclass
from pathlib import Path

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

_FORBIDDEN_ACTION_WORDS = ("publish", "post")
_TELEGRAM_MESSAGE_LIMIT = 4096


@dataclass(frozen=True)
class ContentPreviewApprovalPackage:
    candidate_id: str
    preview_video_path: str
    social_review_text: str
    approval_commands: tuple[str, ...]
    approval_language: str = "de"
    final_video_language: str = "en"
    requires_human_approval: bool = True
    side_effects: tuple[str, ...] = ()
    external_calls: tuple[str, ...] = ()


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


def _platform_approval_command(platform: str) -> str:
    if platform == "youtube":
        return "Freigabe YouTube"
    if platform == "tiktok":
        return "Freigabe TikTok"
    if platform == "instagram":
        return "Freigabe Instagram"
    return f"Freigabe {platform}"


def _approval_commands(draft: SocialMediaDraft) -> tuple[str, ...]:
    return (
        *(tuple(_platform_approval_command(platform) for platform in draft.platforms)),
        "Freigabe alle",
        "Ablehnen",
        "Ändern: <requested change>",
    )


def build_content_preview_approval_package(
    *,
    draft: SocialMediaDraft,
    preview_video_path: str | Path,
    social_review_text: str,
    approval_language: str = "de",
    final_video_language: str = "en",
) -> ContentPreviewApprovalPackage:
    """Build a side-effect-free approval package from MP4 preview plus social review text."""

    draft_validation = validate_social_media_draft(draft)
    if not draft_validation.is_valid:
        raise ValueError("; ".join(draft_validation.errors))
    if _is_blank(social_review_text):
        raise ValueError("social_review_text is required")

    video_path = Path(preview_video_path)
    if not video_path.exists():
        raise ValueError("preview video path must exist")
    if video_path.suffix != ".mp4":
        raise ValueError("preview video path must be .mp4")

    package = ContentPreviewApprovalPackage(
        candidate_id=draft.candidate_id,
        preview_video_path=str(video_path),
        social_review_text=social_review_text,
        approval_commands=_approval_commands(draft),
        approval_language=approval_language,
        final_video_language=final_video_language,
        requires_human_approval=True,
        side_effects=(),
        external_calls=(),
    )
    validation = validate_content_preview_approval_package(package)
    if not validation.is_valid:
        raise ValueError("; ".join(validation.errors))
    return package


def validate_content_preview_approval_package(package: ContentPreviewApprovalPackage) -> ValidationResult:
    errors: list[str] = []
    for field_name, value in {
        "candidate_id": package.candidate_id,
        "preview_video_path": package.preview_video_path,
        "social_review_text": package.social_review_text,
        "approval_language": package.approval_language,
        "final_video_language": package.final_video_language,
    }.items():
        if _is_blank(value):
            errors.append(f"{field_name} is required")

    if package.preview_video_path and not package.preview_video_path.endswith(".mp4"):
        errors.append("preview_video_path must end with .mp4")
    if package.preview_video_path and not Path(package.preview_video_path).exists():
        errors.append("preview video path must exist")
    if not package.approval_commands:
        errors.append("at least one approval command is required")
    elif any(_is_blank(command) for command in package.approval_commands):
        errors.append("approval commands must not be blank")
    if "Freigabe alle" not in package.approval_commands:
        errors.append("Freigabe alle command is required")
    if not package.requires_human_approval:
        errors.append("human approval is required")
    if package.side_effects:
        errors.append("content preview packages must not have side effects")
    if package.external_calls:
        errors.append("content preview packages must not call external tools")
    if any(word in package.social_review_text.casefold() for word in _FORBIDDEN_ACTION_WORDS):
        errors.append("social_review_text must not contain publish/post action language")

    return ValidationResult(is_valid=not errors, errors=tuple(errors))


def render_content_preview_approval_text(package: ContentPreviewApprovalPackage) -> str:
    """Render the combined preview package as a Telegram-safe text block."""

    validation = validate_content_preview_approval_package(package)
    if not validation.is_valid:
        raise ValueError("; ".join(validation.errors))

    command_lines = "\n".join(f"- {command}" for command in package.approval_commands)
    text = "\n".join(
        (
            "## Content Preview Review",
            "",
            f"Candidate: {package.candidate_id}",
            f"Video preview: {package.preview_video_path}",
            f"Approval preview language: {package.approval_language}",
            f"Final video language: {package.final_video_language}",
            "Requires human approval: yes",
            "Side effects: none",
            "External calls: none",
            "",
            "Approval commands:",
            command_lines,
            "",
            package.social_review_text,
        )
    )
    if len(text) > _TELEGRAM_MESSAGE_LIMIT:
        raise ValueError("content preview approval text exceeds Telegram message limit")
    return text
