"""Quotation stock reservation engine.

Uses inventory_operations with operation types:
  QUOTE_RESERVE  — negative quantity, reserves stock when quote is created
  QUOTE_RELEASE  — positive quantity, restores stock when quote is cancelled/expired
  QUOTE_CONVERT  — neutral (just a marker), actual sale uses SALE operation

The trigger update_stock_summary() recalculates inventory_stock_summary
by summing ALL operations, so reservations automatically affect visible stock.
"""
from services.inventory_engine import record_operation


def reserve_for_quotation(conn, quotation_id, items, employee_id=None):
    """Reserve stock for each item in a new quotation.

    Args:
        conn: tenant DB connection (not committed by this function).
        quotation_id: the quotations.id.
        items: list of dicts with inventory_id, quantity, branch_id (optional).
        employee_id: optional, passed explicitly when g.employee_id is unavailable.
    Returns:
        list of operation IDs.
    """
    op_ids = []
    for item in items:
        inv_id = item.get('inventory_id')
        qty = item.get('quantity', 0)
        branch_id = item.get('branch_id')
        if not inv_id or qty <= 0:
            continue
        op_id = record_operation(
            conn, inv_id, branch_id, 'QUOTE_RESERVE',
            quantity=-qty,
            reference_id=quotation_id,
            reference_type='quotation',
            notes=f'Reserva cotizacion #{quotation_id}'
        )
        op_ids.append(op_id)
    return op_ids


def release_quotation_reservation(conn, quotation_id, items, employee_id=None):
    """Release previously reserved stock (cancel, expire, or convert).

    Args:
        conn: tenant DB connection.
        quotation_id: the quotations.id.
        items: list of dicts with inventory_id, quantity, branch_id.
        employee_id: optional.
    Returns:
        list of operation IDs.
    """
    op_ids = []
    for item in items:
        inv_id = item.get('inventory_id')
        qty = item.get('quantity', 0)
        branch_id = item.get('branch_id')
        if not inv_id or qty <= 0:
            continue
        op_id = record_operation(
            conn, inv_id, branch_id, 'QUOTE_RELEASE',
            quantity=qty,
            reference_id=quotation_id,
            reference_type='quotation',
            notes=f'Liberacion cotizacion #{quotation_id}'
        )
        op_ids.append(op_id)
    return op_ids


def convert_quotation_reservation(conn, quotation_id, items, sale_id=None, employee_id=None):
    """Convert reservation to actual sale.

    Flow:
      1. Release the reservation (QUOTE_RELEASE +qty)
      2. Record the actual sale (SALE -qty)

    Args:
        conn: tenant DB connection.
        quotation_id: the quotations.id.
        items: list of dicts with inventory_id, quantity, branch_id.
        sale_id: the resulting sales.id (for reference).
        employee_id: optional.
    Returns:
        list of operation IDs.
    """
    op_ids = release_quotation_reservation(conn, quotation_id, items, employee_id)
    for item in items:
        inv_id = item.get('inventory_id')
        qty = item.get('quantity', 0)
        branch_id = item.get('branch_id')
        if not inv_id or qty <= 0:
            continue
        op_id = record_operation(
            conn, inv_id, branch_id, 'SALE',
            quantity=-qty,
            reference_id=sale_id or quotation_id,
            reference_type='sale' if sale_id else 'quotation',
            notes=f'Venta convertida de cotizacion #{quotation_id}'
        )
        op_ids.append(op_id)
    return op_ids


def get_quotation_items_for_reservation(conn, quotation_id):
    """Fetch items from a quotation joined with inventory to get branch_id.

    Returns list of dicts: {inventory_id, quantity, branch_id}
    """
    cur = conn.cursor()
    cur.execute("""
        SELECT qi.inventory_id, qi.quantity, i.branch_id
        FROM quotation_items qi
        JOIN inventory i ON i.id = qi.inventory_id
        WHERE qi.quotation_id = %s
    """, (quotation_id,))
    rows = cur.fetchall()
    cur.close()
    return [
        {'inventory_id': r[0], 'quantity': r[1], 'branch_id': r[2]}
        for r in rows
    ]
