"""Factories for integrations app models."""

from datetime import timedelta

import factory
from django.utils import timezone
from factory.django import DjangoModelFactory

from accounts.tests.factories import WorkspaceFactory
from integrations.models import (
    GitHubInstallation,
    GitHubRepository,
    LinkedInPage,
    LinkedInSyncStatus,
)
from sources.tests.factories import SourceFactory


class GitHubInstallationFactory(DjangoModelFactory):
    """Factory for creating GitHubInstallation instances."""

    class Meta:
        model = GitHubInstallation

    workspace = factory.SubFactory(WorkspaceFactory)
    installation_id = factory.Sequence(lambda n: 10000 + n)
    account_login = factory.Sequence(lambda n: f"org-{n}")
    account_type = "Organization"
    account_id = factory.Sequence(lambda n: 20000 + n)
    account_avatar_url = ""
    permissions = factory.LazyFunction(dict)
    suspended_at = None


class GitHubRepositoryFactory(DjangoModelFactory):
    """Factory for creating GitHubRepository instances."""

    class Meta:
        model = GitHubRepository

    installation = factory.SubFactory(GitHubInstallationFactory)
    source = factory.SubFactory(
        SourceFactory,
        workspace=factory.SelfAttribute("..installation.workspace"),
        kind="github_repo",
    )
    repo_id = factory.Sequence(lambda n: 30000 + n)
    owner = factory.LazyAttribute(lambda obj: obj.installation.account_login)
    name = factory.Sequence(lambda n: f"repo-{n}")
    full_name = factory.LazyAttribute(lambda obj: f"{obj.owner}/{obj.name}")
    private = False
    sync_status = "pending"
    last_sync_at = None
    last_sync_error = ""
    sync_cursors = factory.LazyFunction(dict)
    is_archived = False


class LinkedInPageFactory(DjangoModelFactory):
    """Factory for creating LinkedInPage instances."""

    class Meta:
        model = LinkedInPage

    workspace = factory.SubFactory(WorkspaceFactory)
    source = factory.SubFactory(
        SourceFactory,
        workspace=factory.SelfAttribute("..workspace"),
        kind="linkedin_page",
    )

    # LinkedIn Organization identifiers
    organization_urn = factory.Sequence(lambda n: f"urn:li:organization:{12345 + n}")
    organization_id = factory.Sequence(lambda n: str(12345 + n))
    name = factory.Sequence(lambda n: f"Acme Corp {n}")
    vanity_name = factory.Sequence(lambda n: f"acme-corp-{n}")
    logo_url = factory.LazyAttribute(lambda obj: f"https://media.licdn.com/dms/image/{obj.organization_id}/logo.png")

    # OAuth tokens - using encrypted values would require encryption setup
    # So we use empty defaults that tests can override
    _access_token = ""
    _refresh_token = ""
    token_expires_at = factory.LazyFunction(lambda: timezone.now() + timedelta(days=60))

    # Authorized user
    authorized_user_urn = factory.Sequence(lambda n: f"urn:li:person:test-user-{n}")

    # Sync configuration and state
    sync_status = LinkedInSyncStatus.PENDING
    sync_error = ""
    last_sync_at = None
    next_sync_at = None
    sync_interval_minutes = 15
    sync_cursors = factory.LazyFunction(dict)

    # Soft delete
    is_archived = False

    class Params:
        """Factory params for common scenarios."""

        # Create with active sync status
        active = factory.Trait(
            sync_status=LinkedInSyncStatus.ACTIVE,
            last_sync_at=factory.LazyFunction(timezone.now),
            next_sync_at=factory.LazyFunction(lambda: timezone.now() + timedelta(minutes=15)),
        )

        # Create with expired token
        expired_token = factory.Trait(
            sync_status=LinkedInSyncStatus.EXPIRED,
            token_expires_at=factory.LazyFunction(lambda: timezone.now() - timedelta(days=1)),
        )

        # Create with error status
        error = factory.Trait(
            sync_status=LinkedInSyncStatus.ERROR,
            sync_error="LinkedIn API returned 500 Internal Server Error",
        )

        # Create paused
        paused = factory.Trait(sync_status=LinkedInSyncStatus.PAUSED)

        # Create archived
        archived = factory.Trait(is_archived=True)
