from rest_framework import serializers, status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from basic_info import models as basic_models
from basic_info.models import FrontendPage, FrontendPageTypeEnum


class CustomerEmployeeBindingSerializer(serializers.Serializer):
    """客户员工绑定序列化器"""
    customer_name = serializers.CharField(max_length=100, help_text='客户名称')
    employee_name = serializers.CharField(max_length=100, help_text='员工姓名')


class CustomerEmployeeBindingView(APIView):
    """
    客户员工可见性绑定 API
    
    将指定员工添加到指定客户的可见员工列表中。
    
    POST /api/v2/customers/bind-employee/
    """
    
    permission_classes = [IsAuthenticated]
    
    def post(self, request):
        serializer = CustomerEmployeeBindingSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        
        employee_name = serializer.validated_data['employee_name']
        customer_name = serializer.validated_data['customer_name']
        
        # 查询员工
        employees = basic_models.Employee.objects.filter(name=employee_name)
        if employees.count() == 0:
            return Response(
                {'error': f'未找到名为 "{employee_name}" 的员工'},
                status=status.HTTP_400_BAD_REQUEST
            )
        if employees.count() > 1:
            return Response(
                {'error': f'找到多个名为 "{employee_name}" 的员工（{employees.count()} 个），请使用更精确的标识'},
                status=status.HTTP_403_FORBIDDEN
            )
        
        # 查询客户
        customers = basic_models.Customer.objects.filter(name=customer_name)
        if customers.count() == 0:
            return Response(
                {'error': f'未找到名为 "{customer_name}" 的客户'},
                status=status.HTTP_400_BAD_REQUEST
            )
        if customers.count() > 1:
            return Response(
                {'error': f'找到多个名为 "{customer_name}" 的客户（{customers.count()} 个），请使用更精确的标识'},
                status=status.HTTP_403_FORBIDDEN
            )
        
        # 建立绑定关系
        employee = employees.first()
        customer = customers.first()
        
        # 检查是否已经绑定
        if customer.visible_employees.filter(id=employee.id).exists():
            return Response(
                {
                    'message': f'员工 "{employee_name}" 已在客户 "{customer_name}" 的可见列表中',
                    'customer_id': customer.id,
                    'employee_id': employee.id,
                },
                status=status.HTTP_200_OK
            )
        
        # 添加绑定
        customer.visible_employees.add(employee)
        
        return Response(
            {
                'message': f'成功将员工 "{employee_name}" 添加到客户 "{customer_name}" 的可见列表',
                'customer_id': customer.id,
                'customer_name': customer.name,
                'employee_id': employee.id,
                'employee_name': employee.name,
            },
            status=status.HTTP_201_CREATED
        )


class FrontendPageSerializer(serializers.ModelSerializer):
    """前端页面序列化器"""
    parent_key = serializers.CharField(source='parent.key', read_only=True, allow_null=True)
    
    class Meta:
        model = FrontendPage
        fields = ['key', 'label', 'page_type', 'parent_key', 'sort_order']


class MyVisiblePagesView(APIView):
    """
    获取当前登录用户的可见页面 API
    
    根据当前登录用户关联的员工岗位，返回其可见的前端页面列表。
    授予主菜单会自动包含其所有子菜单。
    
    GET /api/v2/me/visible-pages/
    
    响应示例:
    {
        "employee_id": 1,
        "employee_name": "张三",
        "position_id": 2,
        "position_title": "生产主管",
        "visible_pages": [
            {"key": "production", "label": "生产管理", "page_type": "main", "parent_key": null, "sort_order": 100},
            {"key": "production-kanban", "label": "生产看板", "page_type": "sub", "parent_key": "production", "sort_order": 101}
        ],
        "visible_keys": ["production", "production-kanban", "printing-order-list"]
    }
    """
    
    permission_classes = [IsAuthenticated]
    
    def get(self, request):
        # 从 request.user 获取关联的员工
        user = request.user
        
        # 检查用户是否关联员工
        if not hasattr(user, 'employee'):
            return Response({
                'employee_id': None,
                'employee_name': None,
                'position_id': None,
                'position_title': None,
                'visible_pages': [],
                'visible_keys': [],
            })
        
        employee = user.employee
        
        # 检查员工是否有岗位
        if not employee.position:
            return Response({
                'employee_id': employee.id,
                'employee_name': employee.name,
                'position_id': None,
                'position_title': None,
                'visible_pages': [],
                'visible_keys': [],
            })
        
        # 获取岗位直接授予的页面
        granted_pages = employee.position.visible_pages.filter(is_active=True).select_related('parent')
        
        # 计算所有可见页面（含子菜单继承）
        visible_pages = []
        visible_keys = set()
        
        for page in granted_pages:
            visible_pages.append(page)
            visible_keys.add(page.key)
            
            # 如果是主菜单，自动包含所有子菜单
            if page.page_type == FrontendPageTypeEnum.MAIN:
                children = page.children.filter(is_active=True).select_related('parent')
                for child in children:
                    if child.key not in visible_keys:
                        visible_pages.append(child)
                        visible_keys.add(child.key)
        
        # 按 sort_order 排序
        visible_pages.sort(key=lambda p: (p.sort_order, p.id))
        
        return Response({
            'employee_id': employee.id,
            'employee_name': employee.name,
            'position_id': employee.position.id,
            'position_title': employee.position.title,
            'visible_pages': FrontendPageSerializer(visible_pages, many=True).data,
            'visible_keys': sorted(visible_keys),
        })
