from rest_framework import serializers
from .models import Project, ProjectMember, ProjectAttachment, ProjectStageLog
from apps.users.serializers import UserSerializer


class ProjectStageLogSerializer(serializers.ModelSerializer):
    changed_by_name = serializers.CharField(source='changed_by.full_name', read_only=True)
    
    class Meta:
        model = ProjectStageLog
        fields = ['id', 'from_stage', 'to_stage', 'note', 'changed_by_name', 'timestamp']


class ProjectMemberSerializer(serializers.ModelSerializer):
    user_name = serializers.CharField(source='user.full_name', read_only=True)
    user_initials = serializers.SerializerMethodField()

    class Meta:
        model = ProjectMember
        fields = ['id', 'user', 'user_name', 'user_initials', 'role_on_project', 'hourly_rate_snapshot']
        read_only_fields = ['hourly_rate_snapshot']

    def get_user_initials(self, obj):
        if obj.user.full_name:
            return ''.join(n[0] for n in obj.user.full_name.split()[:2]).upper()
        return '?'


class ProjectListSerializer(serializers.ModelSerializer):
    pm_name = serializers.CharField(source='pm.full_name', read_only=True)
    client_email = serializers.SerializerMethodField()
    team_count = serializers.SerializerMethodField()
    progress = serializers.SerializerMethodField()
    tasks_total = serializers.SerializerMethodField()
    tasks_done = serializers.SerializerMethodField()

    class Meta:
        model = Project
        fields = [
            'id', 'name', 'client_name', 'client_email', 'service_type', 'pm', 'pm_name',
            'status', 'stage', 'approved_budget', 'estimated_cost', 'actual_cost',
            'expected_end_date', 'team_count', 'progress', 'tasks_total', 'tasks_done'
        ]

    def get_client_email(self, obj):
        return obj.lead.client_email if obj.lead else ''

    def get_team_count(self, obj):
        return obj.members.count()

    def get_progress(self, obj):
        # A simple conceptual calculation based on tasks if tasks existed, but we'll mock it or use an actual logic
        tasks = getattr(obj, 'tasks', None)
        if tasks:
            total = tasks.count()
            if total > 0:
                done = tasks.filter(status__in=['Done', 'Verified']).count()
                return int((done / total) * 100)
        return 0

    def get_tasks_total(self, obj):
        tasks = getattr(obj, 'tasks', None)
        return tasks.count() if tasks else 0

    def get_tasks_done(self, obj):
        tasks = getattr(obj, 'tasks', None)
        return tasks.filter(status__in=['Done', 'Verified']).count() if tasks else 0


class ProjectDetailSerializer(serializers.ModelSerializer):
    pm_name = serializers.CharField(source='pm.full_name', read_only=True)
    members = ProjectMemberSerializer(many=True, read_only=True)
    stage_logs = ProjectStageLogSerializer(many=True, read_only=True)
    progress = serializers.SerializerMethodField()
    actual_cost = serializers.SerializerMethodField()
    tasks_count = serializers.SerializerMethodField()
    
    class Meta:
        model = Project
        fields = '__all__'

    def get_progress(self, obj):
        tasks = obj.tasks.all()
        if not tasks: return 0
        done = tasks.filter(status__in=['Done', 'Verified']).count()
        return int((done / tasks.count()) * 100)

    def get_actual_cost(self, obj):
        # Calculate from TimeLogs and hourly_rate_snapshot or user rates
        total = 0
        for task in obj.tasks.all():
            for log in task.time_logs.all():
                # We prioritize the member snapshot if available
                member = obj.members.filter(user=log.user).first()
                rate = member.hourly_rate_snapshot if member else log.user.hourly_rate
                total += log.hours * rate
        return total

    def get_tasks_count(self, obj):
        return {
            'total': obj.tasks.count(),
            'done': obj.tasks.filter(status__in=['Done', 'Verified']).count(),
            'todo': obj.tasks.filter(status='To_Do').count(),
            'in_progress': obj.tasks.filter(status='In_Progress').count(),
        }


class ProjectCreateSerializer(serializers.ModelSerializer):
    """Simplified for initial creation"""
    class Meta:
        model = Project
        fields = [
            'name', 'client_name', 'service_type', 'pm',
            'approved_budget', 'start_date', 'expected_end_date'
        ]

    def create(self, validated_data):
        # Default status/stage are set in model defaults
        return super().create(validated_data)
