"""Content remixer for importing and remixing content from URLs."""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import TYPE_CHECKING, Optional

from ..utils.logger import Logger

if TYPE_CHECKING:
    from .api_client import ApiClient


@dataclass
class ExtractedContent:
    """Content extracted from a URL."""

    title: str
    text: str
    author: Optional[str] = None
    source_url: str = ""
    metadata: dict = field(default_factory=dict)


@dataclass
class RemixResult:
    """Result of content remixing."""

    success: bool
    content: Optional[str] = None
    angle_used: Optional[str] = None
    error: Optional[str] = None


@dataclass
class AngleTemplate:
    """Angle template for remixing."""

    id: str
    name: str
    description: str
    prompt_template: str


class ContentRemixer:
    """Remixes content from URLs for Reply Cash marketing."""

    # Preset angles for Reply Cash
    # CRITICAL: These angles must preserve the ORIGINAL topic/content.
    # The angle provides a lens/perspective for presenting the content, NOT a new topic.
    PRESET_ANGLES = [
        AngleTemplate(
            id="angle_preset_crypto_simplified",
            name="Crypto Simplified",
            description="For beginners, simple analogies, no jargon",
            prompt_template="""You are a content marketer for Reply Cash (a stablecoin remittance platform).

TASK: Remix the following content to make it accessible for crypto beginners.

IMPORTANT RULES:
1. KEEP THE ORIGINAL TOPIC - do NOT change the subject matter
2. Use simple analogies and avoid unnecessary technical jargon
3. Naturally connect to Reply Cash context where relevant
4. Include a subtle Reply Cash call-to-action at the end (optional)

VOICE & TONE - WRITE LIKE A HUMAN:
- Write in a natural, conversational human voice - avoid robotic or overly polished corporate language
- Use the original author's style and tone where possible - match their energy and phrasing
- Keep direct quotes and specific examples from the original content intact
- Include personal opinions or perspectives where appropriate - don't be afraid to have a point of view
- Use contractions, casual transitions, and varied sentence lengths
- Avoid buzzwords, jargon, and marketing-speak like "leverage," "synergy," "game-changing," "innovative solution"
- Write like you're explaining this to a friend over coffee, not presenting to a boardroom
- It's okay to be slightly imperfect - human writing has personality and occasional informality

Original content to remix:
{content}

Create content that:
- Preserves the core message and topic of the original
- Uses everyday analogies when explaining concepts
- Focuses on accessibility and ease of understanding
- Mentions Reply Cash only as a natural solution/example if relevant
- Sounds authentically human, not AI-generated
- Avoids changing the topic to stablecoins or crypto education""",
        ),
        AngleTemplate(
            id="angle_preset_cross_border_hero",
            name="Cross-Border Hero",
            description="Focus on remittance savings vs Western Union",
            prompt_template="""You are a content marketer for Reply Cash (a stablecoin remittance platform).

TASK: Remix the following content to highlight cross-border payment/remittance benefits.

IMPORTANT RULES:
1. KEEP THE ORIGINAL TOPIC - do NOT change the subject matter
2. Connect the original content to remittance/cross-border payment context
3. Highlight Reply Cash benefits as they relate to the original topic
4. Do NOT rewrite the content to be about remittances - keep the original topic

VOICE & TONE - WRITE LIKE A HUMAN:
- Write in a natural, conversational human voice - avoid robotic or overly polished corporate language
- Use the original author's style and tone where possible - match their energy and phrasing
- Keep direct quotes and specific examples from the original content intact
- Include personal opinions or perspectives where appropriate - don't be afraid to have a point of view
- Use contractions, casual transitions, and varied sentence lengths
- Avoid buzzwords, jargon, and marketing-speak like "leverage," "synergy," "game-changing," "innovative solution"
- Write like you're explaining this to a friend over coffee, not presenting to a boardroom
- It's okay to be slightly imperfect - human writing has personality and occasional informality

Original content to remix:
{content}

Create content that:
- Preserves the core message and topic of the original
- Adds context about remittance savings where relevant
- Shows speed/cost advantages only if they support the original topic
- Naturally weaves in Reply Cash as a solution for related pain points
- Sounds authentically human, not AI-generated
- Keeps the focus on the ORIGINAL topic, not remittances""",
        ),
        AngleTemplate(
            id="angle_preset_stablecoin_education",
            name="Stablecoin Education",
            description="Build trust, explain USDC safety",
            prompt_template="""You are a content marketer for Reply Cash (a stablecoin remittance platform).

TASK: Remix the following content to build trust and credibility through educational framing.

IMPORTANT RULES:
1. KEEP THE ORIGINAL TOPIC - do NOT change the subject matter
2. Use an educational, trustworthy tone to present the original content
3. Only mention stablecoins/USDC if naturally relevant to the original topic
4. Do NOT turn this into a general stablecoin education piece

VOICE & TONE - WRITE LIKE A HUMAN:
- Write in a natural, conversational human voice - avoid robotic or overly polished corporate language
- Use the original author's style and tone where possible - match their energy and phrasing
- Keep direct quotes and specific examples from the original content intact
- Include personal opinions or perspectives where appropriate - don't be afraid to have a point of view
- Use contractions, casual transitions, and varied sentence lengths
- Avoid buzzwords, jargon, and marketing-speak like "leverage," "synergy," "game-changing," "innovative solution"
- Write like you're explaining this to a friend over coffee, not presenting to a boardroom
- It's okay to be slightly imperfect - human writing has personality and occasional informality

Original content to remix:
{content}

Create content that:
- Preserves the core message and topic of the original
- Uses credible, transparent language
- Addresses trust/safety only if relevant to the original topic
- Naturally references Reply Cash's reliability where appropriate
- Sounds authentically human, not AI-generated
- Maintains focus on the ORIGINAL content's subject matter""",
        ),
        AngleTemplate(
            id="angle_preset_controversial_take",
            name="Controversial Take",
            description="Bold opinions, viral potential",
            prompt_template="""You are a content marketer for Reply Cash (a stablecoin remittance platform).

TASK: Remix the following content with a bold, opinionated stance.

IMPORTANT RULES:
1. KEEP THE ORIGINAL TOPIC - do NOT change the subject matter
2. Present the original content with a provocative but professional angle
3. Challenge conventional thinking related to the original topic
4. Do NOT change the topic to be about Reply Cash or remittances

VOICE & TONE - WRITE LIKE A HUMAN:
- Write in a natural, conversational human voice - avoid robotic or overly polished corporate language
- Use the original author's style and tone where possible - match their energy and phrasing
- Keep direct quotes and specific examples from the original content intact
- Include personal opinions or perspectives where appropriate - don't be afraid to have a point of view
- Use contractions, casual transitions, and varied sentence lengths
- Avoid buzzwords, jargon, and marketing-speak like "leverage," "synergy," "game-changing," "innovative solution"
- Write like you're explaining this to a friend over coffee, not presenting to a boardroom
- It's okay to be slightly imperfect - human writing has personality and occasional informality

Original content to remix:
{content}

Create content that:
- Preserves the core message and topic of the original
- Takes a strong stance on issues raised in the original content
- Challenges the status quo related to the original topic
- Uses provocative but professional language
- Only mentions Reply Cash if it's a natural fit for the argument
- Sounds authentically human, not AI-generated
- Is shareable and discussion-worthy about the ORIGINAL topic""",
        ),
        AngleTemplate(
            id="angle_preset_africa_focus",
            name="Africa Focus",
            description="Local context for African markets",
            prompt_template="""You are a content marketer for Reply Cash (a stablecoin remittance platform).

TASK: Remix the following content specifically for African markets.

IMPORTANT RULES:
1. KEEP THE ORIGINAL TOPIC - do NOT change the subject matter
2. Use local African context and relevance to frame the original content
3. Reference African markets only as they relate to the original topic
4. Do NOT change the topic to be about Africa or African remittances

VOICE & TONE - WRITE LIKE A HUMAN:
- Write in a natural, conversational human voice - avoid robotic or overly polished corporate language
- Use the original author's style and tone where possible - match their energy and phrasing
- Keep direct quotes and specific examples from the original content intact
- Include personal opinions or perspectives where appropriate - don't be afraid to have a point of view
- Use contractions, casual transitions, and varied sentence lengths
- Avoid buzzwords, jargon, and marketing-speak like "leverage," "synergy," "game-changing," "innovative solution"
- Write like you're explaining this to a friend over coffee, not presenting to a boardroom
- It's okay to be slightly imperfect - human writing has personality and occasional informality

Original content to remix:
{content}

Create content that:
- Preserves the core message and topic of the original
- References African markets (Nigeria, Kenya, Ghana, etc.) where relevant
- Uses local examples that support the original topic
- Naturally includes Reply Cash as a solution for African users if applicable
- Sounds authentically human, not AI-generated
- Keeps the focus on the ORIGINAL topic with African context""",
        ),
        AngleTemplate(
            id="angle_preset_founder_story",
            name="Founder Story",
            description="Personal, authentic, community building",
            prompt_template="""You are a content marketer for Reply Cash (a stablecoin remittance platform).

TASK: Remix the following content from a personal, founder perspective.

IMPORTANT RULES:
1. KEEP THE ORIGINAL TOPIC - do NOT change the subject matter
2. Frame the original content from a personal, authentic perspective
3. Connect the topic to Reply Cash's mission/vision only if relevant
4. Do NOT turn this into a founder story about Reply Cash's creation

VOICE & TONE - WRITE LIKE A HUMAN:
- Write in a natural, conversational human voice - avoid robotic or overly polished corporate language
- Use the original author's style and tone where possible - match their energy and phrasing
- Keep direct quotes and specific examples from the original content intact
- Include personal opinions or perspectives where appropriate - don't be afraid to have a point of view
- Use contractions, casual transitions, and varied sentence lengths
- Avoid buzzwords, jargon, and marketing-speak like "leverage," "synergy," "game-changing," "innovative solution"
- Write like you're explaining this to a friend over coffee, not presenting to a boardroom
- It's okay to be slightly imperfect - human writing has personality and occasional informality

Original content to remix:
{content}

Create content that:
- Preserves the core message and topic of the original
- Uses first-person perspective ('I', 'we', 'our') where appropriate
- Makes authentic connections between the topic and Reply Cash's values
- Shows vulnerability and authenticity about the topic at hand
- Sounds authentically human, not AI-generated
- Builds community around the ORIGINAL topic, not Reply Cash itself""",
        ),
    ]

    def __init__(self, api_client: Optional["ApiClient"] = None) -> None:
        self.api_client = api_client

    def get_available_angles(self) -> list[AngleTemplate]:
        """Get list of available angle templates."""
        # Try to fetch from API first
        if self.api_client:
            try:
                response = self.api_client.get("/angles")
                if response.success and response.data:
                    angles = response.data.get("angles", [])
                    return [
                        AngleTemplate(
                            id=a["id"],
                            name=a["name"],
                            description=a.get("description", ""),
                            prompt_template=a.get("promptTemplate", ""),
                        )
                        for a in angles
                    ]
            except Exception as e:
                Logger.error("Failed to fetch angles from API", e)

        # Return preset angles
        return self.PRESET_ANGLES

    def extract_from_url(self, url: str) -> Optional[ExtractedContent]:
        """Extract content from a URL.

        Args:
            url: The URL to extract from

        Returns:
            ExtractedContent or None if failed
        """
        Logger.info("Extracting content from URL", {"url": url})

        if not self.api_client:
            return None

        # Try Twitter/X extraction first
        if "x.com" in url or "twitter.com" in url:
            try:
                content = self._extract_tweet(url)
                if content:
                    return content
                # If tweet extraction fails, fall back to web scraping
                Logger.warn("Tweet extraction failed, trying web scraping fallback")
            except Exception as e:
                Logger.error("Tweet extraction error, trying web scraping", e)

        # Generic web scraping for any URL
        try:
            response = self.api_client.post(
                "/skills/web/scrape",
                {
                    "url": url,
                    "formats": ["markdown"],
                    "onlyMainContent": True,
                },
            )

            if response.success and response.data:
                data = response.data
                markdown = data.get("markdown", "")
                metadata = data.get("metadata", {})

                return ExtractedContent(
                    title=metadata.get("title", "Imported Content"),
                    text=markdown,
                    source_url=url,
                    metadata=metadata,
                )

            Logger.error("Web scraping failed", response.error)
            return None

        except Exception as e:
            Logger.error("Failed to extract content", e)
            return None

    def _extract_tweet(self, url: str) -> Optional[ExtractedContent]:
        """Extract tweet content."""
        try:
            response = self.api_client.post(
                "/twitter/extract",
                {"url": url},
            )

            if response.success and response.data:
                data = response.data
                tweet = data.get("tweet", {})

                return ExtractedContent(
                    title=f"Tweet by @{tweet.get('author', {}).get('username', 'unknown')}",
                    text=tweet.get("text", ""),
                    author=tweet.get("author", {}).get("name"),
                    source_url=url,
                    metadata={
                        "metrics": tweet.get("metrics"),
                        "created_at": tweet.get("createdAt"),
                    },
                )

            return None

        except Exception as e:
            Logger.error("Failed to extract tweet", e)
            return None

    def remix_content(
        self,
        source_content: str,
        angle_id: str,
        format_type: str = "blog",
        length: str = "medium",
    ) -> RemixResult:
        """Remix content using an angle template.

        This method calls the /remix/generate API to get a rendered prompt,
        then returns the prompt for the LLM to generate actual content.

        Args:
            source_content: Original content to remix
            angle_id: The angle template ID
            format_type: Output format (blog, social, email)
            length: Content length (short, medium, long)

        Returns:
            RemixResult with rendered prompt (to be processed by LLM)
        """
        Logger.info("Remixing content", {"angle": angle_id, "format": format_type})

        # Find angle template name for display
        angle_name = angle_id
        for a in self.PRESET_ANGLES:
            if a.id == angle_id:
                angle_name = a.name
                break

        # Use API to get rendered prompt
        if self.api_client:
            try:
                response = self.api_client.post(
                    "/remix/generate",
                    {
                        "text": source_content,  # API expects 'text' not 'content'
                        "angleId": angle_id,
                        "format": format_type,
                        "length": length,
                    },
                )

                if response.success and response.data:
                    data = response.data
                    prompt_data = data.get("prompt", {})
                    rendered_template = prompt_data.get("renderedTemplate", "")
                    system_prompt = prompt_data.get("baseSystemPrompt", "")

                    return RemixResult(
                        success=True,
                        content=rendered_template,  # This is the prompt for LLM
                        angle_used=angle_name,
                    )

                elif response.error:
                    Logger.error("Remix API error", response.error)

            except Exception as e:
                Logger.error("API remix failed, falling back to local", e)

        # Local fallback using preset angle template
        angle = None
        for a in self.PRESET_ANGLES:
            if a.id == angle_id:
                angle = a
                break

        if angle:
            try:
                prompt = angle.prompt_template.format(content=source_content)

                # Add format instructions
                if format_type == "social":
                    prompt += "\n\nFormat this as social media content (Twitter/LinkedIn style). Keep it concise and engaging."
                elif format_type == "email":
                    prompt += "\n\nFormat this as an email. Include a subject line and body."

                return RemixResult(
                    success=True,
                    content=prompt,
                    angle_used=angle.name,
                )
            except Exception as e:
                return RemixResult(success=False, error=str(e))

        return RemixResult(
            success=False,
            error=f"Angle template not found: {angle_id}",
        )

    def format_angles_list(self, angles: list[AngleTemplate]) -> str:
        """Format angles list for display."""
        lines = ["Available remix angles:", ""]

        for i, angle in enumerate(angles, 1):
            lines.append(f"{i}. **{angle.name}**")
            lines.append(f"   {angle.description}")
            lines.append("")

        return "\n".join(lines)

    def format_extracted_content(self, content: ExtractedContent) -> str:
        """Format extracted content for display."""
        lines = [
            f"📄 **{content.title}**",
            "",
            f"Source: {content.source_url}",
        ]

        if content.author:
            lines.append(f"Author: {content.author}")

        lines.extend([
            "",
            "Content preview:",
            "```",
            content.text[:500] + "..." if len(content.text) > 500 else content.text,
            "```",
        ])

        return "\n".join(lines)
