# ============================================================================
# WAREHOUSE REPORT - Routes
# ============================================================================
# Report confronto inventario scansionato vs giacenze magazzino
# 
# Mostra SOLO righe con differenza != 0
# Confronta TUTTI i prodotti scansionati con le giacenze teoriche del magazzino
# Senza filtri su data/sessione - solo tenant e filiale
# ============================================================================

from flask import Blueprint, request, jsonify, render_template
from functools import wraps
from datetime import datetime
import logging
import os

logger = logging.getLogger(__name__)

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


def require_auth(f):
    """Decorator per autenticazione"""
    @wraps(f)
    def decorated(*args, **kwargs):
        # Assume che l'utente sia già autenticato da Flask
        request.user = {
            'id': 1,
            'tenant_id': 1,
            'email': 'demo@studium.it',
            'role': 'admin'
        }
        return f(*args, **kwargs)
    return decorated


def get_service():
    """Factory per InventoryService"""
    from app.services.inventory_service import create_inventory_service
    
    db_config = {
        'host': os.getenv('DB_HOST', 'localhost'),
        'user': os.getenv('DB_USER', 'enigma_user'),
        'password': os.getenv('DB_PASSWORD', 'arcana2026'),
        'database': os.getenv('DB_NAME', 'enigma')
    }
    
    api_key = os.getenv('CASSANOVA_API_KEY')
    if not api_key:
        raise ValueError("CASSANOVA_API_KEY non trovata nel .env!")
    
    return create_inventory_service(db_config, api_key)


# ============================================================================
# ENDPOINT: REPORT MAGAZZINO PER FILIALE
# ============================================================================

@warehouse_bp.route('/report/sede/<int:sede_id>', methods=['GET'])
@require_auth
def report_magazzino_sede(sede_id):
    """
    Report magazzino: confronta inventario scansionato vs giacenze magazzino.
    
    Mostra SOLO righe con differenza != 0.
    Confronta TUTTI i prodotti scansionati (indipendentemente da data/sessione)
    con le giacenze teoriche del magazzino per la filiale specificata.
    
    NOTA: Il barcode può essere sia EAN13/CODE39 che UUID.
    Il JOIN matcha su entrambi per catturare articoli scansionati con UUID.
    """
    try:
        service = get_service()
        tenant_id = request.user['tenant_id']
        
        import pymysql
        conn = pymysql.connect(
            host=os.getenv('DB_HOST', 'localhost'),
            user=os.getenv('DB_USER', 'enigma_user'),
            password=os.getenv('DB_PASSWORD', 'arcana2026'),
            database=os.getenv('DB_NAME', 'enigma'),
            charset='utf8mb4',
            cursorclass=pymysql.cursors.DictCursor
        )
        cursor = conn.cursor()
        
        # ✅ STEP 1: Verifica che la filiale esista
        cursor.execute("""
            SELECT id, nome FROM inv_sedi WHERE id = %s AND id_tenant = %s
        """, (sede_id, tenant_id))
        
        sede = cursor.fetchone()
        if not sede:
            cursor.close()
            conn.close()
            return jsonify({
                'success': False,
                'error': 'Filiale non trovata'
            }), 404
        
        # ✅ STEP 2: Conta articoli totali scansionati per questa sede
        cursor.execute("""
            SELECT COUNT(DISTINCT barcode) as total
            FROM inv_risultati_inventario
            WHERE id_tenant = %s AND id_sede = %s
        """, (tenant_id, sede_id))
        total_items = cursor.fetchone()['total']

        # ✅ STEP 3: Confronta TUTTI i prodotti scansionati con giacenze magazzino
        # JOIN diretto su codice_prodotto (no cache), subquery giacenze per evitare duplicati varianti
        cursor.execute("""
            SELECT
              r.barcode,
              r.nome_prodotto,
              SUM(r.quantita_fisica) as quantita_inventario,
              COALESCE(g.quantita, 0) as quantita_magazzino,
              (SUM(r.quantita_fisica) - COALESCE(g.quantita, 0)) as differenza,
              CASE WHEN (SUM(r.quantita_fisica) - COALESCE(g.quantita, 0)) > 0 THEN 'excess' ELSE 'deficit' END as status
            FROM inv_risultati_inventario r
            LEFT JOIN (
                SELECT id_prodotto, id_sede, id_tenant,
                    COALESCE(
                        MAX(CASE WHEN id_variante IS NULL THEN quantita END),
                        SUM(CASE WHEN id_variante IS NOT NULL THEN quantita ELSE 0 END)
                    ) as quantita
                FROM inv_giacenze
                GROUP BY id_prodotto, id_sede, id_tenant
            ) g ON r.codice_prodotto = g.id_prodotto
                AND g.id_sede = r.id_sede
                AND g.id_tenant = r.id_tenant
            WHERE r.id_tenant = %s
            AND r.id_sede = %s
            GROUP BY r.barcode, r.nome_prodotto, g.quantita
            HAVING (SUM(r.quantita_fisica) - COALESCE(g.quantita, 0)) != 0
            ORDER BY ABS(differenza) DESC
        """, (tenant_id, sede_id))
        
        report_items = []
        total_excess = 0
        total_deficit = 0

        for item in cursor.fetchall():
            report_items.append({
                'nome_prodotto': item['nome_prodotto'],
                'barcode': item['barcode'],
                'giacenza_negozio': item['quantita_magazzino'],
                'giacenza_inventario': item['quantita_inventario'],
                'differenza': item['differenza'],
                'status': item['status']
            })
            
            if item['differenza'] > 0:
                total_excess += 1
            else:
                total_deficit += 1
        
        cursor.close()
        conn.close()
        
        report_date = datetime.now().strftime('%Y-%m-%d')
        
        return jsonify({
            'success': True,
            'data': {
                'sede': sede,
                'report_date': report_date,
                'items': report_items,
                'summary': {
                    'total_items': total_items,
                    'items_with_diff': len(report_items),
                    'total_excess': total_excess,
                    'total_deficit': total_deficit
                }
            }
        }), 200
        
    except Exception as e:
        logger.error(f"Errore report_magazzino_sede: {e}", exc_info=True)
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


@warehouse_bp.route('/magazzino/<int:sede_id>', methods=['GET'])
@require_auth
def warehouse_report_page(sede_id):
    """Serve la pagina HTML del report magazzino"""
    return render_template('warehouse_report_magazzino.html')
    
