"""Supplier and purchase order blueprint.

Endpoints (all under /pos/api):
  GET/POST    /suppliers
  GET/PUT     /suppliers/<id>
  GET         /suppliers/<id>/purchase-orders
  POST        /purchase-orders
  GET         /purchase-orders
  GET         /purchase-orders/<id>
  PUT         /purchase-orders/<id>/send
  PUT         /purchase-orders/<id>/receive
  PUT         /purchase-orders/<id>/cancel
"""

from flask import Blueprint, request, jsonify, g
from middleware import require_auth
from tenant_db import get_tenant_conn
from services.supplier_engine import (
    create_supplier, update_supplier, get_supplier, list_suppliers,
    create_po, send_po, receive_po, cancel_po, get_po, list_pos,
)

supplier_bp = Blueprint('supplier', __name__, url_prefix='/pos/api')


# ── SUPPLIERS ──────────────────────────────────────────────────────────────

@supplier_bp.route('/suppliers', methods=['GET'])
@require_auth('inventory.view')
def get_suppliers():
    """List suppliers."""
    conn = get_tenant_conn(g.tenant_id)
    active_only = request.args.get('active_only', 'true').lower() == 'true'
    limit = request.args.get('limit', 100, type=int)
    offset = request.args.get('offset', 0, type=int)
    data = list_suppliers(conn, active_only=active_only, limit=limit, offset=offset)
    conn.close()
    return jsonify({'data': data})


@supplier_bp.route('/suppliers', methods=['POST'])
@require_auth('inventory.edit')
def post_supplier():
    """Create a supplier."""
    data = request.get_json() or {}
    if not data.get('name'):
        return jsonify({'error': 'name is required'}), 400

    conn = get_tenant_conn(g.tenant_id)
    try:
        supplier_id = create_supplier(conn, data)
        conn.commit()
        conn.close()
        return jsonify({'id': supplier_id, 'message': 'Supplier created'}), 201
    except Exception as e:
        conn.rollback()
        conn.close()
        return jsonify({'error': str(e)}), 500


@supplier_bp.route('/suppliers/<int:supplier_id>', methods=['GET'])
@require_auth('inventory.view')
def get_supplier_detail(supplier_id):
    """Get supplier by ID."""
    conn = get_tenant_conn(g.tenant_id)
    supplier = get_supplier(conn, supplier_id)
    conn.close()
    if not supplier:
        return jsonify({'error': 'Supplier not found'}), 404
    return jsonify(supplier)


@supplier_bp.route('/suppliers/<int:supplier_id>', methods=['PUT'])
@require_auth('inventory.edit')
def put_supplier(supplier_id):
    """Update supplier."""
    data = request.get_json() or {}
    conn = get_tenant_conn(g.tenant_id)
    try:
        updated = update_supplier(conn, supplier_id, data)
        conn.commit()
        conn.close()
        if not updated:
            return jsonify({'error': 'Supplier not found or no changes'}), 404
        return jsonify({'message': 'Supplier updated'})
    except Exception as e:
        conn.rollback()
        conn.close()
        return jsonify({'error': str(e)}), 500


@supplier_bp.route('/suppliers/<int:supplier_id>/purchase-orders', methods=['GET'])
@require_auth('inventory.view')
def get_supplier_pos(supplier_id):
    """List POs for a supplier."""
    conn = get_tenant_conn(g.tenant_id)
    status = request.args.get('status')
    limit = request.args.get('limit', 50, type=int)
    offset = request.args.get('offset', 0, type=int)
    data = list_pos(conn, status=status, supplier_id=supplier_id, limit=limit, offset=offset)
    conn.close()
    return jsonify({'data': data})


# ── PURCHASE ORDERS ────────────────────────────────────────────────────────

@supplier_bp.route('/purchase-orders', methods=['POST'])
@require_auth('inventory.edit')
def post_purchase_order():
    """Create a purchase order."""
    data = request.get_json() or {}
    if not data.get('items'):
        return jsonify({'error': 'items are required'}), 400

    conn = get_tenant_conn(g.tenant_id)
    try:
        result = create_po(conn, data, branch_id=g.branch_id, employee_id=g.employee_id)
        conn.commit()
        conn.close()
        return jsonify(result), 201
    except ValueError as e:
        conn.rollback()
        conn.close()
        return jsonify({'error': str(e)}), 400
    except Exception as e:
        conn.rollback()
        conn.close()
        return jsonify({'error': str(e)}), 500


@supplier_bp.route('/purchase-orders', methods=['GET'])
@require_auth('inventory.view')
def get_purchase_orders():
    """List purchase orders."""
    conn = get_tenant_conn(g.tenant_id)
    status = request.args.get('status')
    supplier_id = request.args.get('supplier_id', type=int)
    limit = request.args.get('limit', 50, type=int)
    offset = request.args.get('offset', 0, type=int)
    data = list_pos(conn, status=status, supplier_id=supplier_id, limit=limit, offset=offset)
    conn.close()
    return jsonify({'data': data})


@supplier_bp.route('/purchase-orders/<int:po_id>', methods=['GET'])
@require_auth('inventory.view')
def get_purchase_order(po_id):
    """Get PO detail with items."""
    conn = get_tenant_conn(g.tenant_id)
    po = get_po(conn, po_id)
    conn.close()
    if not po:
        return jsonify({'error': 'Purchase order not found'}), 404
    return jsonify(po)


@supplier_bp.route('/purchase-orders/<int:po_id>/send', methods=['PUT'])
@require_auth('inventory.edit')
def put_send_po(po_id):
    """Mark PO as sent."""
    conn = get_tenant_conn(g.tenant_id)
    try:
        ok = send_po(conn, po_id)
        conn.commit()
        conn.close()
        if not ok:
            return jsonify({'error': 'PO not found or not in draft status'}), 400
        return jsonify({'message': 'PO marked as sent'})
    except Exception as e:
        conn.rollback()
        conn.close()
        return jsonify({'error': str(e)}), 500


@supplier_bp.route('/purchase-orders/<int:po_id>/receive', methods=['PUT'])
@require_auth('inventory.edit')
def put_receive_po(po_id):
    """Receive items from a PO."""
    data = request.get_json() or {}
    received_items = data.get('items', [])
    if not received_items:
        return jsonify({'error': 'items are required'}), 400

    conn = get_tenant_conn(g.tenant_id)
    try:
        result = receive_po(
            conn, po_id, received_items,
            supplier_invoice=data.get('supplier_invoice'),
            notes=data.get('notes')
        )
        conn.commit()
        conn.close()
        return jsonify(result)
    except ValueError as e:
        conn.rollback()
        conn.close()
        return jsonify({'error': str(e)}), 400
    except Exception as e:
        conn.rollback()
        conn.close()
        return jsonify({'error': str(e)}), 500


@supplier_bp.route('/purchase-orders/<int:po_id>/cancel', methods=['PUT'])
@require_auth('inventory.edit')
def put_cancel_po(po_id):
    """Cancel a PO."""
    data = request.get_json() or {}
    reason = data.get('reason', '')
    conn = get_tenant_conn(g.tenant_id)
    try:
        cancel_po(conn, po_id, reason)
        conn.commit()
        conn.close()
        return jsonify({'message': 'PO cancelled'})
    except ValueError as e:
        conn.rollback()
        conn.close()
        return jsonify({'error': str(e)}), 400
    except Exception as e:
        conn.rollback()
        conn.close()
        return jsonify({'error': str(e)}), 500
