from rest_framework import serializers

from .models import PipelineStage, JobApplication, InterviewFeedback, InterviewSchedule, PipelineLog


class InterviewFeedbackSerializer(serializers.ModelSerializer):
    recommendation_label = serializers.CharField(source="get_recommendation_display", read_only=True)
    by = serializers.SerializerMethodField()

    class Meta:
        model = InterviewFeedback
        fields = ["id", "application", "round", "interviewer", "scores", "overall_score",
                  "strengths", "weaknesses", "recommendation", "recommendation_label",
                  "notes", "by", "created_at"]
        read_only_fields = ["id", "by", "created_at"]

    def get_by(self, obj):
        u = obj.created_by
        return (u.full_name or u.email) if u else None


class InterviewScheduleSerializer(serializers.ModelSerializer):
    status_label = serializers.CharField(source="get_status_display", read_only=True)
    candidate_name = serializers.SerializerMethodField()

    class Meta:
        model = InterviewSchedule
        fields = ["id", "application", "candidate_name", "round", "interviewer", "interviewer_email",
                  "scheduled_at", "duration_minutes", "location", "status", "status_label",
                  "reason", "created_at", "updated_at"]
        read_only_fields = ["id", "candidate_name", "created_at", "updated_at"]

    def get_candidate_name(self, obj):
        c = obj.application.candidate
        return f"{c.first_name} {c.last_name}".strip()


class PipelineStageSerializer(serializers.ModelSerializer):
    outcome_label = serializers.CharField(source="get_outcome_display", read_only=True)

    class Meta:
        model = PipelineStage
        fields = ["id", "name", "code", "sort_order", "outcome", "outcome_label", "is_active"]


class JobApplicationSerializer(serializers.ModelSerializer):
    candidate_name = serializers.SerializerMethodField()
    job_title = serializers.CharField(source="job.title", read_only=True)
    job_client = serializers.CharField(source="job.client.name", read_only=True, default=None)
    job_status = serializers.CharField(source="job.status", read_only=True)
    added_by = serializers.CharField(source="created_by.email", read_only=True, default=None)
    added_by_name = serializers.SerializerMethodField()
    added_by_email = serializers.CharField(source="created_by.email", read_only=True, default=None)
    stage_name = serializers.CharField(source="stage.name", read_only=True)
    stage_code = serializers.CharField(source="stage.code", read_only=True)
    stage_outcome = serializers.CharField(source="stage.outcome", read_only=True)
    round1_outcome_label = serializers.CharField(source="get_round1_outcome_display", read_only=True)
    candidate_first_name = serializers.CharField(source="candidate.first_name", read_only=True, default="")
    candidate_last_name = serializers.CharField(source="candidate.last_name", read_only=True, default="")
    candidate_source = serializers.CharField(source="candidate.source", read_only=True, default="OTHER")
    candidate_location = serializers.SerializerMethodField()
    self_applied = serializers.SerializerMethodField()
    job_owner_name = serializers.SerializerMethodField()
    job_owner_email = serializers.CharField(source="job.created_by.email", read_only=True, default=None)

    def get_job_owner_name(self, obj):
        u = obj.job.created_by if (obj.job and obj.job.created_by) else None
        if not u:
            return "—"
        return u.full_name or u.email

    def get_added_by_name(self, obj):
        u = obj.created_by
        if not u:
            return "System"
        return u.full_name or u.email

    def get_candidate_name(self, obj):
        c = obj.candidate
        return f"{c.first_name} {c.last_name}".strip()

    def get_candidate_location(self, obj):
        c = obj.candidate
        return c.current_location or c.city or c.state or ""

    def get_self_applied(self, obj):
        c = obj.candidate
        return bool(obj.created_by_id and c.user_id and obj.created_by_id == c.user_id)

    class Meta:
        model = JobApplication
        fields = [
            "id", "candidate", "candidate_name", "candidate_first_name", "candidate_last_name", "candidate_source",
            "candidate_location", "job", "job_title", "job_client", "job_status", "job_owner_name", "job_owner_email",
            "stage", "stage_name", "stage_code", "stage_outcome", "added_by", "added_by_name", "added_by_email", "self_applied",
            "interviewer", "interview_date", "interview_result", "remark", "activity", "score",
            "round1_outcome", "round1_outcome_label", "screening_answers",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]

    def create(self, validated_data):
        # default the stage to the first active stage ("Contacted") when not given
        if not validated_data.get("stage"):
            validated_data["stage"] = PipelineStage.objects.filter(is_active=True).order_by("sort_order", "id").first()
        return super().create(validated_data)


class PipelineLogSerializer(serializers.ModelSerializer):
    performed_by_name = serializers.SerializerMethodField()
    job_title = serializers.CharField(source="job.title", read_only=True)

    class Meta:
        model = PipelineLog
        fields = [
            "id", "application", "candidate", "job", "job_title",
            "performed_by", "performed_by_name", "status_name", "activity",
            "remark", "changes_summary", "created_at"
        ]
        read_only_fields = ["id", "created_at"]

    def get_performed_by_name(self, obj):
        u = obj.performed_by
        if not u:
            return "System"
        return u.full_name or u.email
