"""
API для запросов на менторство. Студент отправляет запрос по коду ментора,
ментор принимает или отклоняет.
"""
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from django.core.cache import cache

from .models import User, Client, MentorStudentConnection
from apps.notifications.services import NotificationService
from apps.board.models import Board


def _apply_connection(conn):
    """После принятия связи: добавить ментора к студенту, создать доску."""
    student_user = conn.student
    mentor = conn.mentor
    try:
        client = student_user.client_profile
    except Client.DoesNotExist:
        client = Client.objects.create(user=student_user)
    if mentor not in client.mentors.all():
        client.mentors.add(mentor)
    board, _ = Board.objects.get_or_create(
        mentor=mentor,
        student=student_user,
        access_type='mentor_student',
        defaults={
            'title': 'Доска для совместной работы',
            'description': f'Интерактивная доска для {student_user.get_full_name()}',
            'owner': mentor,
        }
    )
    if board:
        board.participants.add(mentor, student_user)
    if conn.status != MentorStudentConnection.STATUS_ACCEPTED:
        conn.status = MentorStudentConnection.STATUS_ACCEPTED
        conn.save(update_fields=['status', 'updated_at'])


class MentorshipRequestViewSet(viewsets.ViewSet):
    """
    Запросы на менторство: студент отправляет по коду ментора, ментор принимает/отклоняет.
    
    send: POST - студент отправляет запрос (mentor_code)
    pending: GET - ментор получает список ожидающих запросов
    accept: POST - ментор принимает
    reject: POST - ментор отклоняет
    my_requests: GET - студент получает свои отправленные запросы
    """
    permission_classes = [IsAuthenticated]

    @action(detail=False, methods=['post'])
    def send(self, request):
        """
        Студент отправляет запрос на менторство по коду ментора.
        POST /api/mentorship-requests/send/  Body: { "mentor_code": "ABC12345" }
        """
        user = request.user
        if user.role != 'client':
            return Response(
                {'error': 'Только для учеников'},
                status=status.HTTP_403_FORBIDDEN
            )
        mentor_code = (request.data.get('mentor_code') or request.data.get('mentorCode') or '').strip().upper()
        if not mentor_code:
            return Response(
                {'error': 'Укажите код ментора'},
                status=status.HTTP_400_BAD_REQUEST
            )
        allowed = set('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
        valid = len(mentor_code) == 8 and all(c in allowed for c in mentor_code)
        if not valid:
            return Response(
                {'error': 'Код ментора: 8 символов (цифры и латинские буквы)'},
                status=status.HTTP_400_BAD_REQUEST
            )
        try:
            mentor = User.objects.get(universal_code=mentor_code, role='mentor')
        except User.DoesNotExist:
            return Response(
                {'error': 'Ментор с таким кодом не найден'},
                status=status.HTTP_404_NOT_FOUND
            )
        # Проверка: уже студент этого ментора
        try:
            client = user.client_profile
        except Client.DoesNotExist:
            client = Client.objects.create(user=user)
        if mentor in client.mentors.all():
            return Response(
                {'error': 'Вы уже являетесь учеником этого ментора'},
                status=status.HTTP_400_BAD_REQUEST
            )
        # Проверка: есть ли уже ожидающий запрос
        pending = MentorStudentConnection.objects.filter(
            student=user,
            mentor=mentor,
            status=MentorStudentConnection.STATUS_PENDING_MENTOR,
        ).exists()
        if pending:
            return Response(
                {'error': 'Запрос уже отправлен, ожидайте ответа ментора'},
                status=status.HTTP_400_BAD_REQUEST
            )
        conn = MentorStudentConnection.objects.create(
            student=user,
            mentor=mentor,
            status=MentorStudentConnection.STATUS_PENDING_MENTOR,
            initiator=MentorStudentConnection.INITIATOR_STUDENT,
        )
        # Уведомление ментору (in-app, email, telegram)
        NotificationService.create_notification_with_telegram(
            recipient=mentor,
            notification_type='mentorship_request_new',
            title='Новый запрос на менторство',
            message=f'{user.get_full_name() or user.email} отправил(а) запрос на связь с вами.',
            action_url='/students?tab=requests',
            data={'mentorship_request_id': conn.id, 'connection_id': conn.id},
        )
        return Response({
            'id': conn.id,
            'status': conn.status,
            'mentor': {
                'id': mentor.id,
                'first_name': mentor.first_name,
                'last_name': mentor.last_name,
                'email': mentor.email,
            },
            'message': 'Запрос отправлен. Ожидайте ответа ментора.',
        }, status=status.HTTP_201_CREATED)

    @action(detail=False, methods=['get'])
    def pending(self, request):
        """
        Ментор получает список ожидающих запросов.
        GET /api/mentorship-requests/pending/
        """
        user = request.user
        if user.role != 'mentor':
            return Response(
                {'error': 'Только для менторов'},
                status=status.HTTP_403_FORBIDDEN
            )
        conns = MentorStudentConnection.objects.filter(
            mentor=user,
            status=MentorStudentConnection.STATUS_PENDING_MENTOR,
            initiator=MentorStudentConnection.INITIATOR_STUDENT,
        ).select_related('student').order_by('-created_at')
        data = []
        for req in conns:
            try:
                client_id = req.student.client_profile.id
            except Client.DoesNotExist:
                client_id = None
            data.append({
                'id': req.id,
                'status': req.status,
                'created_at': req.created_at.isoformat() if req.created_at else None,
                'student': {
                    'id': client_id,
                    'user_id': req.student.id,
                    'email': req.student.email,
                    'first_name': req.student.first_name or '',
                    'last_name': req.student.last_name or '',
                    'avatar': req.student.avatar.url if req.student.avatar else None,
                },
            })
        return Response(data)

    @action(detail=True, methods=['post'])
    def accept(self, request, pk=None):
        """
        Ментор принимает запрос.
        POST /api/mentorship-requests/{id}/accept/
        """
        user = request.user
        if user.role != 'mentor':
            return Response(
                {'error': 'Только для менторов'},
                status=status.HTTP_403_FORBIDDEN
            )
        try:
            req = MentorStudentConnection.objects.select_related('student', 'mentor').get(
                id=pk,
                mentor=user,
                status=MentorStudentConnection.STATUS_PENDING_MENTOR,
                initiator=MentorStudentConnection.INITIATOR_STUDENT,
            )
        except MentorStudentConnection.DoesNotExist:
            return Response(
                {'error': 'Запрос не найден или уже обработан'},
                status=status.HTTP_404_NOT_FOUND
            )
        req.status = MentorStudentConnection.STATUS_ACCEPTED
        req.save(update_fields=['status', 'updated_at'])
        _apply_connection(req)
        # Уведомление студенту (in-app, email, telegram)
        NotificationService.create_notification_with_telegram(
            recipient=req.student,
            notification_type='mentorship_request_accepted',
            title='Запрос на менторство принят',
            message=f'{user.get_full_name() or user.email} принял(а) ваш запрос на связь.',
            action_url='/request-mentor',
            data={'mentorship_request_id': req.id, 'connection_id': req.id},
        )
        # Инвалидация кеша списка клиентов
        for page in range(1, 10):
            for size in [10, 20, 50, 100, 1000]:
                cache.delete(f'manage_clients_{user.id}_{page}_{size}')
        return Response({
            'status': 'accepted',
            'message': 'Запрос принят. Студент добавлен в ваш список.',
        })

    @action(detail=True, methods=['post'])
    def reject(self, request, pk=None):
        """
        Ментор отклоняет запрос. Студент сможет отправить запрос повторно.
        POST /api/mentorship-requests/{id}/reject/
        """
        user = request.user
        if user.role != 'mentor':
            return Response(
                {'error': 'Только для менторов'},
                status=status.HTTP_403_FORBIDDEN
            )
        try:
            req = MentorStudentConnection.objects.select_related('student').get(
                id=pk,
                mentor=user,
                status=MentorStudentConnection.STATUS_PENDING_MENTOR,
                initiator=MentorStudentConnection.INITIATOR_STUDENT,
            )
        except MentorStudentConnection.DoesNotExist:
            return Response(
                {'error': 'Запрос не найден или уже обработан'},
                status=status.HTTP_404_NOT_FOUND
            )
        req.status = MentorStudentConnection.STATUS_REJECTED
        req.save(update_fields=['status', 'updated_at'])
        # Уведомление студенту (in-app, email, telegram)
        NotificationService.create_notification_with_telegram(
            recipient=req.student,
            notification_type='mentorship_request_rejected',
            title='Запрос на менторство отклонён',
            message=f'{user.get_full_name() or user.email} отклонил(а) ваш запрос на связь. Вы можете отправить запрос повторно.',
            action_url='/request-mentor',
            data={'mentorship_request_id': req.id},
        )
        return Response({
            'status': 'rejected',
            'message': 'Запрос отклонён.',
        })

    @action(detail=False, methods=['get'], url_path='my-requests')
    def my_requests(self, request):
        """
        Студент получает список своих отправленных запросов.
        Не показывает менторов, от которых студент отключён (связь убрана в админке).
        GET /api/mentorship-requests/my-requests/
        """
        user = request.user
        if user.role != 'client':
            return Response(
                {'error': 'Только для учеников'},
                status=status.HTTP_403_FORBIDDEN
            )
        conns = MentorStudentConnection.objects.filter(
            student=user,
            initiator=MentorStudentConnection.INITIATOR_STUDENT,
        ).select_related('mentor').order_by('-created_at')[:50]
        try:
            client = user.client_profile
            mentor_ids = set(client.mentors.values_list('id', flat=True))
        except Client.DoesNotExist:
            mentor_ids = set()
        data = []
        for req in conns:
            if req.status == MentorStudentConnection.STATUS_ACCEPTED and req.mentor_id not in mentor_ids:
                continue
            data.append({
                'id': req.id,
                'status': req.status,
                'created_at': req.created_at.isoformat() if req.created_at else None,
                'updated_at': req.updated_at.isoformat() if req.updated_at else None,
                'mentor': {
                    'id': req.mentor.id,
                    'email': req.mentor.email,
                    'first_name': req.mentor.first_name,
                    'last_name': req.mentor.last_name,
                },
            })
        return Response(data)

    @action(detail=False, methods=['get'], url_path='my-mentors')
    def my_mentors(self, request):
        """
        Список менторов студента (из client.mentors).
        Включает менторов, подключённых через приглашение или принятый запрос.
        GET /api/mentorship-requests/my-mentors/
        """
        user = request.user
        if user.role != 'client':
            return Response(
                {'error': 'Только для учеников'},
                status=status.HTTP_403_FORBIDDEN
            )
        try:
            client = user.client_profile
            mentors = client.mentors.all().order_by('first_name', 'last_name')
        except Client.DoesNotExist:
            mentors = []
        data = [
            {
                'id': m.id,
                'email': m.email,
                'first_name': m.first_name,
                'last_name': m.last_name,
                'avatar_url': request.build_absolute_uri(m.avatar.url) if m.avatar else None,
            }
            for m in mentors
        ]
        return Response(data)
