# -*- coding: utf-8 -*-
from __future__ import annotations

from django.utils.timezone import now
import pytest

from hotpocket_soa.dto.associations import AssociationWithTargetOut


@pytest.fixture
def association_factory(request: pytest.FixtureRequest):
    default_account = request.getfixturevalue('account')
    default_target = request.getfixturevalue('save')

    def factory(account=None, target=None, **kwargs):
        from hotpocket_backend_testing.factories.saves import AssociationFactory

        return AssociationFactory(
            account_uuid=(
                account.pk
                if account is not None
                else default_account.pk
            ),
            target=target or default_target,
            **kwargs,
        )

    return factory


@pytest.fixture
def association(association_factory):
    return association_factory()


@pytest.fixture
def association_out(association):
    return AssociationWithTargetOut.model_validate(
        association, from_attributes=True,
    )


@pytest.fixture
def deleted_association(association_factory):
    return association_factory(deleted_at=now())


@pytest.fixture
def deleted_association_out(deleted_association):
    return AssociationWithTargetOut.model_validate(
        deleted_association, from_attributes=True,
    )


@pytest.fixture
def archived_association(association_factory):
    return association_factory(archived_at=now())


@pytest.fixture
def archived_association_out(archived_association):
    return AssociationWithTargetOut.model_validate(
        archived_association, from_attributes=True,
    )


@pytest.fixture
def starred_association(association_factory):
    return association_factory(starred_at=now())


@pytest.fixture
def starred_association_out(starred_association):
    return AssociationWithTargetOut.model_validate(
        starred_association, from_attributes=True,
    )


@pytest.fixture
def deleted_save_association(association_factory, deleted_save):
    return association_factory(target=deleted_save)


@pytest.fixture
def deleted_save_association_out(deleted_save_association):
    return AssociationWithTargetOut.model_validate(
        deleted_save_association, from_attributes=True,
    )


@pytest.fixture
def other_account_association(association_factory, other_account):
    return association_factory(account=other_account)


@pytest.fixture
def other_account_association_out(other_account_association):
    return AssociationWithTargetOut.model_validate(
        other_account_association, from_attributes=True,
    )


@pytest.fixture
def other_account_deleted_association(association_factory, other_account):
    return association_factory(account=other_account, deleted_at=now())


@pytest.fixture
def other_account_deleted_association_out(other_account_deleted_association):
    return AssociationWithTargetOut.model_validate(
        other_account_deleted_association, from_attributes=True,
    )


@pytest.fixture
def other_account_archived_association(association_factory, other_account):
    return association_factory(account=other_account, archived_at=now())


@pytest.fixture
def other_account_archived_association_out(other_account_archived_association):
    return AssociationWithTargetOut.model_validate(
        other_account_archived_association, from_attributes=True,
    )


@pytest.fixture
def other_account_starred_association(association_factory, other_account):
    return association_factory(account=other_account, starred_at=now())


@pytest.fixture
def other_account_starred_association_out(other_account_starred_association):
    return AssociationWithTargetOut.model_validate(
        other_account_starred_association, from_attributes=True,
    )


@pytest.fixture
def other_account_deleted_save_association(association_factory, other_account, deleted_save):
    return association_factory(account=other_account, target=deleted_save)


@pytest.fixture
def other_account_deleted_save_association_out(other_account_deleted_save_association):
    return AssociationWithTargetOut.model_validate(
        other_account_deleted_save_association, from_attributes=True,
    )


@pytest.fixture
def browsable_associations(association,
                           deleted_association,
                           archived_association,
                           starred_association,
                           other_account_association,
                           ):
    return [
        association,
        starred_association,
    ]


@pytest.fixture
def browsable_association_outs(browsable_associations):
    return [
        AssociationWithTargetOut.model_validate(obj, from_attributes=True)
        for obj
        in browsable_associations
    ]


@pytest.fixture
def paginatable_associations(association_factory):
    result = [
        association_factory()
        for _ in range(0, 14)
    ]

    return result[::-1]


@pytest.fixture
def paginatable_association_outs(paginatable_associations):
    return [
        AssociationWithTargetOut.model_validate(obj, from_attributes=True)
        for obj
        in paginatable_associations
    ]
