import itertools
import shutil
from io import BytesIO

import pytest
from django.conf import settings
from django.core.cache import cache
from django.core.files.uploadedfile import SimpleUploadedFile
from django.utils import timezone
from PIL import Image

from apps.accounts.models import Role, User
from apps.editorial.models import Article, Status
from apps.taxonomy.models import Category

_seq = itertools.count()


@pytest.fixture(autouse=True)
def _isolation():
    cache.clear()
    yield
    shutil.rmtree(settings.MEDIA_ROOT, ignore_errors=True)


@pytest.fixture
def user_factory(db):
    def make(role=Role.LECTEUR, **kw):
        n = next(_seq)
        return User.objects.create_user(kw.pop("email", f"u{n}@test.bj"), "motdepasse-solide", name=kw.pop("name", f"User {n}"), role=role, **kw)
    return make


@pytest.fixture
def admin(user_factory):
    return user_factory(Role.ADMIN, name="Admin")


@pytest.fixture
def editeur(user_factory):
    return user_factory(Role.EDITEUR, name="Éditeur")


@pytest.fixture
def redacteur(user_factory):
    return user_factory(Role.REDACTEUR, name="Rédacteur")


@pytest.fixture
def lecteur(user_factory):
    return user_factory(Role.LECTEUR)


@pytest.fixture
def category(db):
    return Category.objects.create(nom="Politique", est_dans_menu=True, ordre=1)


@pytest.fixture
def article_factory(db, category, editeur):
    def make(**kw):
        n = next(_seq)
        kw.setdefault("titre", f"Article {n}")
        kw.setdefault("contenu", "<p>Contenu de test.</p>")
        kw.setdefault("categorie", category)
        kw.setdefault("auteur", editeur)
        kw.setdefault("statut", Status.PUBLIE)
        if "publie_le" not in kw:
            kw["publie_le"] = timezone.now() - timezone.timedelta(minutes=n + 1)
        return Article.objects.create(**kw)
    return make


@pytest.fixture
def image_file():
    def make(name="photo.jpg", size=(1400, 800)):
        buf = BytesIO()
        Image.new("RGB", size, (18, 48, 90)).save(buf, "JPEG")
        return SimpleUploadedFile(name, buf.getvalue(), content_type="image/jpeg")
    return make
