# 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

"""
Instagram Graph API Skill

View insights, recent media, and audience demographics for business/creator accounts.

Setup:
    INSTAGRAM_ACCESS_TOKEN=your_long_lived_token
    INSTAGRAM_BUSINESS_ID=your_ig_user_id

Get credentials at: https://developers.facebook.com/
API: https://graph.instagram.com/v21.0/
"""

import logging

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

logger = logging.getLogger(__name__)

BASE_URL = "https://graph.instagram.com/v21.0"


def _token() -> str:
    return get_env("INSTAGRAM_ACCESS_TOKEN") or ""


def _business_id() -> str:
    return get_env("INSTAGRAM_BUSINESS_ID") or ""


def _check_config() -> str:
    if not _token():
        return (
            "Instagram not configured.\n"
            "Set INSTAGRAM_ACCESS_TOKEN and INSTAGRAM_BUSINESS_ID.\n"
            "Get credentials at: https://developers.facebook.com/"
        )
    if not _business_id():
        return "INSTAGRAM_BUSINESS_ID not set."
    return ""


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


def ig_insights(data: dict) -> str:
    """Get account insights (impressions, reach, followers)."""
    err = _check_config()
    if err:
        return err

    period = data.get("period", "day")
    metrics = data.get("metrics", "impressions,reach,follower_count")

    try:
        result = _insights_cached(metrics, period)

        insights = result.get("data", [])
        if not insights:
            return "No insights data available."

        lines = [f"**Instagram Insights** (period: {period}):", ""]

        for metric in insights:
            name = metric.get("name", "")
            title = metric.get("title", name)
            values = metric.get("values", [])

            if values:
                latest = values[-1]
                value = latest.get("value", 0)
                end_time = latest.get("end_time", "")[:10]

                if isinstance(value, dict):
                    lines.append(f"**{title}:**")
                    for k, v in sorted(value.items(), key=lambda x: -x[1])[:10]:
                        lines.append(f"  {k}: {v}")
                else:
                    lines.append(
                        f"  {title}: {value:,}" if isinstance(value, int) else f"  {title}: {value}"
                    )
                    if end_time:
                        lines.append(f"    (as of {end_time})")
            lines.append("")

        return "\n".join(lines)

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


@cached(prefix="ig_insights", ttl=300)
def _insights_cached(metrics: str, period: str) -> dict:
    return api_get(
        f"{BASE_URL}/{_business_id()}/insights",
        params={
            "metric": metrics,
            "period": period,
            "access_token": _token(),
        },
        service_name="Instagram",
    )


def ig_recent_media(data: dict) -> str:
    """List recent Instagram posts."""
    err = _check_config()
    if err:
        return err

    limit = min(int(data.get("limit", 10)), 25)

    try:
        result = _media_cached(limit)

        posts = result.get("data", [])
        if not posts:
            return "No recent media found."

        lines = [f"**Recent Posts** ({len(posts)}):", ""]

        for i, post in enumerate(posts, 1):
            media_type = post.get("media_type", "")
            caption = post.get("caption", "")
            timestamp = post.get("timestamp", "")[:10]
            permalink = post.get("permalink", "")
            post_id = post.get("id", "")

            type_icon = {
                "IMAGE": "Photo",
                "VIDEO": "Video",
                "CAROUSEL_ALBUM": "Carousel",
                "REELS": "Reel",
            }.get(media_type, media_type)

            caption_preview = (caption[:60] + "...") if len(caption) > 60 else caption
            lines.append(f"{i}. **[{type_icon}]** {caption_preview}")
            details = [f"ID: {post_id}"]
            if timestamp:
                details.append(timestamp)
            if permalink:
                details.append(permalink)
            lines.append(f"   {' | '.join(details)}")
            lines.append("")

        return "\n".join(lines)

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


@cached(prefix="ig_media", ttl=120)
def _media_cached(limit: int) -> dict:
    return api_get(
        f"{BASE_URL}/{_business_id()}/media",
        params={
            "fields": "id,caption,media_type,timestamp,permalink",
            "limit": limit,
            "access_token": _token(),
        },
        service_name="Instagram",
    )


def ig_audience(data: dict) -> str:
    """Get audience demographics (gender, age, country)."""
    err = _check_config()
    if err:
        return err

    try:
        result = _audience_cached()

        insights = result.get("data", [])
        if not insights:
            return "No audience data available (need 100+ followers)."

        lines = ["**Audience Demographics:**", ""]

        for metric in insights:
            name = metric.get("name", "")
            title = metric.get("title", name)
            values = metric.get("values", [])

            if values:
                value = values[-1].get("value", {})
                if isinstance(value, dict) and value:
                    lines.append(f"**{title}:**")
                    sorted_items = sorted(value.items(), key=lambda x: -x[1])
                    for k, v in sorted_items[:10]:
                        if isinstance(v, float):
                            lines.append(f"  {k}: {v:.1f}%")
                        else:
                            lines.append(f"  {k}: {v}")
                    lines.append("")

        return "\n".join(lines)

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


@cached(prefix="ig_audience", ttl=600)
def _audience_cached() -> dict:
    return api_get(
        f"{BASE_URL}/{_business_id()}/insights",
        params={
            "metric": "audience_gender_age,audience_country,audience_city",
            "period": "lifetime",
            "access_token": _token(),
        },
        service_name="Instagram",
    )


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

TOOLS = [
    {
        "name": "ig_insights",
        "description": "Get Instagram account insights: impressions, reach, follower count.",
        "input_schema": {
            "type": "object",
            "properties": {
                "period": {
                    "type": "string",
                    "description": "Period: day, week, month, lifetime",
                    "default": "day",
                },
                "metrics": {
                    "type": "string",
                    "description": "Comma-separated metrics (default: impressions,reach,follower_count)",
                },
            },
        },
        "handler": ig_insights,
        "category": "instagram",
    },
    {
        "name": "ig_recent_media",
        "description": "List recent Instagram posts with type, caption, and link.",
        "input_schema": {
            "type": "object",
            "properties": {
                "limit": {
                    "type": "integer",
                    "description": "Max posts (1-25, default 10)",
                    "default": 10,
                },
            },
        },
        "handler": ig_recent_media,
        "category": "instagram",
    },
    {
        "name": "ig_audience",
        "description": "Get Instagram audience demographics: gender, age, country, city.",
        "input_schema": {"type": "object", "properties": {}},
        "handler": ig_audience,
        "category": "instagram",
    },
]
