"""LinkedIn Organization Social Action Notifications mock responses.

Reference: https://learn.microsoft.com/en-us/linkedin/marketing/community-management/organizations/organization-notifications-api

Notification types (action field):
- SHARE_MENTION: Organization mentioned in a share/post
- COMMENT: Comment on organization's content
- SHARE: Share of organization's content
- LIKE: Reaction on organization's content

The response contains notifications for actions on posts that mention or
are related to the organization.
"""

import time
from typing import Any

# Sample person data for notification authors
SAMPLE_PERSONS = {
    "john_doe": {
        "urn": "urn:li:person:ABC123xyz",
        "first_name": "John",
        "last_name": "Doe",
        "headline": "Software Engineer at TechCorp",
        "profile_url": "https://www.linkedin.com/in/johndoe",
        "avatar_url": "https://media.licdn.com/dms/image/C5603AQ/profile.jpg",
    },
    "jane_smith": {
        "urn": "urn:li:person:DEF456abc",
        "first_name": "Jane",
        "last_name": "Smith",
        "headline": "Product Manager | Innovation Leader",
        "profile_url": "https://www.linkedin.com/in/janesmith",
        "avatar_url": "https://media.licdn.com/dms/image/C5603AQ/profile-jane.jpg",
    },
    "developer_mike": {
        "urn": "urn:li:person:GHI789def",
        "first_name": "Mike",
        "last_name": "Developer",
        "headline": "Full Stack Developer",
        "profile_url": "https://www.linkedin.com/in/mikedev",
        "avatar_url": "https://media.licdn.com/dms/image/C5603AQ/profile-mike.jpg",
    },
}


def _generate_timestamp(days_ago: int = 0, hours_ago: int = 0) -> int:
    """Generate a timestamp in milliseconds for n days/hours ago."""
    seconds_ago = (days_ago * 24 * 60 * 60) + (hours_ago * 60 * 60)
    return int((time.time() - seconds_ago) * 1000)


def mock_share_mention_notification(
    notification_id: int = 4406001,
    organization_urn: str = "urn:li:organization:12345",
    person_key: str = "john_doe",
    mention_text: str = "Check out @AcmeCorp's amazing new product launch! 🚀",
    days_ago: int = 0,
    hours_ago: int = 1,
) -> dict[str, Any]:
    """Generate a mock SHARE_MENTION notification.

    A SHARE_MENTION is when someone mentions the organization in their post.

    Args:
        notification_id: Unique notification identifier
        organization_urn: The organization being mentioned
        person_key: Key from SAMPLE_PERSONS for the author
        mention_text: The post text containing the @mention
        days_ago: How many days ago the notification occurred
        hours_ago: Additional hours ago

    Returns:
        Dict matching LinkedIn's notification format for SHARE_MENTION
    """
    person = SAMPLE_PERSONS.get(person_key, SAMPLE_PERSONS["john_doe"])
    timestamp = _generate_timestamp(days_ago, hours_ago)
    activity_id = 29292929292992929292 + notification_id

    return {
        "notificationId": notification_id,
        "organizationalEntity": organization_urn,
        "action": "SHARE_MENTION",
        "sourcePost": f"urn:li:activity:{activity_id}",
        "decoratedSourcePost": {
            "entity": f"urn:li:share:{343443 + notification_id}",
            "owner": person["urn"],
            "text": mention_text,
            "landingPageUrl": f"https://www.linkedin.com/feed/update/urn:li:activity:{activity_id}",
            "mediaCategory": "NONE",
        },
        "lastModifiedAt": timestamp,
        "subscriber": person["urn"],
    }


def mock_comment_notification(
    notification_id: int = 4406002,
    organization_urn: str = "urn:li:organization:12345",
    person_key: str = "jane_smith",
    comment_text: str = "Great insights! This is exactly what we needed.",
    parent_activity_id: int | None = None,
    days_ago: int = 0,
    hours_ago: int = 2,
) -> dict[str, Any]:
    """Generate a mock COMMENT notification.

    A COMMENT notification is when someone comments on the organization's post.

    Args:
        notification_id: Unique notification identifier
        organization_urn: The organization that owns the commented post
        person_key: Key from SAMPLE_PERSONS for the commenter
        comment_text: The comment text
        parent_activity_id: The activity being commented on
        days_ago: How many days ago the notification occurred
        hours_ago: Additional hours ago

    Returns:
        Dict matching LinkedIn's notification format for COMMENT
    """
    person = SAMPLE_PERSONS.get(person_key, SAMPLE_PERSONS["jane_smith"])
    timestamp = _generate_timestamp(days_ago, hours_ago)

    if parent_activity_id is None:
        parent_activity_id = 19191919191919191919 + notification_id

    comment_urn = f"urn:li:comment:(urn:li:activity:{parent_activity_id},{notification_id * 1000})"

    return {
        "notificationId": notification_id,
        "organizationalEntity": organization_urn,
        "action": "COMMENT",
        "sourcePost": f"urn:li:activity:{parent_activity_id}",
        "decoratedSourcePost": {
            "entity": comment_urn,
            "owner": person["urn"],
            "text": comment_text,
            "landingPageUrl": f"https://www.linkedin.com/feed/update/urn:li:activity:{parent_activity_id}?commentUrn={comment_urn}",
            "mediaCategory": "NONE",
        },
        "lastModifiedAt": timestamp,
        "subscriber": person["urn"],
    }


def mock_share_notification(
    notification_id: int = 4406003,
    organization_urn: str = "urn:li:organization:12345",
    person_key: str = "developer_mike",
    share_text: str = "Sharing this important update from @AcmeCorp",
    days_ago: int = 0,
    hours_ago: int = 3,
) -> dict[str, Any]:
    """Generate a mock SHARE notification.

    A SHARE notification is when someone reshares the organization's content.

    Args:
        notification_id: Unique notification identifier
        organization_urn: The organization whose content was shared
        person_key: Key from SAMPLE_PERSONS for the person sharing
        share_text: The text added to the reshare
        days_ago: How many days ago the notification occurred
        hours_ago: Additional hours ago

    Returns:
        Dict matching LinkedIn's notification format for SHARE
    """
    person = SAMPLE_PERSONS.get(person_key, SAMPLE_PERSONS["developer_mike"])
    timestamp = _generate_timestamp(days_ago, hours_ago)
    activity_id = 38383838383838383838 + notification_id

    return {
        "notificationId": notification_id,
        "organizationalEntity": organization_urn,
        "action": "SHARE",
        "sourcePost": f"urn:li:activity:{activity_id}",
        "decoratedSourcePost": {
            "entity": f"urn:li:share:{454545 + notification_id}",
            "owner": person["urn"],
            "text": share_text,
            "landingPageUrl": f"https://www.linkedin.com/feed/update/urn:li:activity:{activity_id}",
            "mediaCategory": "ARTICLE",
        },
        "lastModifiedAt": timestamp,
        "subscriber": person["urn"],
    }


def mock_like_notification(
    notification_id: int = 4406004,
    organization_urn: str = "urn:li:organization:12345",
    person_key: str = "john_doe",
    reaction_type: str = "LIKE",
    days_ago: int = 0,
    hours_ago: int = 4,
) -> dict[str, Any]:
    """Generate a mock LIKE (reaction) notification.

    A LIKE notification is when someone reacts to the organization's content.
    Reaction types: LIKE, PRAISE, EMPATHY, INTEREST, APPRECIATION

    Args:
        notification_id: Unique notification identifier
        organization_urn: The organization whose content was liked
        person_key: Key from SAMPLE_PERSONS for the person reacting
        reaction_type: Type of reaction
        days_ago: How many days ago the notification occurred
        hours_ago: Additional hours ago

    Returns:
        Dict matching LinkedIn's notification format for LIKE
    """
    person = SAMPLE_PERSONS.get(person_key, SAMPLE_PERSONS["john_doe"])
    timestamp = _generate_timestamp(days_ago, hours_ago)
    activity_id = 47474747474747474747 + notification_id

    return {
        "notificationId": notification_id,
        "organizationalEntity": organization_urn,
        "action": "LIKE",
        "sourcePost": f"urn:li:activity:{activity_id}",
        "decoratedSourcePost": {
            "entity": f"urn:li:socialAction:(urn:li:activity:{activity_id},{person['urn']},{reaction_type})",
            "owner": person["urn"],
            "text": "",  # Likes don't have text
            "landingPageUrl": f"https://www.linkedin.com/feed/update/urn:li:activity:{activity_id}",
            "mediaCategory": "NONE",
        },
        "lastModifiedAt": timestamp,
        "subscriber": person["urn"],
        "reactionType": reaction_type,  # Extra field for likes
    }


def mock_notifications_response(
    count: int = 5,
    action_types: list[str] | None = None,
    organization_urn: str = "urn:li:organization:12345",
    start: int = 0,
    include_paging: bool = True,
) -> dict[str, Any]:
    """Generate a mock paginated notifications response.

    Args:
        count: Number of notifications to generate
        action_types: List of action types to include. Defaults to mix of all types.
        organization_urn: Organization URN for all notifications
        start: Pagination start index
        include_paging: Whether to include paging information

    Returns:
        Dict matching LinkedIn's notifications response format
    """
    if action_types is None:
        action_types = ["SHARE_MENTION", "COMMENT", "SHARE", "LIKE"]

    person_keys = list(SAMPLE_PERSONS.keys())
    notifications = []

    for i in range(count):
        notification_id = 4406000 + start + i
        action = action_types[i % len(action_types)]
        person_key = person_keys[i % len(person_keys)]
        hours_ago = i + 1  # Each notification 1 hour older

        if action == "SHARE_MENTION":
            notification = mock_share_mention_notification(
                notification_id=notification_id,
                organization_urn=organization_urn,
                person_key=person_key,
                mention_text=f"Excited about @AcmeCorp's announcement #{i + 1}! 🎉",
                hours_ago=hours_ago,
            )
        elif action == "COMMENT":
            notification = mock_comment_notification(
                notification_id=notification_id,
                organization_urn=organization_urn,
                person_key=person_key,
                comment_text=f"This is comment #{i + 1} - very insightful!",
                hours_ago=hours_ago,
            )
        elif action == "SHARE":
            notification = mock_share_notification(
                notification_id=notification_id,
                organization_urn=organization_urn,
                person_key=person_key,
                share_text=f"Resharing post #{i + 1} from @AcmeCorp",
                hours_ago=hours_ago,
            )
        else:  # LIKE
            notification = mock_like_notification(
                notification_id=notification_id,
                organization_urn=organization_urn,
                person_key=person_key,
                hours_ago=hours_ago,
            )

        notifications.append(notification)

    response = {
        "type": "ORGANIZATION_SOCIAL_ACTION_NOTIFICATIONS",
        "notifications": notifications,
    }

    if include_paging:
        response["paging"] = {  # type: ignore[assignment]
            "count": count,
            "start": start,
            "total": count + start + (10 if count > 0 else 0),  # Simulate more results
            "links": [],
        }

    return response


def mock_empty_notifications_response() -> dict[str, Any]:
    """Generate an empty notifications response.

    Returns:
        Dict with empty notifications list
    """
    return {
        "type": "ORGANIZATION_SOCIAL_ACTION_NOTIFICATIONS",
        "notifications": [],
        "paging": {
            "count": 0,
            "start": 0,
            "total": 0,
            "links": [],
        },
    }


# Pre-built scenarios for common test cases
NOTIFICATION_SCENARIOS = {
    "single_mention": mock_notifications_response(count=1, action_types=["SHARE_MENTION"]),
    "mentions_only": mock_notifications_response(count=5, action_types=["SHARE_MENTION"]),
    "comments_only": mock_notifications_response(count=5, action_types=["COMMENT"]),
    "mixed": mock_notifications_response(count=10),
    "empty": mock_empty_notifications_response(),
    "large_batch": mock_notifications_response(count=50),  # For pagination testing
}


# Sample persons exported for use in tests
SAMPLE_PERSON_URNS = {key: person["urn"] for key, person in SAMPLE_PERSONS.items()}
