from flask import Blueprint, request, jsonify
from app.services.outbound_service import OutboundService
from flask_jwt_extended import jwt_required, get_jwt_identity, get_jwt
from app.utils.decorators import permission_required, audit_log
from app.services.auth_service import AuthService
import traceback

outbound_bp = Blueprint('outbound', __name__, url_prefix='/outbound')


# ==============================================================================
# 辅助函数：获取当前用户的完整权限列表（基于角色查询）
# ==============================================================================
def get_current_user_permissions():
    """
    返回当前用户拥有的所有权限码列表（包括菜单和元素）
    此函数根据角色查询数据库得到权限。
    """
    from flask_jwt_extended import get_jwt
    from app.services.auth_service import AuthService
    claims = get_jwt()
    user_role = claims.get('role')
    if not user_role:
        return []
    # 超级管理员返回所有字段权限 (忽略大小写)
    if user_role.upper() == 'SUPER_ADMIN':
        return ['outbound_list:*']
    perm_dict = AuthService.get_user_permissions(user_role)
    # 合并菜单和元素权限
    perms = perm_dict.get('menus', []) + perm_dict.get('elements', [])
    return perms


def filter_item_by_permissions(item_dict, user_permissions):
    """
    根据用户权限过滤 item 字典，无权限的字段值置为 None
    """
    # 字段名到权限码的映射（与前端 permissionMap 保持一致）
    field_to_perm = {
        'outbound_no': 'outbound_list:outbound_no',
        'outbound_time': 'outbound_list:outbound_time',
        'outbound_type': 'outbound_list:outbound_type',
        'total_amount': 'outbound_list:total_amount',
        'consumer_name': 'outbound_list:consumer_name',
        'operator_name': 'outbound_list:operator_name',
        'remark': 'outbound_list:remark',
        'signature_path': 'outbound_list:signature_path',
        # 明细字段
        'sku': 'outbound_list:sku',
        'name': 'outbound_list:name',
        'material_type': 'outbound_list:material_type',
        'category': 'outbound_list:category',
        'spec_model': 'outbound_list:spec_model',
        'quantity': 'outbound_list:quantity',
        'unit_price': 'outbound_list:unit_price',
        'subtotal': 'outbound_list:subtotal',
    }
    # 如果用户是超级管理员且有 'outbound_list:*'，则不过滤
    if 'outbound_list:*' in user_permissions:
        return item_dict
    for field, perm_code in field_to_perm.items():
        if field in item_dict and perm_code not in user_permissions:
            item_dict[field] = None
    # 如果 item_dict 中包含 items 列表，递归处理每个子项
    if 'items' in item_dict and isinstance(item_dict['items'], list):
        for sub_item in item_dict['items']:
            filter_item_by_permissions(sub_item, user_permissions)
    return item_dict


# --------------------------------------------------------
# 1. 扫码查询库存接口 (关联三个库存表)
# GET /api/v1/outbound/scan?barcode=...
# --------------------------------------------------------
@outbound_bp.route('/scan', methods=['GET'])
@jwt_required()
@permission_required('outbound_selection')
def scan_barcode():
    barcode = request.args.get('barcode')
    if not barcode:
        return jsonify({'code': 400, 'msg': '请提供条码'}), 400

    try:
        # 调用 Service 层去三个表中查找 (Service已更新，会返回价格)
        result = OutboundService.get_stock_by_barcode(barcode)

        if result:
            return jsonify({
                'code': 200,
                'msg': '扫描成功',
                'data': result
            })
        else:
            return jsonify({
                'code': 404,
                'msg': '未找到对应的库存记录，请确认条码是否正确'
            }), 404

    except Exception as e:
        traceback.print_exc()
        return jsonify({'code': 500, 'msg': f'扫描查询出错: {str(e)}'}), 500


# --------------------------------------------------------
# 2. 提交出库单接口 (批量)
# POST /api/v1/outbound
# --------------------------------------------------------
@outbound_bp.route('', methods=['POST'])
@jwt_required()
@audit_log(
    module='出库管理',
    action='新增',
    get_target_name_fn=lambda: request.get_json().get('order_no') if request.get_json() else None
)
def create_outbound():
    # 权限检查：需要 outbound_create:operation 或 outbound_selection:operation 之一
    claims = get_jwt()
    user_role = claims.get('role')
    if not user_role:
        return jsonify({'code': 403, 'msg': '未授权'}), 403

    # 超级管理员直接放行
    if user_role.upper() != 'SUPER_ADMIN':
        perm_dict = AuthService.get_user_permissions(user_role)
        perms = perm_dict.get('menus', []) + perm_dict.get('elements', [])
        if ('outbound_create:operation' not in perms) and ('outbound_selection:operation' not in perms):
            return jsonify({'code': 403, 'msg': '权限不足'}), 403

    data = request.get_json()
    if not data:
        return jsonify({'code': 400, 'msg': '无有效数据'}), 400

    # 获取当前登录用户名 (JWT identity)
    current_user_name = get_jwt_identity()
    if not current_user_name:
        current_user_name = 'Unknown'

    # 获取最终的操作员名称
    final_operator = data.get('operator_name')
    if not final_operator:
        final_operator = current_user_name

    # 必填校验 (针对整个单据)
    # items 必须是列表且不为空，consumer_name 和 signature_path 必填
    if 'items' not in data or not data['items']:
        return jsonify({'code': 400, 'msg': '出库商品列表不能为空'}), 400

    if not data.get('consumer_name') or not data.get('signature_path'):
        return jsonify({'code': 400, 'msg': '领用人及签名信息缺失'}), 400

    # 数据清洗：移除用户没有权限的字段
    user_permissions = get_current_user_permissions()
    # 超级管理员不过滤
    if 'outbound_list:*' not in user_permissions:
        # 字段名到权限码的映射（与前端 permissionMap 保持一致）
        field_to_perm = {
            'outbound_no': 'outbound_list:outbound_no',
            'outbound_time': 'outbound_list:outbound_time',
            'outbound_type': 'outbound_list:outbound_type',
            'total_amount': 'outbound_list:total_amount',
            'consumer_name': 'outbound_list:consumer_name',
            'operator_name': 'outbound_list:operator_name',
            'remark': 'outbound_list:remark',
            'signature_path': 'outbound_list:signature_path',
            # 明细字段
            'sku': 'outbound_list:sku',
            'name': 'outbound_list:name',
            'material_type': 'outbound_list:material_type',
            'category': 'outbound_list:category',
            'spec_model': 'outbound_list:spec_model',
            'quantity': 'outbound_list:quantity',
            'unit_price': 'outbound_list:unit_price',
            'price': 'outbound_list:unit_price',  # 兼容 price 字段
            'subtotal': 'outbound_list:subtotal',
        }
        # 清洗顶层字段
        for field in list(data.keys()):
            perm_code = field_to_perm.get(field)
            if perm_code and perm_code not in user_permissions:
                data.pop(field, None)
        # 清洗 items 中的每个商品字段
        if 'items' in data and isinstance(data['items'], list):
            for item in data['items']:
                for field in list(item.keys()):
                    perm_code = field_to_perm.get(field)
                    if perm_code and perm_code not in user_permissions:
                        item.pop(field, None)

    try:
        # ★ [修改] 调用批量创建服务
        outbound_no = OutboundService.create_outbound_batch(data, operator_name=final_operator)
        return jsonify({
            'code': 200,
            'msg': '出库成功',
            'data': {'outbound_no': outbound_no}
        })
    except ValueError as e:
        # 业务逻辑错误 (如库存不足)
        return jsonify({'code': 400, 'msg': str(e)}), 400
    except Exception as e:
        traceback.print_exc()
        return jsonify({'code': 500, 'msg': f'服务器内部错误: {str(e)}'}), 500


# --------------------------------------------------------
# 3. 获取出库记录列表 (分组展示)
# GET /api/v1/outbound
# --------------------------------------------------------
@outbound_bp.route('', methods=['GET'])
@jwt_required()
@permission_required('outbound_list')
def get_outbound_list():
    try:
        page = int(request.args.get('page', 1))
        limit = int(request.args.get('limit', 10))
        keyword = request.args.get('keyword', '')
        # 如果前端传了日期范围，可以解析处理，这里暂略

        # ★ [修改] 调用分组查询服务
        result = OutboundService.get_grouped_list(page, limit, keyword)

        # 字段级脱敏
        user_permissions = get_current_user_permissions()
        if result.get('items'):
            result['items'] = [filter_item_by_permissions(item, user_permissions) for item in result['items']]

        return jsonify({
            'code': 200,
            'msg': '获取成功',
            'data': result
        })
    except Exception as e:
        traceback.print_exc()
        return jsonify({'code': 500, 'msg': str(e)}), 500
