"""Collector: company_follower_collector — Track new followers on company LinkedIn pages.

Polls GET /api/v1/users/followers to detect new followers over time.
Saves SIGNAL_COMPANY_FOLLOWER for each new follower.

Runs every 4 hours via the scheduler.
"""

from __future__ import annotations

import json
import logging
import time
from typing import Any

from ..constants import (
    SIGNAL_COMPANY_FOLLOWER,
    SIGNAL_TTL_COMPANY_FOLLOWER,
)

logger = logging.getLogger(__name__)


async def collect_company_followers() -> str:
    """Collect new follower signals from company LinkedIn pages.

    For each company watchlist entry:
    1. Call get_followers() for the company account
    2. Diff against previously seen followers (stored in watchlist keywords)
    3. Save new followers as SIGNAL_COMPANY_FOLLOWER signals

    Note: This requires the company page admin to have connected their
    LinkedIn account via Unipile. The followers endpoint may not be
    available for all company pages — gracefully skips on failure.

    Returns summary string.
    """
    from ..db.signal_queries import (
        list_watchlists,
        save_signal,
        signal_exists,
        update_watchlist,
        upsert_signal_account,
    )
    from ..linkedin import get_account_id, get_linkedin_client

    account_id = get_account_id()
    if not account_id:
        return "No LinkedIn account connected — skipping follower collection."

    client = get_linkedin_client()

    # Get company-type watchlists
    watchlists = list_watchlists(is_active=True)
    company_watchlists = [w for w in watchlists if w.get("watch_type") == "company"]

    if not company_watchlists:
        return "No company watchlists configured."

    total_new = 0
    errors = 0
    now = int(time.time())

    for wl in company_watchlists:
        wl_id = wl["id"]
        company_name = wl.get("name", "Unknown Company")
        campaign_id = wl.get("campaign_id")

        try:
            # Get followers — use company-specific endpoint for numeric IDs
            keywords_list = wl.get("keywords_list", [])
            company_id = keywords_list[0] if keywords_list else ""
            if company_id.isdigit():
                followers = await client.get_followers(account_id, company_id=company_id)
            else:
                followers = await client.get_followers(account_id)

            if not followers:
                continue

            for follower in followers:
                follower_id = follower.get("provider_id") or follower.get("id", "")
                follower_name = follower.get("name", "") or follower.get("full_name", "")

                if not follower_id:
                    continue

                dedup_key = f"cf:{wl_id}:{follower_id}"

                if signal_exists(SIGNAL_COMPANY_FOLLOWER, post_id=dedup_key):
                    continue

                metadata = {
                    "company_name": company_name,
                    "follower_name": follower_name,
                    "follower_id": follower_id,
                    "follower_headline": follower.get("headline", ""),
                    "follower_url": follower.get("profile_url", ""),
                }

                save_signal(
                    signal_type=SIGNAL_COMPANY_FOLLOWER,
                    source="company_page",
                    prospect_name=follower_name,
                    linkedin_id=follower_id,
                    campaign_id=campaign_id,
                    content=f"New follower of {company_name}: {follower_name}",
                    post_id=dedup_key,
                    metadata_json=json.dumps(metadata),
                    expires_at=now + SIGNAL_TTL_COMPANY_FOLLOWER,
                )
                upsert_signal_account(
                    linkedin_id=follower_id,
                    prospect_name=follower_name,
                )
                total_new += 1

            # Update last polled timestamp
            update_watchlist(wl_id, last_polled_at=now)

        except Exception as e:
            logger.warning(
                "Follower collection failed for '%s': %s (endpoint may not be available for company pages)",
                company_name, e,
            )
            errors += 1

    # ── Personal follower fallback ──
    # When company page followers returned zero (Voyager broken), collect
    # personal profile followers via the standard Unipile API instead.
    personal_new = 0
    if total_new == 0:
        try:
            personal_followers = await client.get_followers(account_id)
            if personal_followers:
                # Use first active campaign for attribution
                fallback_campaign_id = (
                    company_watchlists[0].get("campaign_id") if company_watchlists else None
                )
                for follower in personal_followers:
                    follower_id = follower.get("provider_id") or follower.get("id", "")
                    follower_name = follower.get("name", "") or follower.get("full_name", "")
                    if not follower_id:
                        continue

                    dedup_key = f"pf:{follower_id}"
                    if signal_exists(SIGNAL_COMPANY_FOLLOWER, post_id=dedup_key):
                        continue

                    metadata = {
                        "source": "personal_profile",
                        "follower_name": follower_name,
                        "follower_id": follower_id,
                        "follower_headline": follower.get("headline", ""),
                        "follower_url": follower.get("profile_url", ""),
                    }
                    save_signal(
                        signal_type=SIGNAL_COMPANY_FOLLOWER,
                        source="personal_profile",
                        prospect_name=follower_name,
                        linkedin_id=follower_id,
                        campaign_id=fallback_campaign_id,
                        content=f"New personal profile follower: {follower_name}",
                        post_id=dedup_key,
                        metadata_json=json.dumps(metadata),
                        expires_at=now + SIGNAL_TTL_COMPANY_FOLLOWER,
                    )
                    upsert_signal_account(
                        linkedin_id=follower_id,
                        prospect_name=follower_name,
                    )
                    personal_new += 1

        except Exception as e:
            logger.debug("Personal follower fallback failed: %s", e)

    summary = f"Checked {len(company_watchlists)} company pages, found {total_new} new followers"
    if personal_new:
        summary += f", {personal_new} personal profile followers"
    if errors:
        summary += f", {errors} errors"
    return summary
