"""
Celery tasks for syncing Addons Marketplace data per tenant.

Each task receives org_id and schema explicitly — there is no Flask request
context in Celery workers, so g.tenant_schema is not available. session_scope
must be called with schema= explicitly.
"""

from __future__ import annotations

import logging

from ..celery_app import celery_app
from ..db import session_scope

logger = logging.getLogger(__name__)


@celery_app.task(bind=True, max_retries=3, default_retry_delay=60)
def sync_threads(self, org_id: int, schema: str) -> dict:
    """
    Sync recent threads from the Addons API for the given tenant.

    Replaces the threading.Thread background sync used in the single-tenant app.
    Called after each manual sync trigger and on a schedule (if configured).
    """
    logger.info("[sync_threads] org_id=%s schema=%s", org_id, schema)
    try:
        from ..services.sync_service import SyncService
        from ..public_models import Organization
        from ..db import SessionLocal

        # Load org to get the encrypted Addons API key
        with session_scope() as pub_session:
            org = pub_session.query(Organization).filter_by(id=org_id).one_or_none()
            if not org:
                logger.error("Org %s not found, aborting sync", org_id)
                return {"status": "error", "detail": "org not found"}
            addons_api_key_encrypted = org.addons_api_key_encrypted

        with session_scope(schema=schema) as session:
            from ..config import config
            from cryptography.fernet import Fernet

            api_key = None
            if addons_api_key_encrypted:
                fernet_key = config.CREDENTIAL_ENCRYPTION_KEY
                if fernet_key:
                    f = Fernet(fernet_key.encode() if isinstance(fernet_key, str) else fernet_key)
                    raw = addons_api_key_encrypted
                    if isinstance(raw, str):
                        raw = raw.encode()
                    api_key = f.decrypt(raw).decode()

            sync_service = SyncService(session=session, api_key=api_key)
            result = sync_service.sync_recent()
            return {"status": "ok", "synced": result}

    except Exception as exc:
        logger.error("[sync_threads] Failed for org %s: %s", org_id, exc)
        raise self.retry(exc=exc)


@celery_app.task(bind=True, max_retries=2, default_retry_delay=120)
def run_historical_sync(self, org_id: int, schema: str, start_page: int = 1, end_page: int = None) -> dict:
    """
    Run a full historical sync (multiple pages) for the given tenant.

    Used during initial onboarding to backfill all threads.
    """
    logger.info("[run_historical_sync] org_id=%s schema=%s pages=%s-%s", org_id, schema, start_page, end_page)
    try:
        with session_scope(schema=schema) as session:
            from ..services.sync_service import SyncService
            sync_service = SyncService(session=session)
            result = sync_service.sync_historical(start_page=start_page, end_page=end_page)
            return {"status": "ok", "result": result}
    except Exception as exc:
        logger.error("[run_historical_sync] Failed for org %s: %s", org_id, exc)
        raise self.retry(exc=exc)
