"""
Printing API ViewSet
"""
from rest_framework import viewsets, filters, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import BasePermission
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.permissions import DjangoModelPermissions
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser
from django.db.models import CharField, Prefetch
from django.db.models.functions import Cast, Coalesce
from django_filters.rest_framework import DjangoFilterBackend
from django_filters import rest_framework as django_filters
from django_filters import IsoDateTimeFilter
from printing import models
from basic_info.models import MerchantTypeEnum

from .serializers import (
    PrintingOrderListSerializer,
    PrintingOrderDetailSerializer,
    PrintingOrderCreateUpdateSerializer,
    PrintingJobListSerializer,
    PrintingJobDetailSerializer,
    PrintingJobCreateUpdateSerializer,
)


class IsPrintingFactory(BasePermission):
    """自定义权限类，允许印染工厂用户访问"""

    message = '您没有访问印染订单的权限'
    
    def has_permission(self, request, view):
        if not request.user.is_authenticated:
            return False
        if hasattr(request.user, 'employee'):
            return request.user.employee.merchant.type == MerchantTypeEnum.FACTORY
        return False


class HasInvalidatePrintingOrderPermission(BasePermission):
    """自定义权限类，检查用户是否有作废印染订单的权限"""

    message = '您没有权限作废订单'
    
    def has_permission(self, request, view):
        if not request.user.is_authenticated:
            return False
        return request.user.has_perm('printing.can_invalidate_printingorder')


class HasActivatePrintingOrderPermission(BasePermission):
    """自定义权限类，检查用户是否有恢复印染订单的权限"""

    message = '您没有权限恢复订单'
    
    def has_permission(self, request, view):
        if not request.user.is_authenticated:
            return False
        return request.user.has_perm('printing.can_activate_printingorder')


class PrintingOrderFilterSet(django_filters.FilterSet):
    """印染订单过滤器"""
    customer_name = django_filters.CharFilter(field_name='customer__name', lookup_expr='icontains')
    customer_phone = django_filters.CharFilter(field_name='customer__phone', lookup_expr='icontains')
    fabric = django_filters.CharFilter(lookup_expr='icontains')
    is_urgent = django_filters.BooleanFilter()
    is_fabric_received = django_filters.BooleanFilter()
    is_invalid = django_filters.BooleanFilter()
    area = django_filters.CharFilter(lookup_expr='icontains')
    outgoing_date_from = django_filters.DateFilter(field_name='outgoing_date', lookup_expr='gte')
    outgoing_date_to = django_filters.DateFilter(field_name='outgoing_date', lookup_expr='lte')
    created_date_from = django_filters.DateFilter(field_name='created_at', lookup_expr='gte')
    created_date_to = django_filters.DateFilter(field_name='created_at', lookup_expr='lte')
    
    class Meta:
        model = models.PrintingOrder
        fields = ['customer', 'is_urgent', 'is_fabric_received', 'is_invalid']


class PrintingOrderViewSet(viewsets.ModelViewSet):
    """
    印染订单 ViewSet
    
    提供印染订单的增改查功能（不支持删除）
    
    list: 获取印染订单列表
    retrieve: 获取印染订单详情
    create: 创建印染订单
    update: 更新印染订单
    partial_update: 部分更新印染订单
    
    查询参数:
    - customer: 客户ID
    - customer_name: 客户名称（模糊查询）
    - customer_phone: 客户电话（模糊查询）
    - fabric: 面料（模糊查询）
    - is_urgent: 是否紧急（true/false）
    - is_fabric_received: 布料是否已收（true/false）
    - is_invalid: 是否作废（true/false）
    - area: 地区（模糊查询）
    - outgoing_date_from: 出货日期起始
    - outgoing_date_to: 出货日期结束
    - created_date_from: 创建日期起始
    - created_date_to: 创建日期结束
    - search: 全文搜索（客户名称、面料、地区、工艺）
    - ordering: 排序字段
    """
    queryset = models.PrintingOrder.objects.all()
    permission_classes = [DjangoModelPermissions]
    pagination_class = LimitOffsetPagination
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_class = PrintingOrderFilterSet
    search_fields = ['customer__name', 'fabric', 'area', 'craft', 'description']
    ordering_fields = [
        'id', 'created_at', 'updated_at', 'outgoing_date',
        'is_urgent', 'is_fabric_received', 'is_invalid'
    ]
    ordering = ['-created_at']

    def get_permissions(self):
        permissions = super().get_permissions() + [IsPrintingFactory()]
        if self.action == 'invalidate':
            permissions.append(HasInvalidatePrintingOrderPermission())
        elif self.action == 'activate':
            permissions.append(HasActivatePrintingOrderPermission())
        return permissions
    
    def get_serializer_class(self):
        """根据动作选择序列化器"""
        if self.action == 'list':
            return PrintingOrderListSerializer
        elif self.action in ['create', 'update', 'partial_update']:
            return PrintingOrderCreateUpdateSerializer
        else:  # retrieve
            return PrintingOrderDetailSerializer
    
    def get_queryset(self):
        """优化查询"""
        queryset = super().get_queryset()
        if self.action in ['list', 'retrieve']:
            queryset = queryset.select_related('customer')
        return queryset
    
    def destroy(self, request, *args, **kwargs):
        """禁用删除操作"""
        return Response(
            {'detail': '印染订单不支持删除操作，请使用作废功能'},
            status=status.HTTP_405_METHOD_NOT_ALLOWED
        )
    
    @action(detail=True, methods=['post'])
    def invalidate(self, request, pk=None):
        """
        作废订单
        
        需要权限: printing.can_invalidate_printingorder
        """
        # 检查权限
        if not request.user.has_perm('printing.can_invalidate_printingorder'):
            return Response(
                {'detail': '您没有权限作废订单'},
                status=status.HTTP_403_FORBIDDEN
            )
        
        printing_order = self.get_object()
        
        if printing_order.is_invalid:
            return Response(
                {'detail': '该订单已经作废'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        printing_order.is_invalid = True
        printing_order.save()
        
        serializer = PrintingOrderDetailSerializer(printing_order)
        return Response({
            'detail': '订单已作废',
            'data': serializer.data
        })
    
    @action(detail=True, methods=['post'])
    def activate(self, request, pk=None):
        """
        恢复订单
        
        需要权限: printing.can_activate_printingorder
        """
        # 检查权限
        if not request.user.has_perm('printing.can_activate_printingorder'):
            return Response(
                {'detail': '您没有权限恢复订单'},
                status=status.HTTP_403_FORBIDDEN
            )
        
        printing_order = self.get_object()
        
        if not printing_order.is_invalid:
            return Response(
                {'detail': '该订单未作废，无需恢复'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        printing_order.is_invalid = False
        printing_order.save()
        
        serializer = PrintingOrderDetailSerializer(printing_order)
        return Response({
            'detail': '订单已恢复',
            'data': serializer.data
        })
    
    @action(detail=True, methods=['post'])
    def mark_fabric_received(self, request, pk=None):
        """标记布料已收"""
        printing_order = self.get_object()
        
        if printing_order.is_fabric_received:
            return Response(
                {'detail': '布料已经标记为已收'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        printing_order.is_fabric_received = True
        printing_order.save()
        
        serializer = PrintingOrderDetailSerializer(printing_order)
        return Response({
            'detail': '已标记布料已收',
            'data': serializer.data
        })


class PrintingJobFilterSet(django_filters.FilterSet):
    """印染款式明细过滤器"""
    printing_order = django_filters.NumberFilter()
    product = django_filters.NumberFilter()
    product_name = django_filters.CharFilter(field_name='product__name', lookup_expr='icontains')
    unit = django_filters.CharFilter(lookup_expr='icontains')
    quantity_min = django_filters.NumberFilter(field_name='quantity', lookup_expr='gte')
    quantity_max = django_filters.NumberFilter(field_name='quantity', lookup_expr='lte')
    pieces_min = django_filters.NumberFilter(field_name='pieces', lookup_expr='gte')
    pieces_max = django_filters.NumberFilter(field_name='pieces', lookup_expr='lte')
    
    class Meta:
        model = models.PrintingJob
        fields = ['printing_order', 'product']


class PrintingJobViewSet(viewsets.ModelViewSet):
    """
    印染款式明细 ViewSet
    
    提供印染款式明细的增改查功能（不支持删除）
    
    list: 获取款式明细列表
    retrieve: 获取款式明细详情
    create: 创建款式明细
    update: 更新款式明细
    partial_update: 部分更新款式明细
    advance_to_next_state: 推进到下一个状态
    step_back_one_state: 回退一步
    completed_states: 查询已完成的流程列表
    timeline: 获取流程时间线
    
    注意：状态流转接口是对 stateflow 模块的便捷包装
    - 前端只需提供 printing_job 的 ID
    - 系统会自动查找关联的 business_object 并进行状态流转
    - 也可以直接使用 stateflow 的原始接口（需要 business_object_id）
    
    查询参数:
    - printing_order: 印染订单ID
    - product: 产品ID
    - product_name: 产品名称（模糊查询）
    - unit: 单位（模糊查询）
    - quantity_min: 最小数量
    - quantity_max: 最大数量
    - pieces_min: 最小件数
    - pieces_max: 最大件数
    - search: 全文搜索（产品名称、单位、尺寸、备注）
    - ordering: 排序字段
    """
    queryset = models.PrintingJob.objects.all()
    permission_classes = [DjangoModelPermissions, IsPrintingFactory]
    pagination_class = LimitOffsetPagination
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_class = PrintingJobFilterSet
    search_fields = ['product__name', 'unit', 'size', 'description']
    ordering_fields = ['id', 'created_at', 'updated_at', 'quantity', 'pieces']
    ordering = ['-created_at']
    
    def get_serializer_class(self):
        """根据动作选择序列化器"""
        if self.action == 'list':
            return PrintingJobListSerializer
        elif self.action in ['create', 'update', 'partial_update']:
            return PrintingJobCreateUpdateSerializer
        else:  # retrieve
            return PrintingJobDetailSerializer
    
    def get_queryset(self):
        """优化查询"""
        queryset = super().get_queryset()
        if self.action in ['list', 'retrieve']:
            queryset = queryset.select_related('printing_order', 'product')
            # 预取批量推进记录（避免 serializer 产生 N+1）
            queryset = queryset.prefetch_related(
                Prefetch(
                    'batch_advance_records',
                    queryset=models.PrintingJobBatchAdvanceRecord.objects.select_related('state', 'created_by')
                    .order_by('-created_at', '-id'),
                )
            )
        return queryset
    
    def destroy(self, request, *args, **kwargs):
        """禁用删除操作"""
        return Response(
            {'detail': '印染款式明细不支持删除操作'},
            status=status.HTTP_405_METHOD_NOT_ALLOWED
        )
    
    @action(detail=True, methods=['post'], url_path='advance-to-next-state')
    def advance_to_next_state(self, request, pk=None):
        """
        推进到下一个状态
        
        将印染任务推进到下一个流程状态
        
        请求体:
        {
            "parameters": {
                "temperature": "25.5",
                "operator": "张三"
            }
        }
        
        参数可选，但如果下一个状态有必填参数，则必须提供
        
        注意：这是对 stateflow.BusinessObject.advance 接口的便捷包装，
        自动通过 printing_job 查找关联的 business_object 并调用状态流转服务。
        前端只需提供 printing_job 的 ID，无需关心 business_object_id。
        """
        job = self.get_object()
        
        if not job.business_object:
            return Response(
                {'detail': '该任务没有关联的流程实例'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 获取请求参数
        parameters = request.data.get('parameters', {})
        
        # 调用 stateflow 统一服务进行状态流转
        from stateflow import services as stateflow_services
        success, message, state_log = stateflow_services.advance_to_next_state(
            job.business_object, request.user, **parameters
        )
        
        if not success:
            return Response(
                {'detail': message},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 重新获取 job 以刷新状态
        job.refresh_from_db()
        serializer = PrintingJobDetailSerializer(job)
        
        return Response({
            'detail': message,
            'data': serializer.data
        })
    
    @action(detail=True, methods=['post'], url_path='step-back-one-state')
    def step_back_one_state(self, request, pk=None):
        """
        回退一步
        
        将印染任务回退到上一个流程状态
        
        注意：这是对 stateflow.BusinessObject.step_back 接口的便捷包装，
        自动通过 printing_job 查找关联的 business_object 并调用状态流转服务。
        前端只需提供 printing_job 的 ID，无需关心 business_object_id。
        """
        job = self.get_object()
        
        if not job.business_object:
            return Response(
                {'detail': '该任务没有关联的流程实例'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 调用 stateflow 统一服务进行状态回退
        from stateflow import services as stateflow_services
        success, message = stateflow_services.step_back_one_state(
            job.business_object, request.user
        )
        
        if not success:
            return Response(
                {'detail': message},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 重新获取 job 以刷新状态
        job.refresh_from_db()
        serializer = PrintingJobDetailSerializer(job)
        
        return Response({
            'detail': message,
            'data': serializer.data
        })
    
    @action(detail=True, methods=['get'], url_path='completed-states')
    def completed_states(self, request, pk=None):
        """
        查询已完成的流程列表
        
        查询参数:
        - include_cancelled: 是否包含已撤销的流程（true/false），默认 false
        """
        job = self.get_object()
        
        if not job.business_object:
            return Response({
                'count': 0,
                'results': []
            })
        
        # 获取查询参数
        include_cancelled = request.query_params.get('include_cancelled', 'false').lower() == 'true'
        
        # 查询已完成的状态
        state_logs = job.business_object.state_logs.select_related('state', 'completed_by').order_by('completed_at')
        
        if not include_cancelled:
            state_logs = state_logs.filter(is_cancelled=False)
        
        results = []
        for log in state_logs:
            results.append({
                'id': log.id,
                'state_id': log.state.id,
                'state_name': log.state.name,
                'completed_at': log.completed_at,
                'completed_by': log.completed_by.username if log.completed_by else None,
                'completed_by_name': getattr(log.completed_by, 'employee', None) and log.completed_by.employee.name or None,
                'is_cancelled': log.is_cancelled,
                'cancelled_at': log.cancelled_at,
            })
        
        return Response({
            'count': len(results),
            'results': results
        })
    
    @action(detail=True, methods=['get'], url_path='timeline')
    def timeline(self, request, pk=None):
        """
        获取流程时间线
        
        返回该任务的完整流程时间线，包括未开始、进行中和已完成的状态
        不包含已撤销的流程记录
        """
        job = self.get_object()
        
        if not job.business_object or not job.printing_order.process:
            return Response({
                'count': 0,
                'results': []
            })
        
        from stateflow import services as stateflow_services
        timeline_data = stateflow_services.get_business_object_state_timeline(job.business_object)
        
        # 过滤掉已撤销的记录
        timeline_data = [item for item in timeline_data if not item.get('is_cancelled')]
        
        results = []
        for item in timeline_data:
            results.append({
                'state_id': item['state'].id,
                'state_name': item['state'].name,
                'state_description': item['state'].description,
                'order': item['order'],
                'status': item['status'],  # not_started, in_progress, completed
                'completed_at': item['completed_at'],
                'completed_by': item['completed_by'].username if item['completed_by'] else None,
                'completed_by_name': getattr(item['completed_by'], 'employee', None) and item['completed_by'].employee.name or None if item['completed_by'] else None,
            })
        
        return Response({
            'count': len(results),
            'results': results
        })


class HasInvalidatePlateOrderPermission(BasePermission):
    """自定义权限类，检查用户是否有作废开版订单的权限"""

    message = '您没有权限作废开版订单'
    
    def has_permission(self, request, view):
        if not request.user.is_authenticated:
            return False
        return request.user.has_perm('printing.can_invalidate_plateorder')


class HasActivatePlateOrderPermission(BasePermission):
    """自定义权限类，检查用户是否有恢复开版订单的权限"""

    message = '您没有权限恢复开版订单'
    
    def has_permission(self, request, view):
        if not request.user.is_authenticated:
            return False
        return request.user.has_perm('printing.can_activate_plateorder')


class PlateOrderFilterSet(django_filters.FilterSet):
    """开版订单过滤器"""
    customer_name = django_filters.CharFilter(field_name='customer__name', lookup_expr='icontains')
    customer_phone = django_filters.CharFilter(field_name='customer__mobile', lookup_expr='icontains')
    image_name = django_filters.CharFilter(lookup_expr='icontains')
    salesperson = django_filters.NumberFilter()
    merchandiser = django_filters.NumberFilter()
    plate_type = django_filters.CharFilter(lookup_expr='icontains')
    urgency_level = django_filters.CharFilter(lookup_expr='icontains')
    is_invalid = django_filters.BooleanFilter()
    is_ordered = django_filters.BooleanFilter()
    is_mark_frame = django_filters.BooleanFilter()
    fabric = django_filters.CharFilter(lookup_expr='icontains')
    style_name = django_filters.CharFilter(lookup_expr='icontains')
    plate_date_from = django_filters.DateFilter(field_name='plate_date', lookup_expr='gte')
    plate_date_to = django_filters.DateFilter(field_name='plate_date', lookup_expr='lte')
    required_completion_date_from = IsoDateTimeFilter(field_name='required_completion_date', lookup_expr='gte')
    required_completion_date_to = IsoDateTimeFilter(field_name='required_completion_date', lookup_expr='lte')
    created_date_from = django_filters.DateFilter(field_name='created_at', lookup_expr='gte')
    created_date_to = django_filters.DateFilter(field_name='created_at', lookup_expr='lte')
    
    class Meta:
        model = models.PlateOrder
        fields = ['customer', 'salesperson', 'merchandiser', 'urgency_level', 'is_invalid', 'is_ordered']


class PlateOrderViewSet(viewsets.ModelViewSet):
    """
    开版订单 ViewSet
    
    提供开版订单的增改查功能（不支持删除）
    
    list: 获取开版订单列表
    retrieve: 获取开版订单详情
    create: 创建开版订单
    image_name: 图片名称（模糊查询）
    update: 更新开版订单
    partial_update: 部分更新开版订单
    invalidate: 作废开版订单
    activate: 恢复开版订单
    advance_to_next_state: 推进到下一个状态（便捷包装）
    step_back_one_state: 回退一步（便捷包装）
    completed_states: 查询已完成的流程列表
    timeline: 获取流程时间线
    
    注意：状态流转接口是对 stateflow 模块的便捷包装
    - 前端只需提供 plate_order 的 ID
    - 系统会自动查找关联的 business_object 并进行状态流转
    - 也可以直接使用 stateflow 的原始接口（需要 business_object_id）
    
    查询参数:
    - customer: 客户ID
    - customer_name: 客户名称（模糊查询）
    - customer_phone: 客户电话（模糊查询）
    - salesperson: 业务员ID
    - merchandiser: 跟单员ID
    - plate_type: 版型（模糊查询）
    - urgency_level: 紧急程度（1-5）
    - is_invalid: 是否作废（true/false）
    - is_ordered: 是否已下单（true/false）
    - is_mark_frame: 是否打样架（true/false）
    - fabric: 面料（模糊查询）
    - style_name: 款式名称（模糊查询）
    - plate_date_from: 开版日期起始
    - plate_date_to: 开版日期结束
    - required_completion_date_from: 要求完成时间起始（含时分秒）
    - required_completion_date_to: 要求完成时间结束
    - created_date_from: 创建日期起始
    - created_date_to: 创建日期结束
    - search: 全文搜索（设计编号、款式名称、客户名称、面料）
    - ordering: 排序字段
    """
    queryset = models.PlateOrder.objects.all()
    permission_classes = [DjangoModelPermissions]
    parser_classes = [MultiPartParser, FormParser, JSONParser]  # 支持文件上传
    pagination_class = LimitOffsetPagination
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_class = PlateOrderFilterSet
    # design_code_normalized: 当 design_code 为空时用 id 兜底，便于搜索数字编号
    search_fields = ['design_code', 'design_code_normalized', 'style_name', 'customer__name', 'fabric']
    ordering_fields = [
        'id', 'created_at', 'updated_at', 'plate_date', 
        'required_completion_date', 'completion_date',
        'urgency_level', 'is_ordered', 'is_invalid'
    ]
    ordering = ['-created_at']
    
    def get_serializer_class(self):
        """根据动作选择序列化器"""
        from .serializers import (
            PlateOrderListSerializer,
            PlateOrderDetailSerializer,
            PlateOrderCreateUpdateSerializer,
        )
        
        if self.action == 'list':
            return PlateOrderListSerializer
        elif self.action in ['create', 'update', 'partial_update']:
            return PlateOrderCreateUpdateSerializer
        else:  # retrieve
            return PlateOrderDetailSerializer
    
    def get_queryset(self):
        """优化查询"""
        queryset = super().get_queryset()
        if self.action in ['list', 'retrieve']:
            queryset = queryset.select_related('customer', 'salesperson', 'merchandiser', 'business_object')
        # 为搜索提供 design_code 的兜底（为空时使用主键字符串）
        queryset = queryset.annotate(
            design_code_normalized=Coalesce('design_code', Cast('id', output_field=CharField()))
        )
        return queryset
    
    def destroy(self, request, *args, **kwargs):
        """禁用删除操作"""
        return Response(
            {'detail': '开版订单不支持删除操作，请使用作废功能'},
            status=status.HTTP_405_METHOD_NOT_ALLOWED
        )
    
    @action(detail=True, methods=['post'])
    def invalidate(self, request, pk=None):
        """
        作废开版订单
        
        需要权限: printing.can_invalidate_plateorder
        """
        # 检查权限
        if not request.user.has_perm('printing.can_invalidate_plateorder'):
            return Response(
                {'detail': '您没有权限作废开版订单'},
                status=status.HTTP_403_FORBIDDEN
            )
        
        plate_order = self.get_object()
        
        if plate_order.is_invalid:
            return Response(
                {'detail': '该开版订单已经作废'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        plate_order.is_invalid = True
        plate_order.save()
        
        from .serializers import PlateOrderDetailSerializer
        serializer = PlateOrderDetailSerializer(plate_order, context={'request': request})
        return Response({
            'detail': '开版订单已作废',
            'data': serializer.data
        })
    
    @action(detail=True, methods=['post'])
    def activate(self, request, pk=None):
        """
        恢复开版订单
        
        需要权限: printing.can_activate_plateorder
        """
        # 检查权限
        if not request.user.has_perm('printing.can_activate_plateorder'):
            return Response(
                {'detail': '您没有权限恢复开版订单'},
                status=status.HTTP_403_FORBIDDEN
            )
        
        plate_order = self.get_object()
        
        if not plate_order.is_invalid:
            return Response(
                {'detail': '该开版订单未作废，无需恢复'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        plate_order.is_invalid = False
        plate_order.save()
        
        from .serializers import PlateOrderDetailSerializer
        serializer = PlateOrderDetailSerializer(plate_order, context={'request': request})
        return Response({
            'detail': '开版订单已恢复',
            'data': serializer.data
        })
    
    @action(detail=True, methods=['post'], url_path='advance-to-next-state')
    def advance_to_next_state(self, request, pk=None):
        """
        推进到下一个状态
        
        将开版订单推进到下一个流程状态
        
        请求体:
        {
            "parameters": {
                "inspector": "李四",
                "quality_score": "95"
            }
        }
        
        参数可选，但如果下一个状态有必填参数，则必须提供
        
        注意：这是对 stateflow.BusinessObject.advance 接口的便捷包装，
        自动通过 plate_order 查找关联的 business_object 并调用状态流转服务。
        """
        plate_order = self.get_object()
        
        if not plate_order.business_object:
            return Response(
                {'detail': '该开版订单没有关联的流程实例'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 获取请求参数
        parameters = request.data.get('parameters', {})
        
        # 调用 stateflow 统一服务进行状态流转
        from stateflow import services as stateflow_services
        success, message, state_log = stateflow_services.advance_to_next_state(
            plate_order.business_object, request.user, **parameters
        )
        
        if not success:
            return Response(
                {'detail': message},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 重新获取 plate_order 以刷新状态
        plate_order.refresh_from_db()
        from .serializers import PlateOrderDetailSerializer
        serializer = PlateOrderDetailSerializer(plate_order, context={'request': request})
        
        return Response({
            'detail': message,
            'data': serializer.data
        })
    
    @action(detail=True, methods=['post'], url_path='step-back-one-state')
    def step_back_one_state(self, request, pk=None):
        """
        回退一步
        
        将开版订单回退到上一个流程状态
        
        注意：这是对 stateflow.BusinessObject.step_back 接口的便捷包装，
        自动通过 plate_order 查找关联的 business_object 并调用状态流转服务。
        """
        plate_order = self.get_object()
        
        if not plate_order.business_object:
            return Response(
                {'detail': '该开版订单没有关联的流程实例'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 调用 stateflow 统一服务进行状态回退
        from stateflow import services as stateflow_services
        success, message = stateflow_services.step_back_one_state(
            plate_order.business_object, request.user
        )
        
        if not success:
            return Response(
                {'detail': message},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # 重新获取 plate_order 以刷新状态
        plate_order.refresh_from_db()
        from .serializers import PlateOrderDetailSerializer
        serializer = PlateOrderDetailSerializer(plate_order, context={'request': request})
        
        return Response({
            'detail': message,
            'data': serializer.data
        })
    
    @action(detail=True, methods=['get'], url_path='completed-states')
    def completed_states(self, request, pk=None):
        """
        查询已完成的流程列表
        
        查询参数:
        - include_cancelled: 是否包含已撤销的流程（true/false），默认 false
        """
        plate_order = self.get_object()
        
        if not plate_order.business_object:
            return Response({
                'count': 0,
                'results': []
            })
        
        # 获取查询参数
        include_cancelled = request.query_params.get('include_cancelled', 'false').lower() == 'true'
        
        # 查询已完成的状态
        state_logs = plate_order.business_object.state_logs.select_related('state', 'completed_by').order_by('completed_at')
        
        if not include_cancelled:
            state_logs = state_logs.filter(is_cancelled=False)
        
        results = []
        for log in state_logs:
            results.append({
                'id': log.id,
                'state_id': log.state.id,
                'state_name': log.state.name,
                'completed_at': log.completed_at,
                'completed_by': log.completed_by.username if log.completed_by else None,
                'completed_by_name': getattr(log.completed_by, 'employee', None) and log.completed_by.employee.name or None,
                'is_cancelled': log.is_cancelled,
                'cancelled_at': log.cancelled_at,
            })
        
        return Response({
            'count': len(results),
            'results': results
        })
    
    @action(detail=True, methods=['get'], url_path='timeline')
    def timeline(self, request, pk=None):
        """
        获取流程时间线
        
        返回该开版订单的完整流程时间线，包括未开始、进行中和已完成的状态
        不包含已撤销的流程记录
        """
        plate_order = self.get_object()
        
        if not plate_order.business_object:
            return Response({
                'count': 0,
                'results': []
            })
        
        from stateflow import services as stateflow_services
        
        # 获取流程
        from stateflow.models import Process
        try:
            process = Process.objects.get(id=plate_order.process)
        except Process.DoesNotExist:
            return Response({
                'count': 0,
                'results': []
            })
        
        timeline_data = stateflow_services.get_business_object_state_timeline(plate_order.business_object)
        
        # 过滤掉已撤销的记录
        timeline_data = [item for item in timeline_data if not item.get('is_cancelled')]
        
        results = []
        for item in timeline_data:
            results.append({
                'state_id': item['state'].id,
                'state_name': item['state'].name,
                'state_description': item['state'].description,
                'order': item['order'],
                'status': item['status'],  # not_started, in_progress, completed
                'completed_at': item['completed_at'],
                'completed_by': item['completed_by'].username if item['completed_by'] else None,
                'completed_by_name': getattr(item['completed_by'], 'employee', None) and item['completed_by'].employee.name or None if item['completed_by'] else None,
            })
        
        return Response({
            'count': len(results),
            'results': results
        })
