import os

from rest_framework import serializers
from .models import (AdminMenuGroup, AdminMenuSubGroup, AdminMenuSubGroupDetail,
                     AdminMenuSubUsers, AdminEventLog, AdminEventType, AdminUsers, AdminUserPermission, AdminPositions,
                     AdminRoles, AdminRoleMenus,
                     Genre, Movie, TVShow, Episode, WatchHistory, UserWatchlist, Favorite, Review, SubscriptionPlan,
                     MenuGroup, MenuSubGroup, MenuSubGroupDetail, MenuSubUsers, EventLog, EventType, User, UserPermission, Positions, Roles, RoleMenus,
                     PayrollPeriod, PayrollTransaction, AffordabilityFormula, LoanTransaction, NonDeductionReason)

class AdminMenuGroupSerializer(serializers.ModelSerializer):
    class Meta:
        fields=('id','code','name','description','status','date',)
        model= AdminMenuGroup

class AdminMenuSubGroupSerializer(serializers.ModelSerializer):
    class Meta:
        fields=('id','menugpcode','code','name','namespace','icons','status','date',)
        model= AdminMenuSubGroup

class AdminMenuSubGroupDetailSerializer(serializers.ModelSerializer):
    class Meta:
        fields=('id','menugpcode','menucatcode','code','icons','name','namespace','imageuniname','status','notification','sidebar','dashboard','windview','windviewgeneralreport','windviewfinancialreport','windviewstatisticalreport','admin_accessright','date','targeted','viewer',)
        model= AdminMenuSubGroupDetail

class AdminMenuSubUsersSerializer(serializers.ModelSerializer):
    class Meta:
        fields=('id','usruserid','menudetcode','status','addedby','date',)
        model= AdminMenuSubUsers

class AdminEventLogSerializer(serializers.ModelSerializer):
    class Meta:
        fields='__all__'
        model= AdminEventLog

class AdminEventTypeSerializer(serializers.ModelSerializer):

    class Meta:

        fields='__all__'

        model= AdminEventType



class AdminUsersSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True, required=False)

    class Meta:

        fields= ['id','code','surname','othernames','password','username','startdate','emergencyphone','phoneno','level','passwordchange','organisationcode','organisationname','position','role_code','email','status','actorid','actorname','type','regioncode','regionname','districtcode','districtname','date']

        model= AdminUsers



class AdminUserPermissionSerializer(serializers.ModelSerializer):

    class Meta:

        fields=('id','usruserid','menudetcode','status','addedby','date',)

        model= AdminUserPermission


class AdminPositionsSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ('id', 'name', 'description', 'status', 'date',)
        model = AdminPositions

class AdminRolesSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ('id', 'code', 'name', 'description', 'status', 'date',)
        model = AdminRoles

class AdminRoleMenusSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ('id', 'usruserid', 'menudetcode', 'status', 'addedby', 'date',)
        model = AdminRoleMenus



# ─── User-Facing Serializers (Mirroring Admin) ────────────────────────────────

class MenuGroupSerializer(serializers.ModelSerializer):
    class Meta:
        fields=('id','code','name','description','status','date',)
        model= MenuGroup

class MenuSubGroupSerializer(serializers.ModelSerializer):
    class Meta:
        fields=('id','menugpcode','code','name','namespace','icons','status','date',)
        model= MenuSubGroup

class MenuSubGroupDetailSerializer(serializers.ModelSerializer):
    class Meta:
        fields=('id','menugpcode','menucatcode','code','icons','name','namespace','imageuniname','status','notification','sidebar','dashboard','windview','windviewgeneralreport','windviewfinancialreport','windviewstatisticalreport','admin_accessright','date','targeted','viewer',)
        model= MenuSubGroupDetail

class MenuSubUsersSerializer(serializers.ModelSerializer):
    class Meta:
        fields=('id','usruserid','menudetcode','status','addedby','date',)
        model= MenuSubUsers

class EventLogSerializer(serializers.ModelSerializer):
    class Meta:
        fields='__all__'
        model= EventLog

class EventTypeSerializer(serializers.ModelSerializer):
    class Meta:
        fields='__all__'
        model= EventType

class UserSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True, required=False)

    class Meta:
        fields= ['id','code','surname','othernames','password','username','startdate','emergencyphone','phoneno','level','passwordchange','organisationcode','organisationname','position','role_code','email','status','actorid','actorname','type','regioncode','regionname','districtcode','districtname','date']
        model= User

class UserPermissionSerializer(serializers.ModelSerializer):
    class Meta:
        fields=('id','usruserid','menudetcode','status','addedby','date',)
        model= UserPermission

class PositionsSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ('id', 'name', 'description', 'status', 'date',)
        model = Positions

class RolesSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ('id', 'code', 'name', 'description', 'status', 'date',)
        model = Roles

class RoleMenusSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ('id', 'usruserid', 'menudetcode', 'status', 'addedby', 'date',)
        model = RoleMenus


# ─── Content Serializers ──────────────────────────────────────────────────────

class GenreSerializer(serializers.ModelSerializer):
    movies_count = serializers.IntegerField(source='movies.count', read_only=True)
    tv_shows_count = serializers.IntegerField(source='tv_shows.count', read_only=True)

    class Meta:
        fields = '__all__'
        model = Genre


class MovieSerializer(serializers.ModelSerializer):
    genres = serializers.StringRelatedField(many=True, read_only=True)
    genre_ids = serializers.PrimaryKeyRelatedField(
        many=True, queryset=Genre.objects.all(), write_only=True,
        source='genres', required=False
    )
    video_file = serializers.FileField(write_only=True, required=False, allow_null=True)
    hls_playlist = serializers.FileField(write_only=True, required=False, allow_null=True)
    video_url = serializers.SerializerMethodField()
    trailer_url = serializers.SerializerMethodField()
    release_year = serializers.SerializerMethodField()
    has_video = serializers.SerializerMethodField()
    has_hls = serializers.SerializerMethodField()
    release_date = serializers.DateField(required=False, allow_null=True, default=None)
    duration = serializers.IntegerField(required=False, allow_null=True, default=None)

    class Meta:
        model = Movie
        fields = [
            'id', 'title', 'description', 'release_date', 'release_year',
            'duration', 'poster', 'backdrop', 'trailer_file', 'trailer_url',
            'video_file', 'video_url', 'has_video', 'transcoding_status',
            'hls_playlist', 'has_hls', 'rating', 'genres', 'genre_ids', 'director', 'cast',
            'imdb_rating', 'rotten_tomatoes_score', 'is_featured', 'is_active',
            'views_count', 'likes_count', 'created_at', 'updated_at',
        ]

    def get_video_url(self, obj):
        return None

    def get_trailer_url(self, obj):
        if obj.trailer_file:
            request = self.context.get('request')
            if request:
                return request.build_absolute_uri(obj.trailer_file.url)
            return obj.trailer_file.url
        return None

    def get_release_year(self, obj):
        return obj.release_date.year if obj.release_date else None

    def get_has_video(self, obj):
        return bool(obj.video_file and obj.video_file.name)

    def get_has_hls(self, obj):
        if not (obj.hls_playlist and obj.hls_playlist.name):
            return False
        try:
            return os.path.exists(obj.hls_playlist.path)
        except (NotImplementedError, ValueError):
            return bool(obj.hls_playlist.name)


class TVShowSerializer(serializers.ModelSerializer):
    genres = serializers.StringRelatedField(many=True, read_only=True)
    genre_ids = serializers.PrimaryKeyRelatedField(
        many=True, queryset=Genre.objects.all(), write_only=True,
        source='genres', required=False
    )
    seasons = serializers.IntegerField(source='seasons_count', read_only=True)
    episodes = serializers.IntegerField(source='episodes_count', read_only=True)
    director = serializers.CharField(source='creator', read_only=True)
    release_year = serializers.SerializerMethodField()
    release_date = serializers.DateField(required=False, allow_null=True, default=None)

    class Meta:
        model = TVShow
        fields = [
            'id', 'title', 'description', 'release_date', 'release_year', 'end_date',
            'poster', 'trailer_url', 'genres', 'genre_ids', 'creator', 'director', 'cast',
            'imdb_rating', 'rotten_tomatoes_score', 'seasons_count', 'seasons',
            'episodes_count', 'episodes', 'is_featured', 'is_active', 'is_ongoing',
            'views_count', 'likes_count', 'created_at', 'updated_at',
        ]

    def get_release_year(self, obj):
        return obj.release_date.year if obj.release_date else None


class EpisodeSerializer(serializers.ModelSerializer):
    video_file = serializers.FileField(write_only=True, required=False, allow_null=True)
    hls_playlist = serializers.FileField(write_only=True, required=False, allow_null=True)
    video_url = serializers.SerializerMethodField()
    thumbnail_url = serializers.SerializerMethodField()
    has_video = serializers.SerializerMethodField()
    has_hls = serializers.SerializerMethodField()
    duration = serializers.IntegerField(required=False, allow_null=True, default=None)
    air_date = serializers.DateField(required=False, allow_null=True, default=None)

    class Meta:
        model = Episode
        fields = [
            'id', 'tv_show', 'season_number', 'episode_number', 'title',
            'description', 'duration', 'air_date', 'video_file', 'video_url',
            'has_video', 'transcoding_status', 'hls_playlist', 'has_hls', 'thumbnail', 'thumbnail_url', 'views_count', 'created_at', 'updated_at',
        ]

    def get_video_url(self, obj):
        return None

    def get_has_video(self, obj):
        return bool(obj.video_file and obj.video_file.name)

    def get_has_hls(self, obj):
        if not (obj.hls_playlist and obj.hls_playlist.name):
            return False
        try:
            return os.path.exists(obj.hls_playlist.path)
        except (NotImplementedError, ValueError):
            return bool(obj.hls_playlist.name)

    def get_thumbnail_url(self, obj):
        if obj.thumbnail:
            request = self.context.get('request')
            if request:
                return request.build_absolute_uri(obj.thumbnail.url)
            return obj.thumbnail.url
        return None


class WatchHistorySerializer(serializers.ModelSerializer):
    movie_details = MovieSerializer(source='movie', read_only=True)
    episode_details = EpisodeSerializer(source='episode', read_only=True)
    content_title = serializers.SerializerMethodField()
    content_type = serializers.SerializerMethodField()

    class Meta:
        fields = '__all__'
        model = WatchHistory

    def get_content_title(self, obj):
        if obj.movie:
            return obj.movie.title
        if obj.episode:
            return obj.episode.title
        return ''

    def get_content_type(self, obj):
        if obj.movie:
            return 'movie'
        if obj.episode:
            return 'episode'
        return ''


class UserWatchlistSerializer(serializers.ModelSerializer):
    user = serializers.CharField(read_only=True)
    movie_details = MovieSerializer(source='movie', read_only=True)
    tv_show_details = TVShowSerializer(source='tv_show', read_only=True)
    content_title = serializers.SerializerMethodField()
    content_type = serializers.SerializerMethodField()

    class Meta:
        fields = '__all__'
        model = UserWatchlist

    def get_content_title(self, obj):
        if obj.movie:
            return obj.movie.title
        if obj.tv_show:
            return obj.tv_show.title
        return ''

    def get_content_type(self, obj):
        if obj.movie:
            return 'movie'
        if obj.tv_show:
            return 'tv_show'
        return ''


class FavoriteSerializer(serializers.ModelSerializer):
    user = serializers.CharField(read_only=True)
    class Meta:
        fields = '__all__'
        model = Favorite


class ReviewSerializer(serializers.ModelSerializer):
    user = serializers.CharField(read_only=True)
    user_name = serializers.CharField(source='user', read_only=True)
    content_title = serializers.SerializerMethodField()
    content_type = serializers.SerializerMethodField()

    class Meta:
        fields = '__all__'
        model = Review

    def get_content_title(self, obj):
        if obj.movie:
            return obj.movie.title
        if obj.tv_show:
            return obj.tv_show.title
        return ""

    def get_content_type(self, obj):
        if obj.movie:
            return "movie"
        if obj.tv_show:
            return "tvshow"
        return ""


# ─────────────────────────────────────────────
#  PAYROLL & AFFORDABILITY SERIALIZERS
# ─────────────────────────────────────────────

class PayrollPeriodSerializer(serializers.ModelSerializer):
    class Meta:
        fields = '__all__'
        model = PayrollPeriod


class PayrollTransactionSerializer(serializers.ModelSerializer):
    class Meta:
        fields = '__all__'
        model = PayrollTransaction


class AffordabilityFormulaSerializer(serializers.ModelSerializer):
    class Meta:
        fields = '__all__'
        model = AffordabilityFormula


class LoanTransactionSerializer(serializers.ModelSerializer):
    class Meta:
        fields = '__all__'
        model = LoanTransaction


class NonDeductionReasonSerializer(serializers.ModelSerializer):
    class Meta:
        fields = '__all__'
        model = NonDeductionReason


class SubscriptionPlanSerializer(serializers.ModelSerializer):
    price_display = serializers.SerializerMethodField()

    class Meta:
        fields = '__all__'
        model = SubscriptionPlan

    def get_price_display(self, obj):
        return f"GHS {obj.price}{obj.period}"
