# inventory-backend/app/api/v1/warehouse.py
from flask import Blueprint, request, jsonify
from flask_jwt_extended import jwt_required
from app.extensions import db
from app.models.system import SysWarehouseLocation
from app.utils.decorators import audit_log

warehouse_bp = Blueprint('warehouse', __name__, url_prefix='/api/v1/warehouse')


def build_tree(nodes, parent_id=None):
    """
    将平铺的数据构建为树形结构
    """
    tree = []
    for node in nodes:
        if node.parent_id == parent_id:
            children = build_tree(nodes, node.id)
            node_dict = node.to_dict()
            if children:
                node_dict['children'] = children
            else:
                node_dict['children'] = []
            tree.append(node_dict)
    return tree


@warehouse_bp.route('/tree', methods=['GET'])
def get_tree():
    """
    获取库位树形结构
    """
    try:
        # 查询所有库位
        all_locations = SysWarehouseLocation.query.order_by(SysWarehouseLocation.level, SysWarehouseLocation.id).all()
        
        # 构建树形结构
        tree_data = build_tree(all_locations, parent_id=None)
        
        return jsonify({
            'code': 200,
            'msg': 'success',
            'data': tree_data
        })
    except Exception as e:
        return jsonify({
            'code': 500,
            'msg': str(e),
            'data': None
        }), 500


@warehouse_bp.route('', methods=['POST'])
@jwt_required()
@audit_log(
    module='库位管理',
    action='新增',
    get_target_name_fn=lambda: request.get_json().get('name') if request.get_json() else None
)
def create_location():
    """
    创建库位
    """
    try:
        data = request.get_json()
        name = data.get('name', '').strip()
        parent_id = data.get('parent_id')  # None 表示顶级
        is_enabled = data.get('is_enabled', True)
        
        if not name:
            return jsonify({'code': 400, 'msg': '库位名称不能为空', 'data': None})
        
        # 计算 level 和 full_path
        if parent_id is None:
            level = 0
            full_path = name
            parent_full_path = ''
        else:
            parent = SysWarehouseLocation.query.get(parent_id)
            if not parent:
                return jsonify({'code': 400, 'msg': '父级库位不存在', 'data': None})
            level = parent.level + 1
            parent_full_path = parent.full_path or ''
            full_path = f"{parent_full_path}/{name}" if parent_full_path else name
        
        location = SysWarehouseLocation(
            name=name,
            parent_id=parent_id,
            full_path=full_path,
            level=level,
            is_enabled=is_enabled
        )
        db.session.add(location)
        db.session.commit()
        
        return jsonify({
            'code': 200,
            'msg': '创建成功',
            'data': location.to_dict()
        })
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'code': 500,
            'msg': str(e),
            'data': None
        }), 500


@warehouse_bp.route('/<int:location_id>', methods=['PUT'])
@jwt_required()
@audit_log(
    module='库位管理',
    action='修改',
    get_target_id_fn=lambda: request.view_args.get('location_id'),
    get_target_name_fn=lambda: request.get_json().get('name') if request.get_json() else None
)
def update_location(location_id):
    """
    更新库位
    """
    try:
        data = request.get_json()
        location = SysWarehouseLocation.query.get(location_id)
        
        if not location:
            return jsonify({'code': 404, 'msg': '库位不存在', 'data': None})
        
        # 更新名称
        if 'name' in data and data['name']:
            new_name = data['name'].strip()
            if new_name != location.name:
                # 需要更新 full_path
                parent = location.parent
                if parent:
                    location.full_path = f"{parent.full_path}/{new_name}" if parent.full_path else new_name
                else:
                    location.full_path = new_name
                location.name = new_name
        
        # 更新启用状态
        if 'is_enabled' in data:
            location.is_enabled = data['is_enabled']
        
        db.session.commit()
        
        return jsonify({
            'code': 200,
            'msg': '更新成功',
            'data': location.to_dict()
        })
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'code': 500,
            'msg': str(e),
            'data': None
        }), 500


@warehouse_bp.route('/<int:location_id>', methods=['DELETE'])
@jwt_required()
@audit_log(
    module='库位管理',
    action='删除',
    get_target_id_fn=lambda: request.view_args.get('location_id')
)
def delete_location(location_id):
    """
    删除库位（级联删除子库位）
    """
    try:
        location = SysWarehouseLocation.query.get(location_id)
        
        if not location:
            return jsonify({'code': 404, 'msg': '库位不存在', 'data': None})
        
        # 递归删除所有子库位
        def delete_recursive(loc):
            # 先删除所有子节点
            children = SysWarehouseLocation.query.filter_by(parent_id=loc.id).all()
            for child in children:
                delete_recursive(child)
            # 再删除自身
            db.session.delete(loc)
        
        delete_recursive(location)
        db.session.commit()
        
        return jsonify({
            'code': 200,
            'msg': '删除成功',
            'data': None
        })
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'code': 500,
            'msg': str(e),
            'data': None
        }), 500
