import logging
from dataclasses import dataclass
from enum import IntEnum
from typing import Optional
from uuid import uuid4

from django.contrib.auth import get_user_model
from django.db import models
from django.urls import reverse
from imagekit.models import ImageSpecField
from imagekit.processors import ResizeToFit
from scrobbles.dataclasses import BaseLogData
from scrobbles.mixins import ScrobblableConstants, ScrobblableMixin

logger = logging.getLogger(__name__)
BNULL = {"blank": True, "null": True}
User = get_user_model()


class MoodType(models.TextChoices):
    POSITIVE = "positive", "Positive"
    NEGATIVE = "negative", "Negative"


class MoodQuality(IntEnum):
    VERY_UNPLEASANT = 1
    UNPLEASANT = 2
    SLIGHTLY_UNPLEASANT = 3
    NEUTRAL = 4
    SLIGHTLY_PLEASANT = 5
    PLEASANT = 6
    VERY_PLEASANT = 7


@dataclass
class MoodLogData(BaseLogData):
    mood_type: Optional[str] = None
    mood_reason_ids: Optional[list[int]] = None
    mood_quality: Optional[int] = None
    weather_temp: Optional[float] = None
    weather_description: Optional[str] = None

    @classmethod
    def override_fields(cls) -> dict:
        from django import forms
        from moods.models import MoodReason

        return {
            "mood_type": forms.ChoiceField(
                choices=MoodType.choices,
                required=False,
                widget=forms.Select(attrs={"class": "form-control"}),
            ),
            "mood_reason_ids": forms.ModelMultipleChoiceField(
                queryset=MoodReason.objects.all().order_by("title"),
                required=False,
                widget=forms.SelectMultiple(attrs={"size": 10}),
            ),
            "mood_quality": forms.ChoiceField(
                choices=[
                    (mq.value, mq.name.replace("_", " ").title())
                    for mq in MoodQuality
                ],
                required=False,
                widget=forms.Select(attrs={"class": "form-control"}),
            ),
        }


class Mood(ScrobblableMixin):
    description = models.TextField(**BNULL)
    image = models.ImageField(upload_to="moods/", **BNULL)
    image_small = ImageSpecField(
        source="thumbnail",
        processors=[ResizeToFit(100, 100)],
        format="JPEG",
        options={"quality": 60},
    )
    image_medium = ImageSpecField(
        source="thumbnail",
        processors=[ResizeToFit(300, 300)],
        format="JPEG",
        options={"quality": 75},
    )
    mood_type = models.CharField(
        max_length=20, choices=MoodType.choices, **BNULL
    )

    def __str__(self):
        if self.title:
            return self.title
        return str(self.uuid)

    def get_absolute_url(self):
        return reverse("moods:mood_detail", kwargs={"slug": self.uuid})

    @property
    def subtitle(self) -> str:
        return ""

    @property
    def strings(self) -> ScrobblableConstants:
        return ScrobblableConstants(verb="Feeling", tags="thinking")

    @property
    def logdata_cls(self):
        return MoodLogData

    @property
    def primary_image_url(self) -> str:
        if self.image:
            return self.image.url
        return ""


class MoodReason(models.Model):
    uuid = models.UUIDField(default=uuid4, editable=False, **BNULL)
    title = models.CharField(max_length=255, **BNULL)
    description = models.TextField(**BNULL)

    def __str__(self):
        return self.title
