from rest_framework import generics, status, permissions
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework_simplejwt.views import TokenRefreshView
from django.contrib.auth import update_session_auth_hash
from .models import User, SiteConfiguration
from .serializers import (
    UserSerializer, UserDetailSerializer, UserCreateSerializer,
    UserUpdateSerializer, LoginSerializer, PasswordChangeSerializer,
    ProfileSerializer, SiteConfigurationSerializer
)
from .permissions import CanManageUsers, CanViewFinance


def api_response(data=None, message='', errors=None, status_code=status.HTTP_200_OK):
    """Standard API response format"""
    return Response({
        'status': 'success' if status_code < 400 else 'error',
        'data': data,
        'message': message,
        'errors': errors
    }, status=status_code)


class LoginView(APIView):
    permission_classes = [permissions.AllowAny]

    def post(self, request):
        serializer = LoginSerializer(data=request.data)
        if not serializer.is_valid():
            return api_response(
                errors=serializer.errors,
                message='Login failed',
                status_code=status.HTTP_400_BAD_REQUEST
            )
        user = serializer.validated_data['user']
        refresh = RefreshToken.for_user(user)
        return api_response(
            data={
                'access': str(refresh.access_token),
                'refresh': str(refresh),
                'user': UserSerializer(user).data,
                'force_password_change': user.force_password_change
            },
            message='Login successful'
        )


class LogoutView(APIView):
    def post(self, request):
        try:
            refresh_token = request.data.get('refresh')
            if refresh_token:
                token = RefreshToken(refresh_token)
                token.blacklist()
            return api_response(message='Logout successful')
        except Exception:
            return api_response(message='Logout successful')


class ProfileView(APIView):
    def get(self, request):
        serializer = ProfileSerializer(request.user)
        return api_response(data=serializer.data)

    def patch(self, request):
        serializer = ProfileSerializer(request.user, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return api_response(data=serializer.data, message='Profile updated')
        return api_response(
            errors=serializer.errors,
            message='Update failed',
            status_code=status.HTTP_400_BAD_REQUEST
        )


class PasswordChangeView(APIView):
    def post(self, request):
        serializer = PasswordChangeSerializer(data=request.data)
        if not serializer.is_valid():
            return api_response(
                errors=serializer.errors,
                message='Validation error',
                status_code=status.HTTP_400_BAD_REQUEST
            )

        user = request.user
        if not user.check_password(serializer.validated_data['old_password']):
            return api_response(
                errors={'old_password': ['Incorrect current password']},
                message='Password change failed',
                status_code=status.HTTP_400_BAD_REQUEST
            )

        user.set_password(serializer.validated_data['new_password'])
        user.force_password_change = False
        user.save()
        update_session_auth_hash(request, user)
        return api_response(message='Password changed successfully')


class UserListCreateView(APIView):
    permission_classes = [permissions.IsAuthenticated, CanManageUsers]

    def get(self, request):
        users = User.objects.all()

        # Filters
        role = request.query_params.get('role')
        department = request.query_params.get('department')
        is_active = request.query_params.get('is_active')
        search = request.query_params.get('search')

        if role:
            users = users.filter(roles__name=role)
        if department:
            users = users.filter(department=department)
        if is_active is not None:
            users = users.filter(is_active=is_active.lower() == 'true')
        if search:
            users = users.filter(full_name__icontains=search)

        # If requester can view finance data, show salary info
        if request.user.has_role('CEO', 'HR', 'Finance'):
            serializer = UserDetailSerializer(users, many=True)
        else:
            serializer = UserSerializer(users, many=True)

        return api_response(data=serializer.data)

    def post(self, request):
        serializer = UserCreateSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.save()
            return api_response(
                data=UserDetailSerializer(user).data,
                message='User created successfully',
                status_code=status.HTTP_201_CREATED
            )
        return api_response(
            errors=serializer.errors,
            message='User creation failed',
            status_code=status.HTTP_400_BAD_REQUEST
        )


class UserDetailView(APIView):
    permission_classes = [permissions.IsAuthenticated, CanManageUsers]

    def get_object(self, pk):
        try:
            return User.objects.get(pk=pk)
        except User.DoesNotExist:
            return None

    def get(self, request, pk):
        user = self.get_object(pk)
        if not user:
            return api_response(
                message='User not found',
                status_code=status.HTTP_404_NOT_FOUND
            )
        if request.user.has_role('CEO', 'HR', 'Finance'):
            serializer = UserDetailSerializer(user)
        else:
            serializer = UserSerializer(user)
        return api_response(data=serializer.data)

    def patch(self, request, pk):
        user = self.get_object(pk)
        if not user:
            return api_response(
                message='User not found',
                status_code=status.HTTP_404_NOT_FOUND
            )
        serializer = UserUpdateSerializer(user, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return api_response(
                data=UserDetailSerializer(user).data,
                message='User updated successfully'
            )
        return api_response(
            errors=serializer.errors,
            message='Update failed',
            status_code=status.HTTP_400_BAD_REQUEST
        )

    def delete(self, request, pk):
        """Soft delete — deactivate user"""
        user = self.get_object(pk)
        if not user:
            return api_response(
                message='User not found',
                status_code=status.HTTP_404_NOT_FOUND
            )
        user.is_active = False
        user.save()
        return api_response(message='User deactivated successfully')


class TeamListView(APIView):
    """Public list of active team members (no salary info)"""
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        users = User.objects.filter(is_active=True)
        department = request.query_params.get('department')
        role = request.query_params.get('role')
        if department:
            users = users.filter(department=department)
        if role:
            users = users.filter(roles__name=role)
        serializer = UserSerializer(users, many=True)
        return api_response(data=serializer.data)


class TeamMemberRatesView(APIView):
    """Return team members with hourly rates — for costing calculator (PM/CEO only)"""
    permission_classes = [permissions.IsAuthenticated, CanViewFinance]

    def get(self, request):
        users = User.objects.filter(is_active=True)
        data = []
        for user in users:
            data.append({
                'id': user.id,
                'full_name': user.full_name,
                'role': user.roles.first().name if user.roles.exists() else 'Member',
                'department': user.department,
                'hourly_rate': str(user.hourly_rate),
                'initials': user.initials
            })
        return api_response(data=data)

class SiteSettingsView(APIView):
    permission_classes = [permissions.AllowAny]

    def get(self, request):
        config = SiteConfiguration.get_settings()
        serializer = SiteConfigurationSerializer(config, context={'request': request})
        return api_response(data=serializer.data)
