# Familiar - Self-Hosted AI Companion Platform
# Copyright (c) 2026 George Scott Foley
# ORCID: 0009-0006-4957-0540
# Email: Georgescottfoley@proton.me
# Licensed under the MIT License - see LICENSE file for details

"""
MailerLite Email Newsletter Skill

Manage subscribers, create campaigns, and view stats.
Shared by Nonprofit (donor newsletters) and Artist (show invites).

Setup:
    MAILERLITE_API_KEY=your_api_token

Get a key at: https://www.mailerlite.com/
API: https://connect.mailerlite.com/api/
"""

import logging

from familiar.core.api_cache import cached
from familiar.skills._api_utils import (
    APIError,
    api_get,
    api_post,
    get_env,
)

logger = logging.getLogger(__name__)

BASE_URL = "https://connect.mailerlite.com/api"


def _api_key() -> str:
    return get_env("MAILERLITE_API_KEY") or ""


def _headers() -> dict:
    return {
        "Authorization": f"Bearer {_api_key()}",
        "Content-Type": "application/json",
    }


def _check_config() -> str:
    if not _api_key():
        return (
            "MailerLite not configured.\n"
            "Set MAILERLITE_API_KEY in your environment.\n"
            "Get your key at: https://www.mailerlite.com/"
        )
    return ""


# ---------------------------------------------------------------------------
# Tool handlers
# ---------------------------------------------------------------------------


def list_subscribers(data: dict) -> str:
    """List email subscribers."""
    err = _check_config()
    if err:
        return err

    limit = min(int(data.get("limit", 25)), 100)
    status = data.get("status", "active")

    try:
        result = _subscribers_cached(limit, status)

        subs = result.get("data", [])
        if not subs:
            return "No subscribers found."

        total = result.get("meta", {}).get("total", len(subs))
        lines = [f"**Subscribers** ({total} total, showing {len(subs)}):", ""]

        for i, s in enumerate(subs, 1):
            email = s.get("email", "")
            name = s.get("fields", {}).get("name", "")
            sub_status = s.get("status", "")
            created = s.get("created_at", "")[:10]
            opens = s.get("stats", {}).get("opens_count", 0)
            clicks = s.get("stats", {}).get("clicks_count", 0)

            display_name = f"**{name}**" if name else ""
            lines.append(f"{i}. {display_name} {email}".strip())
            details = [sub_status]
            if created:
                details.append(f"Since {created}")
            if opens:
                details.append(f"{opens} opens")
            if clicks:
                details.append(f"{clicks} clicks")
            lines.append(f"   {' | '.join(details)}")
            lines.append("")

        return "\n".join(lines)

    except APIError as e:
        return str(e)
    except Exception as e:
        logger.error("MailerLite subscribers error: %s", e)
        return f"Error fetching subscribers: {e}"


@cached(prefix="mailerlite_subs", ttl=120)
def _subscribers_cached(limit: int, status: str) -> dict:
    params = {"limit": limit}
    if status:
        params["filter[status]"] = status
    return api_get(
        f"{BASE_URL}/subscribers",
        params=params,
        headers=_headers(),
        service_name="MailerLite",
    )


def add_subscriber(data: dict) -> str:
    """Add a new email subscriber."""
    err = _check_config()
    if err:
        return err

    email = data.get("email", "").strip()
    if not email:
        return "Please provide an email address."

    name = data.get("name", "").strip()

    try:
        body = {"email": email}
        if name:
            body["fields"] = {"name": name}

        result = api_post(
            f"{BASE_URL}/subscribers",
            json=body,
            headers=_headers(),
            service_name="MailerLite",
        )

        sub_data = result.get("data", result)
        sub_email = sub_data.get("email", email)
        sub_id = sub_data.get("id", "")
        status = sub_data.get("status", "active")

        return f"**Subscriber added!**\n\n  Email: {sub_email}\n  ID: {sub_id}\n  Status: {status}"

    except APIError as e:
        return str(e)
    except Exception as e:
        logger.error("MailerLite add subscriber error: %s", e)
        return f"Error adding subscriber: {e}"


def list_campaigns(data: dict) -> str:
    """List email campaigns."""
    err = _check_config()
    if err:
        return err

    status = data.get("status", "sent")
    limit = min(int(data.get("limit", 10)), 50)

    try:
        result = _campaigns_cached(status, limit)

        campaigns = result.get("data", [])
        if not campaigns:
            return f"No {status} campaigns found."

        lines = [f"**Campaigns** ({status}, showing {len(campaigns)}):", ""]

        for i, c in enumerate(campaigns, 1):
            name = c.get("name", "Untitled")
            camp_status = c.get("status", "")
            camp_type = c.get("type", "")
            created = c.get("created_at", "")[:10]

            stats = c.get("stats", {})
            sent = stats.get("sent", 0)
            opens = stats.get("opens_count", 0)
            clicks = stats.get("clicks_count", 0)
            open_rate = stats.get("open_rate", {}).get("float", 0)

            lines.append(f"{i}. **{name}**")
            details = [camp_status]
            if camp_type:
                details.append(camp_type)
            if created:
                details.append(created)
            lines.append(f"   {' | '.join(details)}")

            if sent:
                stat_parts = [f"Sent: {sent}"]
                if opens:
                    stat_parts.append(f"Opens: {opens}")
                if open_rate:
                    stat_parts.append(f"Rate: {open_rate:.1f}%")
                if clicks:
                    stat_parts.append(f"Clicks: {clicks}")
                lines.append(f"   {' | '.join(stat_parts)}")
            lines.append("")

        return "\n".join(lines)

    except APIError as e:
        return str(e)
    except Exception as e:
        logger.error("MailerLite campaigns error: %s", e)
        return f"Error fetching campaigns: {e}"


@cached(prefix="mailerlite_campaigns", ttl=120)
def _campaigns_cached(status: str, limit: int) -> dict:
    params = {"limit": limit}
    if status:
        params["filter[status]"] = status
    return api_get(
        f"{BASE_URL}/campaigns",
        params=params,
        headers=_headers(),
        service_name="MailerLite",
    )


def campaign_stats(data: dict) -> str:
    """Get detailed stats for a specific campaign."""
    err = _check_config()
    if err:
        return err

    campaign_id = data.get("campaign_id", "").strip()
    if not campaign_id:
        return "Please provide a campaign_id."

    try:
        result = _campaign_stats_cached(campaign_id)

        camp = result.get("data", result)
        name = camp.get("name", "Campaign")
        stats = camp.get("stats", {})

        sent = stats.get("sent", 0)
        opens = stats.get("opens_count", 0)
        unique_opens = stats.get("unique_opens_count", 0)
        clicks = stats.get("clicks_count", 0)
        unique_clicks = stats.get("unique_clicks_count", 0)
        unsubs = stats.get("unsubscribes_count", 0)
        bounces = stats.get("hard_bounces_count", 0) + stats.get("soft_bounces_count", 0)
        open_rate = stats.get("open_rate", {}).get("float", 0)
        click_rate = stats.get("click_rate", {}).get("float", 0)

        lines = [
            f"**Campaign Stats: {name}**",
            "",
            f"  Sent: {sent}",
            f"  Opens: {opens} ({unique_opens} unique) — {open_rate:.1f}%",
            f"  Clicks: {clicks} ({unique_clicks} unique) — {click_rate:.1f}%",
            f"  Unsubscribes: {unsubs}",
            f"  Bounces: {bounces}",
        ]
        return "\n".join(lines)

    except APIError as e:
        return str(e)
    except Exception as e:
        logger.error("MailerLite campaign stats error: %s", e)
        return f"Error fetching campaign stats: {e}"


@cached(prefix="mailerlite_stats", ttl=300)
def _campaign_stats_cached(campaign_id: str) -> dict:
    return api_get(
        f"{BASE_URL}/campaigns/{campaign_id}",
        headers=_headers(),
        service_name="MailerLite",
    )


# ---------------------------------------------------------------------------
# Tool definitions
# ---------------------------------------------------------------------------

TOOLS = [
    {
        "name": "list_subscribers",
        "description": (
            "List email subscribers from MailerLite. Shows email, name, status, open/click counts."
        ),
        "input_schema": {
            "type": "object",
            "properties": {
                "limit": {
                    "type": "integer",
                    "description": "Max results (1-100, default 25)",
                    "default": 25,
                },
                "status": {
                    "type": "string",
                    "description": "Filter: active, unsubscribed, bounced",
                    "default": "active",
                },
            },
        },
        "handler": list_subscribers,
        "category": "mailerlite",
    },
    {
        "name": "add_subscriber",
        "description": "Add a new email subscriber to MailerLite.",
        "input_schema": {
            "type": "object",
            "properties": {
                "email": {
                    "type": "string",
                    "description": "Subscriber email address",
                },
                "name": {
                    "type": "string",
                    "description": "Subscriber name",
                },
            },
            "required": ["email"],
        },
        "handler": add_subscriber,
        "category": "mailerlite",
    },
    {
        "name": "list_campaigns",
        "description": (
            "List MailerLite email campaigns. Shows name, status, sent count, and open rates."
        ),
        "input_schema": {
            "type": "object",
            "properties": {
                "status": {
                    "type": "string",
                    "description": "Filter: draft, ready, sent",
                    "default": "sent",
                },
                "limit": {
                    "type": "integer",
                    "description": "Max results (1-50, default 10)",
                    "default": 10,
                },
            },
        },
        "handler": list_campaigns,
        "category": "mailerlite",
    },
    {
        "name": "campaign_stats",
        "description": (
            "Get detailed stats for a MailerLite campaign."
            " Shows opens, clicks, unsubscribes, bounce rates."
        ),
        "input_schema": {
            "type": "object",
            "properties": {
                "campaign_id": {
                    "type": "string",
                    "description": "Campaign ID",
                },
            },
            "required": ["campaign_id"],
        },
        "handler": campaign_stats,
        "category": "mailerlite",
    },
]
