from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework import status
from backend.apps.archive.models import AudioMaterial, ImageMaterial, VideoMaterial
from . import serializers
from django.utils.text import capfirst
from rest_framework.metadata import SimpleMetadata
import logging

from django.core.exceptions import FieldDoesNotExist

# Set up logging
logger = logging.getLogger(__name__)

class SerializerFieldsMetadata(SimpleMetadata):
    """
    Generates metadata for fields, ensuring labels use model verbose_name.
    """

    def get_field_info(self, field):
        field_info = super().get_field_info(field)
        label = field.label

        if not label:
            model = None
            root = field.root
            if root is not None and hasattr(root, 'Meta') and hasattr(root.Meta, 'model'):
                model = root.Meta.model
            if model and field.field_name:
                try:
                    model_field = model._meta.get_field(field.field_name)
                    label = model_field.verbose_name
                except FieldDoesNotExist:
                    label = field.field_name.replace('_', ' ').capitalize()
            else:
                label = field.field_name.replace('_', ' ').capitalize()

        field_info['label'] = capfirst(label)
        field_info["type"] = field.__class__.__name__

        if isinstance(field, serializers.ChoiceField):
            field_info["choices"] = [
                {"value": key, "display_name": value}
                for key, value in field.choices.items()
            ]

        return field_info

    def determine_metadata(self, request, view):
        metadata = super().determine_metadata(request, view)
        queryset = view.get_queryset()
        model = queryset.model
        metadata["verbose_name"] = model._meta.verbose_name
        metadata["verbose_name_plural"] = model._meta.verbose_name_plural
        return metadata

class BaseMaterialViewSet(viewsets.ReadOnlyModelViewSet):
    """Base ViewSet for all media materials."""
    metadata_class = SerializerFieldsMetadata

    def get_queryset(self):
        queryset = super().get_queryset()
        search_query = self.request.query_params.get("common_search_query")
        logger.debug(f"Search query: {search_query}")

        logger.debug(f"Initial queryset count: {queryset.count()}")

        if search_query:
            query_lookup = Q()
            for field in self.common_search_fields:
                query_lookup |= Q(**{f"{field}__icontains": search_query})
            queryset = queryset.filter(query_lookup)

            logger.debug(f"Filtered queryset count: {queryset.count()}")
            logger.debug(f"SQL query: {queryset.query}")

        return queryset

    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def options(self, request, *args, **kwargs):
        """Customized method for providing field metadata."""
        metadata = self.metadata_class().determine_metadata(request, self)
        return Response(metadata, status=status.HTTP_200_OK)

class AudioMaterialViewSet(BaseMaterialViewSet):
    queryset = AudioMaterial.objects.all()
    serializer_class = serializers.AudioMaterialListSerializer
    common_search_fields = ["keywords", "annotation", "persons", "title"]

class ImageMaterialViewSet(BaseMaterialViewSet):
    queryset = ImageMaterial.objects.all()
    serializer_class = serializers.ImageMaterialListSerializer
    common_search_fields = ["keywords", "annotation", "persons", "author"]

class VideoMaterialViewSet(BaseMaterialViewSet):
    queryset = VideoMaterial.objects.all()
    serializer_class = serializers.VideoMaterialListSerializer
    common_search_fields = ["keywords", "annotation", "persons", "title", "description"]import re

from rest_framework import serializers

from . import models


class ImageMaterialListSerializer(serializers.ModelSerializer):
    creation_date = serializers.SerializerMethodField()
    annotation = serializers.SerializerMethodField()

    @staticmethod
    def get_annotation(instance):
        max_tokens = 11
        if instance.annotation:
            tokens = re.findall(r"\S+", instance.annotation)
            annotation = " ".join(tokens[:max_tokens])
            annotation += " ..." if len(tokens) > max_tokens else ""
            return annotation

    @staticmethod
    def get_creation_date(instance):
        match instance.creation_date_key:
            case models.CreationDateVariant.ONLY_YEAR:
                return instance.creation_date.year
            case models.CreationDateVariant.MONTH_AND_YEAR:
                return instance.creation_date.strftime("%m.%Y")
            case models.CreationDateVariant.FULL_DATE:
                return instance.creation_date.strftime("%d.%m.%Y")

    class Meta:
        model = models.ImageMaterial
        fields = ("id", "archive_number", "annotation", "creation_date", "author", "photo_type", "color")


class AudioMaterialListSerializer(ImageMaterialListSerializer):
    class Meta:
        model = models.AudioMaterial
        fields = ("id", "archive_number", "title", "annotation", "performer", "creation_date", "language")


class VideoMaterialListSerializer(ImageMaterialListSerializer):
    class Meta:
        model = models.VideoMaterial
        fields = ("id", "archive_number", "title", "creation_date", "annotation", "roles", "language")
from django.db import models
from django_minio_backend import MinioBackend


class BaseFile(models.Model):
    id = models.BigAutoField(primary_key=True, db_column="id_object")
    file_name = models.CharField(max_length=100)

    class Meta:
        abstract = True


class VideoFile(BaseFile):
    duration = models.PositiveIntegerField("Длительность в мс", null=True)
    frame_rate = models.IntegerField("Частота кадров", null=True)
    file_path = models.FileField(storage=MinioBackend(bucket_name="archive-kffd"), upload_to="video")
    material = models.ForeignKey(
        "VideoMaterial",
        verbose_name="Видео-файл",
        related_name="media_files",
        on_delete=models.PROTECT,
        db_column="id_main",
    )

    class Meta:
        db_table = "archive_video_file"
        ordering = ("id",)


class AudioFile(BaseFile):
    duration = models.PositiveIntegerField("Длительность в мс", null=True)
    file_path = models.FileField(storage=MinioBackend(bucket_name="archive-kffd"), upload_to="audio")
    material = models.ForeignKey(
        "AudioMaterial",
        verbose_name="Аудио-файл",
        related_name="media_files",
        on_delete=models.PROTECT,
        db_column="id_main",
    )

    class Meta:
        db_table = "archive_audio_file"
        ordering = ("id",)


class ImageFile(BaseFile):
    file_path = models.FileField(storage=MinioBackend(bucket_name="archive-kffd"), upload_to="image")
    material = models.ForeignKey(
        "ImageMaterial",
        verbose_name="Фото-файл",
        related_name="media_files",
        on_delete=models.PROTECT,
        db_column="id_main",
    )

    class Meta:
        db_table = "archive_image_file"
        ordering = ("id",)


class CreationDateVariant(models.IntegerChoices):
    ONLY_YEAR = 1, "только год"
    MONTH_AND_YEAR = 3, "год и месяц"
    FULL_DATE = 7, "год, месяц и число"


class BaseMaterial(models.Model):
    id = models.BigAutoField(primary_key=True, db_column="id_main")
    keywords = models.CharField("Ключевые слова", max_length=512, blank=True)
    annotation = models.TextField("Аннотация", blank=True)
    archive_number = models.CharField(max_length=256, unique=True)
    persons = models.CharField("Персоналии", max_length=1024, blank=True)
    source = models.CharField("Источник поступления", max_length=256, blank=True)
    founder = models.CharField("Фондообразователь", max_length=256, blank=True)
    creation_date = models.DateField("Дата создания", null=True)
    creation_date_key = models.SmallIntegerField(
        help_text="Показывает какая часть даты известна в двоичном формате: "
        "001 (1) только год, "
        "011 (3) год и месяц, "
        "111 (7) год месяц и число",
        choices=CreationDateVariant.choices,
        null=True,
    )
    creation_date_comment = models.CharField("Дата создания комментарий", max_length=1024, blank=True)
    creation_place = models.CharField("Место создания", max_length=256, blank=True)
    receive_date = models.DateField("Дата поступления", null=True)

    class Meta:
        abstract = True


class AudioMaterial(BaseMaterial):
    title = models.CharField("Название", max_length=512, blank=True)
    text_author = models.CharField("Автор текста", max_length=256, blank=True)
    performer = models.CharField("Исполнитель", max_length=256, blank=True)
    music_author = models.CharField("Автор музыки", max_length=256, blank=True)
    arrangement = models.CharField("Аранжировка", max_length=256, blank=True)
    conductor = models.CharField("Дирижер", max_length=256, blank=True)
    art_director = models.CharField("Художественный руководитель", max_length=256, blank=True)
    language = models.CharField("Язык", max_length=256, blank=True)
    choir = models.CharField("Сопровождение (хор)", max_length=256, blank=True)
    orchestra = models.CharField("Сопровождение (инструменты)", max_length=256, blank=True)
    montage_sheet = models.TextField("Монтажный лист", blank=True)

    class Meta:
        verbose_name = "Фонодокумент"
        verbose_name_plural = "Фонодокументы"
        db_table = "archive_audio_material"
        ordering = ("id",)


class VideoMaterial(BaseMaterial):
    title = models.CharField("Название", max_length=512, blank=True)
    description = models.TextField("Описание сюжета", blank=True)
    montage_sheet = models.TextField("Монтажный лист", blank=True)
    roles = models.TextField("В ролях", blank=True)
    scriptwriter = models.CharField("Сценарист", max_length=512, blank=True)
    director = models.CharField("Режиссер", max_length=512, blank=True)
    cameraman = models.CharField("Оператор", max_length=512, blank=True)
    sound_engineer = models.CharField("Звукооператор", max_length=512, blank=True)
    painter = models.CharField("Художник", max_length=512, blank=True)
    composer = models.CharField("Композитор", max_length=512, blank=True)
    studio = models.CharField("Студия", max_length=512, blank=True)
    role_dubbing = models.CharField("Роли озвучивали", max_length=1024, blank=True)
    video_creators = models.CharField("Над фильмом работали", max_length=1024, blank=True)
    video_type = models.CharField("Вид документа", max_length=256, blank=True)
    color = models.CharField("Цветность", max_length=256, blank=True)
    language = models.CharField("Язык", max_length=256, blank=True)
    literature_source = models.CharField("Литературный первоисточник", max_length=512, blank=True)
    voice_type = models.CharField("Озвученность", max_length=256, blank=True)

    class Meta:
        verbose_name = "Киновидеодокумент"
        verbose_name_plural = "Киновидеодокументы"
        db_table = "archive_video_material"
        ordering = ("id",)


class ImageMaterial(BaseMaterial):
    author = models.CharField("Автор", max_length=256, blank=True)
    photo_type = models.CharField("Вид фотодокумента", max_length=256, blank=True)
    color = models.CharField("Цветность", max_length=256, blank=True)

    class Meta:
        verbose_name = "Фотодокумент"
        verbose_name_plural = "Фотодокументы"
        db_table = "archive_image_material"
        ordering = ("id",)
from rest_framework.routers import DefaultRouter

from . import views

router = DefaultRouter()
router.register(r"audio-materials", views.AudioMaterialViewSet, basename="audio-materials")
router.register(r"image-materials", views.ImageMaterialViewSet, basename="image-materials")
router.register(r"video-materials", views.VideoMaterialViewSet, basename="video-materials")

urlpatterns = [*router.urls]
<template>
  <v-data-iterator :items="items" class="d-flex justify-center">
    <template v-slot:default="{ items }">
      <template v-for="(item, index) in items" :key="index">
        <div class="item">
          <div class="item-icon">
            <v-icon :size="110" color="primary-violet" :icon="iconMap[materialType] || 'mdi-file-document-outline'"></v-icon>
          </div>
          <div class="item-content">
            <div v-for="(value, key) in item.raw" :key="key" class="item-field">
              <span class="field-label">{{ getFieldLabel(key) }}:</span>
              <span class="field-value">{{ value }}</span>
            </div>
          </div>
        </div>
      </template>
    </template>
  </v-data-iterator>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue';
import axios from 'axios';

const props = defineProps({
  items: Array,
  materialType: String
});

const fields = ref({});

const iconMap = {
  audio: 'mdi-volume-high',
  photo: 'mdi-image-outline',
  video: 'mdi-video-outline'
};

const fetchFieldsMetadata = () => {
  axios.options(`/api/materials/${props.materialType}/`)
    .then(({ data }) => {
      console.log('Fetched metadata:', data);
      fields.value = data.fields || {};
    })
    .catch(error => {
      console.error('Error fetching field metadata:', error);
    });
};

const getFieldLabel = (key) => {
  const label = fields.value[key]?.label || key;
  console.log(`Field: ${key}, Label: ${label}`);
  return label;
};

watch(() => props.materialType, fetchFieldsMetadata);

onMounted(fetchFieldsMetadata);
</script>

<style scoped>
.item {
  width: 900px;
  padding: 15px;
  margin-top: 15px;
  margin-bottom: 15px;
  border: 1px solid darkgray;
  border-radius: 8px;
  display: flex;
  overflow: hidden;
}

.item-icon {
  flex-shrink: 0;
  width: 110px;
}

.item-content {
  flex-grow: 1;
  margin-left: 20px;
  overflow: hidden;
}

.item-field {
  display: flex;
  margin-bottom: 8px;
}

.field-label {
  flex-shrink: 0;
  font-size: 12px;
  font-weight: bold;
  margin-right: 12px;
}

.field-value {
  font-size: 12px;
  font-weight: normal;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis; why this code as if it doesn't see views.py code and dynamically displays my database fields in Russian instead of English, for example id:323901
archive_number:E042831
annotation:Head of the Permanent Mission of the Union State in Minsk V. Shalodonov speaks ...
creation_date:14.12.2004
author:Kholodilin S.
photo_type:ed
color:color. why do I display the word annotation in English if I want to take the word from models.py iso this line annotation = models.TextField(“Аннотация”, blank=True) and display the word Аннотация and not annotation, as well as with all other fields. and is it possible to fix this problem without making changes to serializers.py and models.py?